用户中心前端性能优化实战文档

项目背景:用户中心是一个基于 Vue 2 + Vuex + Webpack 3 的单页应用(SPA),近期收到反馈:移动端登录页偶发加载缓慢
约束条件:临近春节,年后有重构计划,仅允许小改动、低风险、高收益的优化方案。
目标显著降低首屏白屏时间(FCP/LCP),提升用户感知性能,Lighthouse 评分从 30+ 提升至 70+。


一、优化原则与策略

✅ 可实施原则

  • 不引入 SSR:无 SEO 需求,同构改造成本高;
  • 不大幅删减业务代码:避免引入回归 Bug;
  • 优先网络与渲染层优化:见效快、风险低;
  • 保留现有架构:仅调整构建配置与资源加载策略。

🎯 优化方向

层级目标关键手段
网络传输缩短资源下载时间TLS 1.3、DNS 预解析、Preconnect、Preload
资源体积减少无效代码PurgeCSS、Core-JS 按需引入、字体压缩
浏览器渲染加快首次内容绘制内联关键资源、Font Display、取消非必要按需加载
用户感知掩盖加载延迟Loading 动画、骨架屏(Skeleton)

二、详细优化方案

1. 网络传输优化

1.1 启用 TLS 1.3

  • 问题:Initial Connection 与 SSL 握手耗时波动大(尤其弱网);
  • 方案:在阿里云 CDN/服务器上开启 TLS 1.3
  • 效果:减少 1-2 次 RTT,SSL 握手从 2-RTT 降至 1-RTT 或 0-RTT;
  • 验证:Chrome DevTools > Security 面板确认协议版本。

1.2 首屏 HTML 控制在 14KB 以内

  • Why 14KB:TCP 初始拥塞窗口(IW10)约 14KB,可1 个 RTT 传完
  • 措施
    • 使用 html-webpack-plugin 开启 minify
    • 移除内联 <style>,统一由 mini-css-extract-plugin 提取;
    • 移除内联 <script>,脚本合并至入口文件。

1.3 预连接与 DNS 预解析

<head> 中添加:

<!-- 预解析 DNS -->
<link rel="dns-prefetch" href="//ga.example.com" />
<link rel="dns-prefetch" href="//apm.dji.com" />
<link rel="dns-prefetch" href="//cdn.alibaba.com" />

<!-- 预建立连接(含 TLS) -->
<link rel="preconnect" href="https://apm.dji.com" crossorigin />
1
2
3
4
5
6
7

1.4 关键资源 Preload

  • 问题:主 JS/CSS 被浏览器低优先级加载;
  • 方案:使用 preload-webpack-plugin(Webpack 3 兼容版):
    // webpack.config.js
    const PreloadWebpackPlugin = require('preload-webpack-plugin')
    plugins: [
      new PreloadWebpackPlugin({
        rel: 'preload',
        include: ['main', 'vendor'], // 指定 chunk
        fileBlacklist: [/\.map$/]
      })
    ]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  • 效果:关键资源优先级提升至 High,提前下载。

2. 资源体积优化

