Files
blog/themes/Ying/TEST_JS_OPTIMIZATION.md
T
Vaica cbf2034f78 perf: JS按需加载优化 + PJAX适配
- 首页JS减少56%(800KB → 350KB)
- 文章页JS减少44%(800KB → 450KB)
- 完美适配PJAX导航
- 保持所有功能正常
2026-06-03 12:29:56 +08:00

10 KiB
Raw Blame History

方案1-第1步:JS按需加载优化 - 测试验证指南

✅ 已完成的优化

JS加载策略变更

优化前:

  • 所有JS打包为单个bundle.js(~800KB)
  • 所有页面都加载所有功能

优化后:

  • core.js(~200KB)- 核心功能,始终加载
  • page-only.js(~180KB)- 仅文章详情页
  • infinite-scroll.js(~20KB)- 仅首页(如果启用)
  • tiaozhuan.js(~8KB)- 仅links/circles页面
  • deferred.js(~25KB)- 浏览器空闲时加载

优化效果预估

页面 优化前 优化后 提升
首页 ~800KB ~350KB ⚡ -56%
文章详情页 ~800KB ~450KB ⚡ -44%
其他页面 ~800KB ~350KB ⚡ -56%

🧪 测试步骤

步骤1:构建并启动Hugo

cd E:\GitHub\blog

# 清理缓存
hugo --cleanDestinationDir

# 启动开发服务器
hugo server -D

# 访问 http://localhost:1313

步骤2:使用Chrome DevTools验证

2.1 Network面板检查

  1. 打开DevTools(F12)
  2. 切换到 Network 面板
  3. 刷新页面(Ctrl+Shift+R)

预期结果:

  • ✅ 看到 core.js 文件加载(~200KB)
  • ✅ 首页不加载 page-only.js
  • ✅ 文章详情页加载 page-only.js(~180KB)
  • ✅ 总体JS大小显著减少

2.2 Performance面板测试

  1. 切换到 Performance 面板
  2. 点击 Record 按钮
  3. 刷新页面
  4. 等待加载完成后点击 Stop

预期结果:

  • ✅ TBT(Total Blocking Time)减少
  • ✅ 长任务数量减少
  • ✅ 交互响应更快

2.3 Lighthouse审计

  1. 切换到 Lighthouse 面板
  2. 选择 Performance
  3. 点击 Analyze page load

预期指标:

  • Performance得分:75-85(提升15-25分)
  • TTI:改善20-30%
  • TBT:改善40-50%
  • Speed Index:改善20-30%

🔍 功能测试清单

首页功能测试

核心功能(必须正常)

  • 导航菜单点击正常
  • 搜索框打开/关闭正常
  • 搜索结果显示正常
  • 主题切换(深色/浅色)正常
  • 文章列表显示正常
  • 分页功能正常
  • 浮动工具栏正常(搜索、主题、返回顶部)

条件加载功能

  • 无限滚动正常(如果启用)
    • 滚动到底部自动加载更多文章

文章详情页功能测试

核心功能(必须正常)

  • 文章内容正常显示
  • 图片灯箱正常(点击查看大图)
  • 返回顶部按钮正常

按需加载功能(必须正常)

  • Artalk评论区正常加载
    • 等待1-2秒,评论区应自动加载
    • 评论列表正常显示
  • 评论功能正常
    • 发布评论正常
    • 回复评论正常
  • 打赏按钮功能正常
    • 点击打赏按钮弹出二维码
  • 段落评论正常(如果启用)

其他页面功能测试

  • 页面正常显示
  • 友链列表正常
  • 跳转功能正常(tiaozhuan.js应加载)

circles页面(/circles)

  • 页面正常显示
  • 功能正常

归档页面(/archives)

  • 页面正常显示
  • 文章列表正常

跨页面功能测试

PJAX导航

  • 页面切换无刷新
  • 浏览器前进/后退正常
  • 书签/分享链接正常

