From f20fb9408db5eb08033f893352f14f30e3599c14 Mon Sep 17 00:00:00 2001 From: hided62 Date: Tue, 25 Aug 2026 02:11:47 +0000 Subject: [PATCH] =?UTF-8?q?perf(game-ui):=20=EB=8C=80=EA=B7=9C=EB=AA=A8=20?= =?UTF-8?q?=EC=9E=A5=EC=88=98=EC=9D=BC=EB=9E=8C=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EB=A0=8C=EB=8D=94=EB=A7=81=EC=9D=84=20=EC=A4=84=EC=9D=B8?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 현재 화면 폭에 필요한 표 또는 카드만 마운트하고 화면 밖 장수 얼굴은 지연 로딩한다. PYA 규모 845명 Chromium 회귀로 레이아웃 전환과 요청 수 경계를 고정한다. --- app/game-frontend/e2e/directoryLists.spec.ts | 61 ++++++++++++++++++- .../directory/GeneralDirectoryTable.vue | 30 ++++++++- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/app/game-frontend/e2e/directoryLists.spec.ts b/app/game-frontend/e2e/directoryLists.spec.ts index 06edbb51..311cb126 100644 --- a/app/game-frontend/e2e/directoryLists.spec.ts +++ b/app/game-frontend/e2e/directoryLists.spec.ts @@ -130,6 +130,18 @@ const generals = [ }, ]; +const pyaScaleGenerals = Array.from({ length: 845 }, (_, index) => { + const source = generals[index % generals.length]!; + return { + ...source, + id: index + 1, + name: `성능장수${index + 1}`, + ownerName: null, + picture: `performance/general-${index + 1}.png`, + imageServer: 0, + }; +}); + const npcGenerals = [ { id: 10, @@ -187,7 +199,8 @@ const install = async ( page: Page, mode: 'general' | 'no-general' | 'error-after-load' = 'general', accessPages: string[] = [], - requestedOperations: string[] = [] + requestedOperations: string[] = [], + directoryRows = generals ) => { let generalDirectoryCalls = 0; await page.addInitScript((profile) => { @@ -260,7 +273,9 @@ const install = async ( } const sort = parseSort(route); const rows = - sort === 8 ? [...generals].sort((left, right) => left.killturn - right.killturn) : generals; + sort === 8 + ? [...directoryRows].sort((left, right) => left.killturn - right.killturn) + : directoryRows; return response({ sort, generals: rows }); } if (operation === 'public.getNpcList') { @@ -307,6 +322,48 @@ const installAccessBoundary = async (page: Page, accessPages: string[]) => { }); }; +test('PYA-scale general directory mounts only the active responsive layout and defers portraits', async ( + { page }, + testInfo +) => { + const requestedPortraits = new Set(); + page.on('request', (request) => { + if (request.url().includes('/performance/general-')) { + requestedPortraits.add(request.url()); + } + }); + await page.setViewportSize({ width: 1200, height: 900 }); + await install(page, 'general', [], [], pyaScaleGenerals); + await page.goto('general-list'); + + await expect(page.locator('.general-table tbody tr[data-general-id]')).toHaveCount(845); + await expect(page.locator('.general-card-list [data-general-card-id]')).toHaveCount(0); + await expect(page.locator('.general-icon')).toHaveCount(845); + await expect(page.locator('.general-icon').first()).toHaveAttribute('loading', 'lazy'); + await expect(page.locator('.general-icon').first()).toHaveAttribute('decoding', 'async'); + await page.waitForTimeout(250); + expect(requestedPortraits.size).toBeLessThan(100); + const desktopMetrics = await page.evaluate(() => ({ + domNodes: document.querySelectorAll('*').length, + documentHeight: document.documentElement.scrollHeight, + })); + await writeFile( + testInfo.outputPath('pya-scale-desktop-metrics.json'), + `${JSON.stringify({ ...desktopMetrics, requestedPortraits: requestedPortraits.size }, null, 2)}\n` + ); + await page.screenshot({ path: testInfo.outputPath('pya-scale-desktop.png') }); + + await page.setViewportSize({ width: 500, height: 844 }); + await expect(page.locator('.general-table')).toHaveCount(0); + await expect(page.locator('.general-card-list [data-general-card-id]')).toHaveCount(845); + await expect(page.locator('.general-icon')).toHaveCount(845); + await page.screenshot({ path: testInfo.outputPath('pya-scale-mobile.png') }); + + await page.setViewportSize({ width: 1200, height: 900 }); + await expect(page.locator('.general-table tbody tr[data-general-id]')).toHaveCount(845); + await expect(page.locator('.general-card-list')).toHaveCount(0); +}); + test('nation and general directories preserve the fixed legacy Chromium geometry', async ({ page }) => { const accessPages: string[] = []; await install(page, 'general', accessPages); diff --git a/app/game-frontend/src/components/directory/GeneralDirectoryTable.vue b/app/game-frontend/src/components/directory/GeneralDirectoryTable.vue index 0d219719..29026e21 100644 --- a/app/game-frontend/src/components/directory/GeneralDirectoryTable.vue +++ b/app/game-frontend/src/components/directory/GeneralDirectoryTable.vue @@ -1,4 +1,6 @@