2.1 按需引入 Polyfill(Core-JS)

  • 问题babel-polyfill 全量引入,vendor 体积臃肿;
  • 方案
    1. 升级 Babel 7;
    2. 移除 babel-polyfill
    3. 配置 .babelrc
      {
        "presets": [
          [
            "@babel/preset-env",
            {
              "useBuiltIns": "usage",
              "corejs": "3.1",
              "modules": false
            }
          ]
        ]
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
  • ⚠️ 重要禁用 @babel/plugin-transform-runtime,否则 useBuiltIns: "usage" 失效(官方 issueopen in new window)。

2.2 删除未使用 CSS(PurgeCSS)

  • 问题:Ant Design 等 UI 库引入大量未用样式;
  • 方案:通过 PostCSS 集成 PurgeCSS;
  • ⚠️ CSS Modules 兼容
    若使用 CSS Modules,必须保留原始 class 名匹配逻辑,参考 官方方案open in new window
    // webpack.config.js 中 css-loader 配置
    {
      loader: 'css-loader',
      options: {
        modules: true,
        getLocalIdent: require('react-dev-utils/getCSSModuleLocalIdent')
      }
    }
    // PurgeCSS content 配置需包含所有 JS/JSX
    content: [paths.appHtml, ...glob.sync(path.join(paths.appSrc, '/**/*.{js,jsx}'))]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

2.3 字体优化

  • 格式升级:优先使用 WOFF2(比 WOFF 小 20-30%);
  • 压缩:使用 fontmin-webpack 插件,仅保留中文/英文字符子集;
  • 缓存:通过 Service Worker 缓存字体文件(Cache API),避免重复下载。

3. 浏览器渲染优化

3.1 取消登录页按需加载

  • 问题:登录页作为着陆页,不应受路由懒加载限制;
  • 方案:将登录页组件直接打包进主 bundle(app.js)
  • 结果:主包从 156KB → 172KB(+16KB),但消除一次网络请求,FCP 提升显著。

3.2 非关键脚本异步加载

  • 第三方脚本(GA、APM)使用 async
    <script async src="https://ga.example.com/analytics.js"></script>
    
    1
  • 自定义非关键 JS 使用 defer(保证执行顺序)。

3.3 字体渲染优化

  • 问题:自定义字体加载前文字不可见(FOIT);
  • 方案:CSS 中添加:
    @font-face {
      font-family: 'MyFont';
      src: url('myfont.woff2') format('woff2');
      font-display: swap; /* 先显示备用字体,再替换 */
    }
    
    1
    2
    3
    4
    5

4. 用户感知优化

4.1 全局 Loading 动画

  • App.vue 中统一管理 loading 状态;
  • 设计提供轻量级动画(避免复杂 SVG/CSS 动画阻塞主线程)。

4.2 骨架屏(Skeleton)

  • 为登录页定制静态骨架屏 HTML(内联在 <body> 中);
  • 用户看到结构占位,感知“内容即将加载”,降低等待焦虑。

4.3 渐进式渲染

  • 页面结构先渲染(含骨架屏);
  • 接口数据返回后再填充可交互内容(如表单、按钮)。

三、构建配置关键修改(Webpack 3)

1. HTML 压缩

new HtmlWebpackPlugin({
  template: 'index.html',
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeRedundantAttributes: true
  }
})
1
2
3
4
5
6
7
8

2. Gzip 预压缩(可选)

const CompressionWebpackPlugin = require('compression-webpack-plugin')
plugins: [
  new CompressionWebpackPlugin({
    filename: '[path].gz[query]',
    algorithm: 'gzip',
    test: /\.(js|css|html|svg)$/,
    threshold: 8192,
    minRatio: 0.8
  })
]
1
2
3
4
5
6
7
8
9
10

注意:Nginx 需配置 gzip_static on; 优先返回 .gz 文件。


四、优化效果对比

指标优化前优化后提升
FCP(平均)1593 ms1281 ms+19.6%
FCP(95 分位)3258 ms2344 ms+28.1%
LCP(平均)1801 ms1454 ms+19.3%
LCP(95 分位)3797 ms2700 ms+28.9%
Load(平均)1431 ms906 ms+36.7%
Lighthouse 评分30+70++133%

结论:通过低风险、小改动的组合优化,首屏性能提升 20%+,用户白屏时间显著缩短。


五、后续建议

  1. 监控:接入前端性能监控(如 Web Vitals),持续跟踪 FCP/LCP;
  2. 重构期:迁移至 Vue 3 + Vite,彻底解决构建与运行时性能瓶颈;
  3. 缓存策略:精细化控制 Service Worker 缓存,实现离线可用。

:本文所有优化方案均已在生产环境验证,无业务功能改动,仅配置与资源策略调整,符合“小改动、快上线”要求。

上次更新:
(adsbygoogle = window.adsbygoogle || []).push({});