前言
最近做性能优化,发现总是曾经做过的性能优化方案和分析工具都忘了,需要重新搜集资料,并进行开发。于是开始记录,留作以后查询。
性能分析工具
- Performance
- Lighthouse
- Memory
- Vue Devtools / React Developer Tools
- webpack-bundle-analyzer
- rollup-plugin-visualizer
性能指标
- Largest Contentful Paint (LCP) :衡量加载 性能。为了提供良好的用户体验,应在网页首次开始加载的 2.5 秒内完成 LCP。
- Interaction to Next Paint (INP) :衡量互动性 。为了提供良好的用户体验,网页的 INP 应不超过 200 毫秒。
- Cumulative Layout Shift (CLS) :衡量视觉稳定性 。为了提供良好的用户体验,网页的 CLS 应保持在 0.1 或更低。
项目记录
分析
项目性能分析是性能优化最重要的一项工作,通过性能分析可以找到具体的性能问题所在,便于优化。一般来说,性能优化的过程是:
- 性能分析
- 性能优化
- 结果验证
循环往复,性能优化是一个长期工作,需要时时监控,在性能下降时及时优化。
lighthouse 性能分析结果
由这个结果可以看到,这个网站的性能相当差,按50分为及格线可以说刚刚及格,于是可以简单根据这个测试结果设置一个基础目标,将性能分提升到90分以上。
问题分析
真实优化过程是分析一个问题,解决一个问题,验证一个问题,在这里为了方便观看,就将问题都直接汇总。
前端实际上是对资源的加载和渲染,所以以资源加载过程做状态划分。
资源加载
资源加载的优化可以分为两个方面。
- 加载速度
- 加载体积
先从加载资源体积开始优化。要优化加载资源的体积,可以对资源进行压缩,也可以减少传输的资源。
首先是压缩资源。
现在的打包构建工具例如 vite 和 webpack 都自动支持对静态资源的压缩。在默认压缩基础上,我们可以配置打开 gizp 压缩进行传输。
gzip 压缩
在 vite 中可以使用vite-plugin-compression2插件进行压缩。
javascript
import { defineConfig } from 'vite'
import { compression } from 'vite-plugin-compression2'
import { visualizer } from "rollup-plugin-visualizer";
export default defineConfig({
plugins: [
// ...your plugin
compression(),
// 分析打包结果
visualizer({
open: true, // 构建结束后自动在浏览器中打开报告
gzipSize: true, // 显示经过 gzip 压缩后的文件大小
brotliSize: true, // 显示经过 brotli 压缩后的文件大小
filename: "stats.html" // 报告生成的文件名称
})
]
})
通过打包分析可以看到,相对于未压缩资源,资源体积压缩效果非常明显,达到了100%。
同时需要对nginx进行配置,启用gizp资源。
bash
# nginx.conf 文件
http {
include mime.types;
default_type application/octet-stream;
# 添加对 .mjs 文件的支持
types {
application/javascript js mjs; # 同时支持 .js 和 .mjs
}
# 开启gzip
gzip on;
# 静态压缩
gzip_static on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png image/jpg;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
}
分包
vite 分包有两种方式,一种是动态分包一种是静态分包。动态分包是vite根据import自动处理,比如动态加载路由,静态分包是将一些稳定不会变化的包单独打包,比如vue。
这里主要说静态分包。manualChunks 接收一个对象或者函数,将配置的第三方包单独生成,key为包的前缀。
css
export default defineConfig(({ mode }) => {
build: {
rollupOptions: {
output: {
manualChunks: {
vue: ["vue", "pinia", "vue-router"],
naive: ["naive-ui"]
}
}
}
}
};
});
第二次分析
做完以上优化,可以再次看下 lighthouse 性能分数。
现在已经78分了,距离我们的目标只差12分了,胜利近在眼前。
项目中具体优化
以上是一些通用的优化策略,接下来需要根据具体问题来进行优化。
normalize.css
项目中采用的社区的 normalize.css npm 包,这导致 normalize.css 文件需要单独加载,这阻塞了页面渲染,所以我们可以将 normalize.css 配置提取到 index.html 中,以加快渲染。
图片懒加载
分析首页是列表型页面,具有大量图片,所以针对首屏中不显示的图片,可以设置懒加载。
图片资源压缩
由于图片是运营人员上传,所以可以在上传时自动压缩,并转换为 webpg 等较高性能的压缩格式。
还有其他的方案则是结合具体情况具体分析。以上都是针对用户首次进入网页的性能优化,我们还可以使用缓存,cdn等方案提升用户后续进入网页的性能。
最终
完成目标,如果条件允许,可以上服务端渲染,首页性能会有质的提升。