perf(game-ui): 대규모 장수일람 초기 렌더링을 줄인다
현재 화면 폭에 필요한 표 또는 카드만 마운트하고 화면 밖 장수 얼굴은 지연 로딩한다. PYA 규모 845명 Chromium 회귀로 레이아웃 전환과 요청 수 경계를 고정한다.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
|
||||
import { resolveGeneralIconUrl, useDefaultGeneralIcon } from '../../utils/generalIcon';
|
||||
import { formatOfficerLevelText } from '../../utils/nationFormat';
|
||||
import { getNpcColor } from '../../utils/npcColor';
|
||||
@@ -29,6 +31,26 @@ const props = withDefaults(
|
||||
|
||||
const emit = defineEmits<{ sort: [value: number] }>();
|
||||
|
||||
const narrowViewportQuery =
|
||||
typeof window !== 'undefined' && typeof window.matchMedia === 'function'
|
||||
? window.matchMedia('(max-width: 600px)')
|
||||
: null;
|
||||
const narrowViewport = ref(narrowViewportQuery?.matches ?? false);
|
||||
const renderCardLayout = computed(() => props.layout === 'card' || narrowViewport.value);
|
||||
const updateNarrowViewport = (event: MediaQueryListEvent): void => {
|
||||
narrowViewport.value = event.matches;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (!narrowViewportQuery) return;
|
||||
narrowViewport.value = narrowViewportQuery.matches;
|
||||
narrowViewportQuery.addEventListener('change', updateNarrowViewport);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
narrowViewportQuery?.removeEventListener('change', updateNarrowViewport);
|
||||
});
|
||||
|
||||
const headers: ReadonlyArray<Header> = [
|
||||
{ label: '얼 굴' },
|
||||
{ label: '이 름', sort: 0 },
|
||||
@@ -71,7 +93,7 @@ const sortHelp = (header: Header): string =>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table class="directory-table general-table legacy-bg0" :class="{ 'layout-card': layout === 'card' }">
|
||||
<table v-if="!renderCardLayout" class="directory-table general-table legacy-bg0">
|
||||
<colgroup>
|
||||
<col style="width: 64px" />
|
||||
<col style="width: 140px" />
|
||||
@@ -134,6 +156,8 @@ const sortHelp = (header: Header): string =>
|
||||
class="general-icon"
|
||||
width="64"
|
||||
height="64"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
:src="resolveGeneralIconUrl(general)"
|
||||
alt=""
|
||||
@error="useDefaultGeneralIcon"
|
||||
@@ -208,7 +232,7 @@ const sortHelp = (header: Header): string =>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="general-card-list" :class="{ 'layout-card': layout === 'card' }">
|
||||
<div v-if="renderCardLayout" class="general-card-list" :class="{ 'layout-card': layout === 'card' }">
|
||||
<div v-if="loading" class="general-card-loading legacy-bg0">불러오는 중...</div>
|
||||
<article
|
||||
v-for="general in generals"
|
||||
@@ -229,6 +253,8 @@ const sortHelp = (header: Header): string =>
|
||||
class="general-icon"
|
||||
width="64"
|
||||
height="64"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
:src="resolveGeneralIconUrl(general)"
|
||||
alt=""
|
||||
@error="useDefaultGeneralIcon"
|
||||
|
||||
Reference in New Issue
Block a user