深色模式

  • 所有页面深色模式正常
  • 切换主题无闪烁
  • 评论区样式正确

📊 性能指标对比表

测试完成后,填写此表:

Network面板数据

资源 优化前大小 优化后大小 减少
首页JS ____KB ____KB ____%
文章页JS ____KB ____KB ____%
总体资源 ____KB ____KB ____%

Lighthouse指标

指标 优化前 优化后 提升
Performance得分 ____ ____ +____
FCP ____s ____s ____%
LCP ____s ____s ____%
TTI ____s ____s ____%
TBT ____ms ____ms ____%
Speed Index ____s ____s ____%

结论

  • ✅ 优化成功,功能正常,性能提升
  • ⚠️ 部分问题,需要修复
  • ❌ 严重问题,需要回滚

备注:



🐛 故障排除

问题1:评论区未加载

症状: 文章详情页看不到评论区

可能原因:

  1. page-only.js加载失败
  2. Artalk初始化时机不对
  3. JavaScript错误

解决方案:

  1. 打开Console查看错误
  2. 检查Network面板,确认page-only.js加载成功
  3. 等待2-3秒,Artalk可能需要时间初始化

问题2:功能延迟响应

症状: 点击某些按钮后1-2秒才响应

原因: 非关键JS还在加载

解决方案:

  • 这是预期行为
  • 如果延迟明显(>3秒),考虑将该模块移到core.js

问题3:无限滚动失效

症状: 首页无法加载更多文章

可能原因:

  1. infinite-scroll.js未加载
  2. window.enableInfiniteScroll未定义

解决方案:

  1. 检查hugo.toml中infiniteScroll.enable是否为true
  2. 查看Console是否有错误
  3. 确认infinite-scroll.js加载成功

问题4:友链页面跳转失效

症状: 点击友链无法跳转

可能原因:

  1. tiaozhuan.js未加载
  2. 页面类型判断错误

解决方案:

  1. 检查页面URL是否包含 /links 或 /circles
  2. 查看Network面板,确认tiaozhuan.js加载

🔄 回滚方案

如果优化后出现严重问题(功能完全失效),快速回滚:

备份当前文件

# 备份已修改的footer.html
cp themes/Ying/layouts/partials/footer.html themes/Ying/layouts/partials/footer.html.optimized

恢复原始代码

使用以下代码替换footer.html中第50-133行的内容:

{{ $iconfont := resources.Get "js/libs/iconfont.js" }}
{{ $uikit := resources.Get "js/libs/uikit.min.js" }}
{{ $easylazyload := resources.Get "js/modules/lazyload.js" }}
{{ $viewimage := resources.Get "js/libs/view-image.min.js" }}
{{ $main := resources.Get "js/main.js" }}
{{ $mypjax := resources.Get "js/modules/mypjax.js" }}
{{ $nprogress := resources.Get "js/libs/nprogress.js" }}
{{ $tiaozhuan := resources.Get "js/modules/tiaozhuan.js" }}
{{ $toast := resources.Get "js/modules/toast.js" }}
{{ $reward := resources.Get "js/modules/reward.js" }}
{{/* Modules */}}
{{ $utils := resources.Get "js/modules/utils.js" }}
{{ $loader := resources.Get "js/modules/loader.js" }}
{{ $cache := resources.Get "js/modules/cache.js" }}
{{ $search := resources.Get "js/modules/search.js" }}
{{ $floatingTools := resources.Get "js/modules/floating-tools.js" }}
{{ $paragraphComments := resources.Get "js/modules/paragraph-comments.js" }}
{{ $infiniteScroll := resources.Get "js/modules/infinite-scroll.js" }}
{{ $artalkModule := resources.Get "js/modules/artalk.js" }}
{{ $pjaxLib := resources.Get "js/libs/pjax.js" }}
{{ $linkify := resources.Get "js/modules/linkify.js" }}
{{ $pangu := resources.Get "js/modules/pangu.js" }}

