perf(暗色): 提交列表、排名首屏卡掉的一秒多回来了 —— 全站共用一个 useDark

VueUse 的 useDark 每个实例挂载时都插一段 style、getComputedStyle 逼整页重算样式,
亮色下它的「没东西要改就跳过」永远不成立。提交列表每行的结果胶囊(useTone)都调它,
一页 30 行就是 30 次整页重算,翻页、换条再来。

改成 shared/composables/dark.ts 的 createGlobalState,auto-import 用 priority 盖掉
@vueuse/core 的同名项,显式 import 的 7 处一并换掉。

生产构建、CPU 降速 6 倍实测:提交列表首屏主线程 2015 → 1092ms(列表出来 1.34 → 0.85 秒),
排名 1950 → 850ms,比赛 1060 → 757ms;右栏换到没看过的一条不再每次卡 100ms。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-11-03 13:55:33 +08:00
1 parent 55bdf317f1
commit e511d82f3b
9 files changed
+28 -7

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
import { useDark } from '@vueuse/core' import { useDark } from 'shared/composables/dark'
/** /**
* 排名页的几种颜色(设计稿「排名重设计」G1)。用户说「颜色可以保留」:你绿、前一名蓝、 * 排名页的几种颜色(设计稿「排名重设计」G1)。用户说「颜色可以保留」:你绿、前一名蓝、
@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useThemeVars } from 'naive-ui' import { useThemeVars } from 'naive-ui'
import { useDark } from '@vueuse/core' import { useDark } from 'shared/composables/dark'
/** /**
* 只读的代码区:行号 + 高亮 + 可选地标红一行(编译失败 / 运行时错误报了行号时)。 * 只读的代码区:行号 + 高亮 + 可选地标红一行(编译失败 / 运行时错误报了行号时)。
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useDark } from '@vueuse/core' import { useDark } from 'shared/composables/dark'
import { rgba } from 'shared/composables/tone' import { rgba } from 'shared/composables/tone'
import { displayName } from '@oj2/contract' import { displayName } from '@oj2/contract'
@@ -1,4 +1,4 @@
import { useDark } from '@vueuse/core' import { useDark } from 'shared/composables/dark'
import { Chart as ChartJS } from 'chart.js' import { Chart as ChartJS } from 'chart.js'
/** /**
+16
View File
@@ -0,0 +1,16 @@
import { createGlobalState, useDark as useVueUseDark } from '@vueuse/core'
/**
* 全站只有一个 `useDark()` 实例。**别再从 `@vueuse/core` 直接取 useDark** ——
* auto-import 已经把 `useDark` 指到这里(apps/web/vite.config.ts 的 priority)。
*
* VueUse 的 useDark 每个实例挂载时都要把 `<html>` 的 class 「同步」一遍,同步的写法是
* 往 `<head>` 插一段关掉过渡的 `<style>`、`getComputedStyle()` 逼浏览器当场重算整页样式、
* 再删掉。亮色模式下它那句「没什么要改就跳过」永远不成立(要摘的 `dark` 本来就不在,它也算
* 一次改动),所以**每个实例挂载一次就是一次整页样式重算**。
*
* 提交列表每行的结果胶囊(StatusPill → useTone)都调它:一页 30 行就是 30 次,翻页、
* 切筛选再来 30 次,右栏换一条又是三四次。2026-11 实测(生产构建、CPU 降速 6 倍)首屏
* 光这一处就占了 1.3 秒。全站共用一个之后只在第一次挂载时同步,后面的调用都是读同一个 ref。
*/
export const useDark = createGlobalState(() => useVueUseDark())
@@ -1,4 +1,4 @@
import { useDark } from '@vueuse/core' import { useDark } from 'shared/composables/dark'
/** /**
* 圆环从哪儿开始扩散。正常点击就用指针落点;键盘触发(Enter / 空格)时浏览器给的 * 圆环从哪儿开始扩散。正常点击就用指针落点;键盘触发(Enter / 空格)时浏览器给的
+1 -1
View File
@@ -1,4 +1,4 @@
import { useDark } from '@vueuse/core' import { useDark } from 'shared/composables/dark'
import { computed } from 'vue' import { computed } from 'vue'
import { RARITY_TEXT_COLOR } from 'utils/constants' import { RARITY_TEXT_COLOR } from 'utils/constants'
+1 -1
View File
@@ -1,5 +1,5 @@
import { useThemeVars } from 'naive-ui' import { useThemeVars } from 'naive-ui'
import { useDark } from '@vueuse/core' import { useDark } from 'shared/composables/dark'
export type Tone = 'success' | 'error' | 'warning' | 'info' | 'default' export type Tone = 'success' | 'error' | 'warning' | 'info' | 'default'
+5
View File
@@ -93,6 +93,11 @@ export default defineConfig(() => {
'vue-router', 'vue-router',
'@vueuse/core', '@vueuse/core',
'pinia', 'pinia',
// 盖掉上面 @vueuse/core 的同名项:全站共用一个实例,原因见 shared/composables/dark.ts
{
from: 'shared/composables/dark',
imports: [{ name: 'useDark', priority: 10 }],
},
{ {
'naive-ui': ['useDialog', 'useMessage', 'useNotification', 'useLoadingBar'], 'naive-ui': ['useDialog', 'useMessage', 'useNotification', 'useLoadingBar'],
}, },