perf: 게임 화면을 경로별로 지연 로드

모든 게임 화면을 진입 번들에 포함하던 정적 import를 Vue Router 동적 import로 바꿉니다. 초기 프로필 진입에서 현재 경로에 필요한 화면만 내려받고, 회귀 방지 테스트를 추가합니다.
This commit is contained in:
2026-08-18 06:39:40 +00:00
parent e1c4336253
commit ada8edc72e
2 changed files with 60 additions and 38 deletions
+39 -38
View File
@@ -1,45 +1,46 @@
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';
import MainView from '../views/MainView.vue';
import PublicView from '../views/PublicView.vue';
import LoginView from '../views/LoginView.vue';
import JoinView from '../views/JoinView.vue';
import SelectGeneralView from '../views/SelectGeneralView.vue';
import InheritView from '../views/InheritView.vue';
import AuctionView from '../views/AuctionView.vue';
import NationCitiesView from '../views/NationCitiesView.vue';
import NationInfoView from '../views/NationInfoView.vue';
import GlobalInfoView from '../views/GlobalInfoView.vue';
import CurrentCityView from '../views/CurrentCityView.vue';
import NationGeneralsView from '../views/NationGeneralsView.vue';
import NationSecretView from '../views/NationSecretView.vue';
import NationPersonnelView from '../views/NationPersonnelView.vue';
import NationStratFinanView from '../views/NationStratFinanView.vue';
import ChiefCenterView from '../views/ChiefCenterView.vue';
import BattleCenterView from '../views/BattleCenterView.vue';
import BattleSimulatorView from '../views/BattleSimulatorView.vue';
import NpcControlView from '../views/NpcControlView.vue';
import NotFoundView from '../views/NotFoundView.vue';
import TournamentView from '../views/TournamentView.vue';
import BettingView from '../views/BettingView.vue';
import MyPageView from '../views/MyPageView.vue';
import BoardView from '../views/BoardView.vue';
import DiplomacyView from '../views/DiplomacyView.vue';
import BestGeneralView from '../views/BestGeneralView.vue';
import HallOfFameView from '../views/HallOfFameView.vue';
import DynastyListView from '../views/DynastyListView.vue';
import DynastyDetailView from '../views/DynastyDetailView.vue';
import SurveyView from '../views/SurveyView.vue';
import TroopView from '../views/TroopView.vue';
import YearbookView from '../views/YearbookView.vue';
import NationBettingView from '../views/NationBettingView.vue';
import NpcListView from '../views/NpcListView.vue';
import NationListView from '../views/NationListView.vue';
import GeneralListView from '../views/GeneralListView.vue';
import TrafficView from '../views/TrafficView.vue';
import PastPlaysView from '../views/PastPlaysView.vue';
import { useSessionStore } from '../stores/session';
import { trpc } from '../utils/trpc';
const MainView = () => import('../views/MainView.vue');
const PublicView = () => import('../views/PublicView.vue');
const LoginView = () => import('../views/LoginView.vue');
const JoinView = () => import('../views/JoinView.vue');
const SelectGeneralView = () => import('../views/SelectGeneralView.vue');
const InheritView = () => import('../views/InheritView.vue');
const AuctionView = () => import('../views/AuctionView.vue');
const NationCitiesView = () => import('../views/NationCitiesView.vue');
const NationInfoView = () => import('../views/NationInfoView.vue');
const GlobalInfoView = () => import('../views/GlobalInfoView.vue');
const CurrentCityView = () => import('../views/CurrentCityView.vue');
const NationGeneralsView = () => import('../views/NationGeneralsView.vue');
const NationSecretView = () => import('../views/NationSecretView.vue');
const NationPersonnelView = () => import('../views/NationPersonnelView.vue');
const NationStratFinanView = () => import('../views/NationStratFinanView.vue');
const ChiefCenterView = () => import('../views/ChiefCenterView.vue');
const BattleCenterView = () => import('../views/BattleCenterView.vue');
const BattleSimulatorView = () => import('../views/BattleSimulatorView.vue');
const NpcControlView = () => import('../views/NpcControlView.vue');
const NotFoundView = () => import('../views/NotFoundView.vue');
const TournamentView = () => import('../views/TournamentView.vue');
const BettingView = () => import('../views/BettingView.vue');
const MyPageView = () => import('../views/MyPageView.vue');
const BoardView = () => import('../views/BoardView.vue');
const DiplomacyView = () => import('../views/DiplomacyView.vue');
const BestGeneralView = () => import('../views/BestGeneralView.vue');
const HallOfFameView = () => import('../views/HallOfFameView.vue');
const DynastyListView = () => import('../views/DynastyListView.vue');
const DynastyDetailView = () => import('../views/DynastyDetailView.vue');
const SurveyView = () => import('../views/SurveyView.vue');
const TroopView = () => import('../views/TroopView.vue');
const YearbookView = () => import('../views/YearbookView.vue');
const NationBettingView = () => import('../views/NationBettingView.vue');
const NpcListView = () => import('../views/NpcListView.vue');
const NationListView = () => import('../views/NationListView.vue');
const GeneralListView = () => import('../views/GeneralListView.vue');
const TrafficView = () => import('../views/TrafficView.vue');
const PastPlaysView = () => import('../views/PastPlaysView.vue');
const accessPageByRouteName = {
'nation-info': 'nation-info',
'nation-cities': 'nation-cities',
@@ -0,0 +1,21 @@
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
import path from 'node:path';
import { describe, it } from 'node:test';
const routerSourcePath = path.resolve(import.meta.dirname, '../src/router/index.ts');
void describe('game route loading contract', () => {
void it('loads view components through route-level dynamic imports', async () => {
const source = await readFile(routerSourcePath, 'utf8');
const staticViewImports = [...source.matchAll(/^import\s+.+\s+from\s+['"]\.\.\/views\//gm)];
const lazyViewImports = [...source.matchAll(/=\s*\(\)\s*=>\s*import\(['"]\.\.\/views\//g)];
const routedViewComponents = new Set(
[...source.matchAll(/^\s*component:\s*([A-Z][A-Za-z0-9]+View),?$/gm)].map((match) => match[1])
);
assert.deepEqual(staticViewImports, []);
assert.equal(lazyViewImports.length, routedViewComponents.size);
assert.ok(lazyViewImports.length >= 35);
});
});