Files
OJ2/apps/web/vite.config.ts
T
xuyueandClaude Opus 5.5 e511d82f3b 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>
2026-11-03 13:55:33 +08:00

145 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import legacy from '@vitejs/plugin-legacy'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
// 机房电脑的 Chrome 是 105 一档,比 plugin-legacy 的现代基线(chrome>=105)正好压线,
// 但比 vite 8 的默认构建 target(chrome111)低。所以这个插件必须留着:它同时管两件事
// —— 把 build.target 压到 chrome105/es2020,再给现代产物补 core-js 的 API polyfill。
//
// 下面这份清单是 `modernPolyfills: true` 自动探测出来的 49 项,抄下来写死:自动探测要
// 对每个产物跑一遍 Babel 扫描,构建从 3 秒涨到 12 秒。**升级前端依赖后重新审计一次**:
// 临时把下面的 modernPolyfills 改成 true,再 DEBUG=vite:legacy bun run build
// (写死清单时它只回显这份清单,不会重新探测)
// 少一项就是老机器上一个静默的 TypeError(这批缺的大多是 Chrome 110+ 的
// Array.prototype.toSorted / Set 运算 / 迭代器辅助)。
const polyfills = [
'es.array-buffer.detached',
'es.array-buffer.transfer',
'es.array-buffer.transfer-to-fixed-length',
'es.array.includes',
'es.array.push',
'es.array.to-reversed',
'es.array.to-sorted',
'es.array.to-spliced',
'es.iterator.constructor',
'es.iterator.drop',
'es.iterator.every',
'es.iterator.filter',
'es.iterator.find',
'es.iterator.flat-map',
'es.iterator.for-each',
'es.iterator.map',
'es.iterator.reduce',
'es.iterator.some',
'es.iterator.take',
'es.iterator.to-array',
'es.json.parse',
'es.json.stringify',
'es.map.get-or-insert',
'es.map.get-or-insert-computed',
'es.regexp.escape',
'es.regexp.flags',
'es.set.difference.v2',
'es.set.intersection.v2',
'es.set.is-disjoint-from.v2',
'es.set.is-subset-of.v2',
'es.set.is-superset-of.v2',
'es.set.symmetric-difference.v2',
'es.set.union.v2',
'es.typed-array.to-reversed',
'es.typed-array.to-sorted',
'es.typed-array.with',
'es.uint8-array.set-from-base64',
'es.uint8-array.set-from-hex',
'es.uint8-array.to-base64',
'es.uint8-array.to-hex',
'es.weak-map.get-or-insert',
'es.weak-map.get-or-insert-computed',
'esnext.array.group',
'web.dom-exception.stack',
'web.url-search-params.delete',
'web.url-search-params.has',
'web.url-search-params.size',
'web.url.can-parse',
'web.url.parse',
]
export default defineConfig(() => {
// 开发时一律指向本机后端(apps/api,3000)。
// **必须写 IP,不能写 localhost**:api 用 Bun.serve 起,只绑 IPv4 的
// 0.0.0.0:3000,而 Node 解析 localhost 时 ::1 排在前面。别的项目的 dev server
// 一旦占着 [::1]:3000,两边端口不冲突(一个 v4 一个 v6,谁都不报错),
// 浏览器发出的 /api/* 就整个落到那个站上 —— 表现是后台一进就被弹回首页。
const backend = {
target: 'http://127.0.0.1:3000',
changeOrigin: true,
}
return {
plugins: [
vue(),
// 不做 SystemJS 双构建,只给现代产物注入 polyfill;modernTargets 不写,
// 用插件自带的基线(chrome>=105 / firefox>=106 / safari>=16.4),正好是机房那档。
legacy({
renderLegacyChunks: false,
modernPolyfills: polyfills,
}),
AutoImport({
imports: [
'vue',
'vue-router',
'@vueuse/core',
'pinia',
// 盖掉上面 @vueuse/core 的同名项:全站共用一个实例,原因见 shared/composables/dark.ts
{
from: 'shared/composables/dark',
imports: [{ name: 'useDark', priority: 10 }],
},
{
'naive-ui': ['useDialog', 'useMessage', 'useNotification', 'useLoadingBar'],
},
{
from: 'naive-ui',
imports: [
'DataTableColumn',
'FormRules',
'FormItemRule',
'SelectOption',
'UploadCustomRequestOptions',
'UploadFileInfo',
'MenuOption',
'DropdownDividerOption',
'DropdownOption',
],
type: true,
},
],
dts: './src/auto-imports.d.ts',
}),
Components({
resolvers: [NaiveUiResolver()],
dts: './src/components.d.ts',
}),
],
envPrefix: 'PUBLIC_',
resolve: {
// 别名(utils / oj / admin / shared)只在 tsconfig.app.json 的 paths 写一份,
// 这里直接读它。tsconfig.json 是 references 空壳也没关系,会顺着找过去(实测)
tsconfigPaths: true,
},
server: {
port: 5173,
proxy: {
// 只有这三段过后端,和生产的 Caddy 认的是同一套(docker/Caddyfile),
// 别在这里加代理规则而不同步改 Caddyfile。
'/api': backend,
'/public': backend,
'/ws': { ...backend, ws: true },
},
},
}
})