chore(前端): 浏览器基线从 Chrome < 94 提到 105,删掉 mermaid@9 那套 fallback

机房只有部分电脑还是 Chrome 105,其余更新,按最低那档定基线。

- legacy 插件留着:vite 8 的默认 build.target 是 chrome111,比机房高。
  modernTargets 不写,用插件自带的 chrome>=105 基线,正好是这一档。
- polyfill 清单按 105 重新探测,63 → 50 项,仍然写死:自动探测要对每个产物
  跑 Babel 扫描,构建 3s → 12s。写死后产出的 polyfills chunk 与自动探测同尺寸。
- 删 mermaid-legacy(mermaid@9)、useMermaid 里按 UA 分叉的 v9 回调式 render、
  为它存在的 cytoscape UMD→ESM 别名 —— 105 直接用 mermaid 11。
- View Transitions 要 111,darkTransition 的降级分支保留,注释改成 105。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-16 07:43:21 -06:00
parent 688005c081
commit 3559ae4d6f
10 changed files with 171 additions and 207 deletions

View File

@@ -1 +0,0 @@
declare module "mermaid-legacy"

View File

@@ -19,8 +19,8 @@ import HelpRequestList from "./HelpRequestList.vue"
*
* 这个组件静态 import 进来的话,整套 CodeMirrorview / state / language /
* autocomplete / lang-*)就跟着 App.vue 进了入口 chunk —— 首屏白白多下 640 KB
* gzip 后 210 KB而下面那个 v-if 决定了学生根本不渲染它机房那批
* Chrome 91 的老机器解析这些字节是实打实的开销。
* gzip 后 210 KB而下面那个 v-if 决定了学生根本不渲染它 —— 机房那批老机器
* 解析这些字节是实打实的开销。
*
* 拆成异步之后首页的 JS 从 1.9 MB 降到 1.3 MBgzip 642 KB → 428 KB
* 老师那边只是在第一次接单时多一次 chunk 请求。

View File

@@ -22,7 +22,7 @@ export function useDarkTransition() {
function toggleDark(event: MouseEvent) {
if (!document.startViewTransition) {
// 机房那批 Chrome 低于 94没有 View Transitions,直接切、不做动画。
// View Transitions 要 Chrome 111机房那批 105 没有,直接切、不做动画。
isDark.value = !isDark.value
return
}

View File

@@ -251,26 +251,14 @@ function applyFlowchartDisplayStyle(container: HTMLElement) {
svg.insertBefore(style, svg.firstChild)
}
function getChromeVersion(): number {
const match = navigator.userAgent.match(/Chrome\/(\d+)/)
return match ? parseInt(match[1]) : Infinity
}
let mermaidPromise: Promise<any> | null = null
let mermaidIsLegacy = false
function loadMermaid(): Promise<any> {
// 缓存 Promise 而不是实例:同一屏里两个组件一起挂载时,缓存实例会让两边都
// 落进 if (!mermaidInstance)import 两次、initialize 两次
if (!mermaidPromise) {
mermaidPromise = (async () => {
let instance: any
if (getChromeVersion() < 94) {
instance = (await import("mermaid-legacy")).default
mermaidIsLegacy = true
} else {
instance = (await import("mermaid")).default
}
const instance = (await import("mermaid")).default
instance.initialize({
startOnLoad: false,
securityLevel: "strict",
@@ -313,17 +301,7 @@ export function useMermaid() {
try {
const m = await loadMermaid()
const id = `mermaid-${getRandomId()}`
// v9 (mermaid-legacy): callback-based render(id, code, cb)
// v10+: Promise-based render(id, code) → { svg }
const svg = mermaidIsLegacy
? await new Promise<string>((resolve, reject) => {
try {
m.render(id, mermaidCode, resolve)
} catch (e) {
reject(e)
}
})
: (await m.render(id, mermaidCode)).svg
const { svg } = await m.render(id, mermaidCode)
if (gen !== renderGeneration) return
container.innerHTML = svg
applyFlowchartDisplayStyle(container)