Skip to content

perf: lazy load detail tabs and thumbnail icons - #79

Merged
CodFrm merged 12 commits into
mainfrom
perf/detail-lazy-thumbnails-tabs
Oct 18, 2026
Merged

CodFrm merged 12 commits into
mainfrom
perf/detail-lazy-thumbnails-tabs

Conversation

@CodFrm

@CodFrm CodFrm commented Oct 18, 2026

Copy link
Copy Markdown
Member

变更说明

同步当前本地 main 到 GitHub main,并包含详情页性能优化:

  • 脚本图标使用固定尺寸 /icon/thumb/64 或 /icon/thumb/128
  • 缩略图失败时回退原图代理,再回退首字母/自定义占位
  • 详情页版本和评分 Tab 改为按需动态加载
  • 使用 antd 6 destroyOnHidden,描述 Tab 首屏不挂载版本/评分内容
  • 版本和评分数据在对应 Tab 激活后请求,并保留 loading/error 状态
  • 保留广告和 rails 的 SSR 预取及曝光逻辑
  • 不做匿名 HTML/CDN 缓存,不做全局 antd CSS 重构

注意:GitHub main 当前比本地最新主线落后 12 个已有提交,因此该 PR 会同步这部分主线差异,而不只是最后两个性能 commit。工作区已有的 vitest.config.mts 修改未提交,也未包含在 PR 中。

验证

  • pnpm test:62 个测试文件、527 个测试通过
  • pnpm run lint:0 error,11 条已有 warning
  • pnpm exec tsc --noEmit
  • pnpm verify:antd-css
  • APP_API_PROXY=http://127.0.0.1:8080 pnpm build
  • git diff --check

以上均已通过。

上传沿用 fetch + 20s 超时,慢速上行链路下几百 KB 的图片就会被 abort,
请求到不了源站、也没有任何提示。新增基于 XHR 的 apiClient.upload,
支持上传进度回调,默认超时 5 分钟;广告管理页上传按钮显示进度条。
用户名下没有脚本时后端返回 list: null,组件直接读 data.list.length
抛错,被 (main)/error.tsx 接住后整页显示「服务器内部错误」。
勾选后封禁请求带 clean_issues,由后端软删该用户的反馈及正文回复。
补齐 7 个语种的 ban_clean_issues 文案。
错误边界只在访客自己的控制台打印,未捕获异常没有任何监听,SSR 报错不带
请求路径——用户发来 "Internal Server Error" 截图时服务端查不到任何痕迹。

- 错误边界、未捕获异常、未处理的 Promise 拒绝上报到后端
  /api/v2/system/client-errors;同一错误每次页面加载只报一次,单页最多 5 条
- 错误页显示的错误 ID 即上报的 error_id,拿截图里的 ID 就能在日志里搜到
- 新增 instrumentation.ts:SSR 出错时带路径、真实消息与 digest 上报,
  并转发访客的 Cookie / IP / UA
- 新增 global-error.tsx 兜住根布局崩溃
- 上报带页面是否被浏览器翻译、构建版本(CI 注入 NEXT_PUBLIC_BUILD_ID)
- 上报是旁路:失败静默、不重试,不影响页面

规格见后端仓库 docs/specs/2026-10-12-client-error-reporting.md
上线首日 95 条上报里:
- 38 条是页面在服务端抛出的「脚本不存在 / 已删除 / 未登录」,3 条是访客
  渲染途中断开连接。这些是预期结果,不再上报;后端 5xx、超时与网络错误
  照常上报。
- 4 条是 Cannot read properties of undefined (reading 'installed'):有的脚本
  管理器在脚本未安装时回调不带参数,checkScriptInstalled 直接读了
  res.installed。按未安装处理。
线上 100 分钟内 28 条 #418,集中在版本、反馈详情、评论页。useSemDateTime 的
输出取决于「现在」和时区,这两样服务端(UTC)与访客浏览器都不同:

- 一年以上的时间显示日期:UTC 的 2023年11月26日,东八区是 27 日
- 一年以内显示相对时间:爬虫拿到 HTML 很久后才执行脚本,「1 天前」变「2 天前」

React 发现文本不一致后丢弃整段服务端 HTML 在浏览器重渲染。

水合那一遍改用服务端下发的 now 与时区复现服务端输出,水合完成后再换成访客
本地时间;语言显式传给 dayjs,不再依赖全局设置。调用方不用改。
线上约 110 条浏览器端「请求超时 / 解析响应数据失败 / Failed to fetch」堆栈只到
apiClient._request,看不出是哪个接口。

- APIError 记下失败请求的方法、路径(不含查询串)、耗时与响应类型
- 上报时拼在消息后:请求超时 [GET /scripts/1/state status=-1 20003ms];
  不参与去重,同一错误仍只报一次
- Promise 拒绝、两个错误边界与 SSR 上报都带

新日志暴露的第一个来源:AdSlot 的曝光上报没有 catch,请求被广告拦截器掐掉
或超时就成了未处理的 Promise 拒绝。曝光统计是旁路,失败时静默。
@CodFrm
CodFrm merged commit ceb0587 into main Oct 18, 2026
2 checks passed
@CodFrm
CodFrm deleted the perf/detail-lazy-thumbnails-tabs branch October 18, 2026 05:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant