再战前端性能优化 超详细汇总

2,981 阅读6分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金

基于细节进行性能实战优化处理,包括 Quasar 重构替换,图片压缩和 base64 转化,SplitChunksPlugin 代码分割,组件性能优化,代码性能优化,代码重构,lighthouse分析优化等等

前言

之前写了一篇前端性能优化实战 从 30s 到 2s的文章,是从大方向上进行优化的,主要是插件的按需引入,加上 gzip 压缩配置。

随着项目的不断迭代,包体积又开始变大了,首屏加载也需要进一步优化了。

这篇主要是讲一下细节的优化点,进行进一步的优化处理。

优化前分析(v5.8 版本)

构建后文件分析

本地环境 localhost 打包后的文件分析:

  1. 有四张图片太大,需要优化
  2. 入口文件总大小为 3.22MB,包括 runtime.js(4.41KB)、main.js(3.16MB,压缩后 804KB)、main.css(57.3KB),总体太大,需要优化;
  3. 其他文件大小,例如:common.js(56.6KB),common.css(1.22KB),vendor.js(184KB,压缩后 60KB)

webpack-bundle-analyzer 包分析

// package.json文件
{
  "scripts": {
    "analyzer": "easy build prod -s",
    "stats": "easy build prod -s stats"
  },
}

// 运行命令
$ npm run analyzer

js 包文件分析:所有包之和为 6.45MB(压缩后为 1.45MB),其中 main.js 为 3.16MB(压缩后 804KB)

ic_compare_4.png

lighthouse 报告分析

通过谷歌浏览器内嵌的lighthouse 分析首页(home)

(1)谷歌浏览器内嵌 lighthouse 配置如下图所示: ic_compare_7.png

(2) 具体分析报告: ic_compare_8.png

(3)可将分析文件,以 JSON 或者 HTML 形式保存到本地:lighthouse_v5.8.jsonlighthouse_v5.8.html

通过分析网站:googlechrome.github.io/lighthouse/…,加载上面的 json 文件,以后也可以看到具体的报告了

Quasar 优化(main.js 减少 62KB)

上一篇文章,对 Quasar 进行了按需引入配置。

Quasar 主要用于框架的搭建(头部,菜单栏,tags 导航栏)、登陆页和一些弹框提示。为了保证 UI 的统一,没多大必要用两个框架。

这次进行了代码的重构,将之前用到的一些 Quasar 组件用 Ant Design Vue 进行替换,再修改按需引入的组件配置,引入包就更小了。

整体布局和 Menu 没改,其他都改了,都换成了 Ant Design Vue。

(1)改造前后 Quasar 对比

改造前 Quasar 的相关文件大小为 563.32KB(Gzipped 大小为 131.34 KB):

改造后 Quasar 的相关文件大小为 453.75KB,减少了110KB

(2)改造前后包大小对比

所有包之和为 6.39MB(压缩后为 1.43MB),入口文件大小为 3.16MB,其中 main.js 为 3.1MB(压缩后 789KB)减少了0.06MB(即62KB) ic_compare_9_1.png

图片性能优化(图片减少 57%)

详细配置可看前端性能优化之图片优化,图片资源减少了约 57%

图片资源优化前后对比:

  • 优化前:4.6MB,110 张图片
  • 优化后:2MB,减少了 57%,图片也减为 42 张了,减少了 68 张

首页 home 分析

优化后,有缓存的情况下,再次加载 home 页,可以分析:

  1. 缓存 disk cache:打包的 css 文件、通过 script 引入的 js 文件
  2. 缓存 memory cache:打包的 js 缓存,base64 图片
  3. 多了很多 base64 图片,都是些小图标

ic_compare_11_3.png

代码分割优化(包减少 26%)

详细配置可看前端性能优化之代码分割,bundle 包减少了 26%