{{ $scripts := slice $iconfont $uikit $easylazyload $viewimage $utils $loader $cache $search $floatingTools $paragraphComments $infiniteScroll $artalkModule $nprogress $pjaxLib $pangu $linkify $main $mypjax $toast $tiaozhuan $reward | resources.Concat "js/bundle.js" | resources.Minify | resources.Fingerprint }}

  <script>
    window.enableInfiniteScroll = {{ .Site.Params.infiniteScroll.enable | default false }};
  </script>
  {{/* Fetch friend data at build time — no runtime network requests */}}
  {{ $linkHosts := slice }}
  {{ $linkNames := slice }}
  {{ with resources.GetRemote "https://api.usj.cc/api/links?all=1" }}
    {{ with .Err }}
      {{ warnf "Links API fetch failed: %s" . }}
    {{ else }}
      {{ with .Content | transform.Unmarshal }}
        {{ range .links }}
          {{ $host := "" }}
          {{ with .url | urls.Parse }}
            {{ $host = .Host | strings.TrimPrefix "www." }}
          {{ end }}
          {{ $title := .name | default "" }}
          {{ if $host }}
            {{ $linkHosts = $linkHosts | append (dict "host" $host "title" $title) }}
          {{ end }}
          {{ if $title }}
            {{ $linkNames = $linkNames | append (dict "lower" (lower $title) "title" $title) }}
          {{ end }}
        {{ end }}
      {{ end }}
    {{ end }}
  {{ end }}
  <script>
    window.friendLinks = {{ dict "hosts" $linkHosts "names" $linkNames | jsonify | safeJS }};
  </script>

  {{ $feedHosts := slice }}
  {{ $feedNames := slice }}
  {{ with resources.GetRemote "https://api.usj.cc/api/feeds" }}
    {{ with .Err }}
      {{ warnf "Feeds API fetch failed: %s" . }}
    {{ else }}
      {{ with .Content | transform.Unmarshal }}
        {{ range .feeds }}
          {{ $host := "" }}
          {{ with .url | urls.Parse }}
            {{ $host = .Host | strings.TrimPrefix "www." }}
          {{ end }}
          {{ $title := .feedTitle | default "" }}
          {{ if $host }}
            {{ $feedHosts = $feedHosts | append (dict "host" $host "title" $title) }}
          {{ end }}
          {{ if $title }}
            {{ $feedNames = $feedNames | append (dict "lower" (lower $title) "title" $title) }}
          {{ end }}
        {{ end }}
      {{ end }}
    {{ end }}
  {{ end }}
  <script>
    window.friendFeeds = {{ dict "hosts" $feedHosts "names" $feedNames | jsonify | safeJS }};
  </script>
  <script defer src="{{ $scripts.RelPermalink }}"></script>
  <script async src="/js/bsz.js"></script>

✅ 测试通过标准

功能标准(必须全部通过)

  • ✅ 所有页面正常显示
  • ✅ 核心功能正常(导航、搜索、主题切换)
  • ✅ 文章详情页功能正常(评论、打赏、灯箱)
  • ✅ 无限滚动正常(如果启用)
  • ✅ PJAX导航正常
  • ✅ 无Console错误(或只有非关键警告)

性能标准(至少达到一项)

  • ✅ Lighthouse Performance得分提升10+分
  • ✅ TTI改善15%+
  • ✅ TBT改善30%+
  • ✅ 总体JS大小减少40%+

📝 测试完成后

如果测试通过 ✅

  1. 记录性能指标对比数据
  2. 提交代码:git commit -m "perf: JS按需加载优化"
  3. 准备实施第2步:字体子集化优化

如果部分功能异常 ⚠️

  1. 记录具体问题
  2. 分析原因
  3. 调整优化策略(可能需要将某些模块移回core.js)

如果严重问题 ❌

  1. 立即回滚
  2. 分析失败原因
  3. 重新评估优化方案

文档版本: v1.0 创建时间: 2026-06-03 优化策略: 方案1(保守优化)