代码分割(Code Splitting)优化前后对比:虽然入口文件增加了 72 KB,但是 main.js 分成了两个文件,可以并行加载,仍可能提高首屏速度

  • 优化前:总包 6.57MB,入口文件 3.16MB,main.js3.1MB
  • 优化后:总包 4.85MB(减少1.78MB),入口文件 3.23MB(增加0.06MB),main.js(1.86MB) + ant_design.js(1.31MB)

优化后分析(v5.8 版本)

构建后分析:

  • 优化前:总包 6.45MB(压缩后为 1.45MB),入口文件 3.22MB,其中 main.js 3.1MB
  • 优化后:总包 4.85MB(减少1.6MB),入口文件 3.23MB(增加0.01MB),main.js(1.86MB) + ant_design.js(1.31MB) ic_compare_13.png

Lighthouse 分析:Performance 减少了 3 分,其他的没变,这确实有点尴尬了

ic_compare_13_1.png

后续优化方向

之后的优化方向:

  1. 针对 Lighthouse 的分析报告,进行逐项优化,提高分数
  2. Performance 面板针对行优化
  3. 组件性能优化
  4. 开发性能优化
  5. 重构优化

可参照接下来的项进行优化,当然有些是已经实现了的,下面列举的是优化总汇

Lighthouse 优化

具体分析报告以及解析可查看:Lighthouse 实战 超详细解析 逐项分析优化,根据 lighthouse 报告总结出了十多条优化建议

实际优化操作:先优化了如下几项,试下水

  1. 字体样式控制:在 @font-face样式中添加font-display: swap
  2. img 图片添加 alt 属性
  3. a 标签添加可链接的 href 属性
  4. PWA 配置开启

PWA 详细配置文档:easywebpack pwa 配置

开发性能优化

  1. 路由懒加载:用不同路由将对应组件分割成不同的代码块,实现按需加载,被访问时才加载对应组件
  2. 组件懒加载、异步组件
  3. 组件化开发:公共组件提取和封装,降低模块之间的耦合度,将相关的请求、资源、逻辑等都封装在内部
  4. 服务端渲染 SSR
  • 优点
    • 更好的 SEO
    • 首屏渲染更快
  • 缺点
    • 需要使用 NodeJS,增加开发难度
    • 服务端渲染增加了服务器的负载压力
    • 开发条件限制:生命周期、浏览器特定属性、第三方库的区别及兼容使用,毕竟服务端和客户端环境还是不太一样的
  1. 加载优先级处理:根据可见性判断,首屏可见部分优先加载,其余的懒加载
  2. 判断可见性:监听滚动事件、resize 事件;IntersectionObserver
  3. 骨架屏使用:替代白屏,提高可读性

组件性能优化

  1. 函数式组件:一个不包含状态和实例的组件,减少响应式带来的性能消耗
  2. 局部变量:响应式对象和非响应式对象的合理使用,不需要响应的数据不要定义在 data 中,直接定义在实例上就行
  3. 长列表性能优化:可以通过 Object.freeze 方法来冻结一个对象,但不能被修改了
  4. 使用 Deferred 组件延时分批渲染组件, 一次的组件渲染拆成多次
  5. 使用 Time slicing 时间片切割技术,避免页面卡死
  6. 使用 Non-reactive data 非响应式数据,减少递归响应式的逻辑,相当于减少了这部分的性能损耗
  7. 使用 Virtual scrolling 虚拟滚动组件
  8. computedwatch 的合理使用
  9. v-ifv-show 的合理使用
  10. 巧用 KeepAlive 动态组件缓存 DOM,避免不必要的性能浪费
  11. v-forv-if 不要同时使用,可用计算属性代替 v-if
  12. v-for 必须添加 key,但不要用 index

参考文章:

重构方案和计划

随着项目的敏捷开发快速迭代,冗余代码和结构越来越多,适度的代码重构是很必要的,可提高代码的可读性和代码质量,具体可查看:前端性能优化之重构方案和计划