web端基础性能优化

1. 概念简介

目前检测web页面性能常用的工具是浏览器(侧重Chrome)开发工具里的性能 面板、Lighthouse面板,其中Lighthouse可以生成性能报告。

检测性能之前,一般为了避免浏览器插件的干扰,会选择在无痕模式进行。

F12打开"开发工具",选择Lighthouse,点击"分析网页加载情况"按钮,即可进行性能分析,得到性能报告。我检测的是页面首次打开的性能,所以选择了"停用缓存"。性能报告包含总评分、关键指标、优化建议等。

因为选择了"开发者工具节流(高级)",所以生成的报告后面有一个"View Trace"按钮,View Trace会将刚才的测试数据放到"性能"面板里,用"性能"面板里的工具进一步分析性能问题

|-------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| 关键指标 | 含义 |
| FCP(First Contentful Paint) | 用户++首次++ 导航到网页屏幕首次出现图像或文本的时间 *这是桌面设备的得分区间 |
| LCP(Largest Contentful Paint) | 用户++首次++ 导航到网页屏幕出现视口内最大图片、文本块或视频的时间 *实际测试时,超过1.3s就会标红 |
| TBT(Total Blocking Time) | 在FCP之后,主线程被长任务阻塞到无法响应用户输入的总时间 *长任务:当主线程上存在运行超过50ms的长任务时,主线程会被视为"阻塞" |
| CLS(Cumulative Layout Shift) | 在网页整个生命周期内,页面发生最大布局偏移的分数。 |

2. 优化方案

2.1. 项目体积优化

在不影响功能前提下,体积越小,请求响应的时间会越短,从而减小FCP、LCP指标的时间。

可以使用rollup-plugin-visualizer插件分析打包体积,引入插件后要增加一点代码:

javascript 复制代码
// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer';

export default defineConfig({
    plugins: [
        visualizer({
          open: true, // 打包完成后自动打开报告
          filename: 'stats.html', // 报告生成文件路径
          template: 'treemap',
          sourcemap: true, // 生成 sourcemap
        }),
    ]
})

如果想分析打包后的结构 ,请改为 sourcemap: false。如果想看打包后的体积 ,请改为 sourcemap: true,参考链接

2.1.1. 静态资源优化

2.1.1.1 png图片优化

将[png]格式且大于50KB的图片转换成[webp]格式,保证清晰度的同时减少图片大小

各大浏览器对Webp的支持程度:

清晰度对比:

(补图)

大小对比:

如果不能用webp,还可以用TinyPNG -- 智能压缩您的WebP、JPEG和PNG图片压缩png大小。

2.1.1.2. gif图片优化

gif\]格式转成\[MPEG-4\]格式。对比: ![](https://i-blog.csdnimg.cn/direct/c3783b27422c4b2d93f376ab79d35c3a.png) #### 2.1.2. 开启minify压缩 在vite.config.ts里开启minify: 'terser'。 #### 2.1.3. 引用三方库优化 ##### 2.1.3.1. antd引用优化 把所有antd/lib引用统一改为 antd/es。因为: * /es是基于ESM模块格式,支持按需引入。 * /lib是为了兼容老项目和 nodejs 项目。 ##### 2.1.3.2. 删除重复依赖 通过\`npm ls abc\`分析项目中三方依赖abc是否存在版本冗余,从而决定是否要统一依赖版本。 ##### 2.1.3.3. 维护devDepencies 新增依赖时要考虑依赖用于生产环境还是开发环境,用在开发环境的依赖尽量不要放到depencies里,增加生产打包的依赖体积。 ### 2.2. 请求响应优化 在项目体积不变的前提下,请求响应的速度越快,FCP、LCP指标的时间越短。 #### 2.2.1. gzip/br压缩 压缩在接口响应阶段生效,网络中间层(如网关)对js/css**资源** 、响应体为**JSON**类型的响应进行压缩,降低传输数据的大小,从而提高响应速度。 比如阿里云支持Gzip压缩、Brotli压缩,通过一键配置就能降低传输数据的大小。 \*注意:gzip、br不会压缩二进制类型的响应。 #### 2.2.2. 预连接/预解析 通过提前解析DNS或建立连接,从而减少连接时间。 |------------------|--------------------------------------------------------------------------------------------------------------| | 预解析 dns-prefetch | 只做一次DNS解析,并将解析后的IP缓存到浏览器或者OS里。 | | 预连接 preconnect | 提前DNS解析、建立TCP连接。如果是HTTPS,还会做TLS/SSL握手。在真正请求资源时,可以直接发送HTTP/HTTPS请求。 **注意**:预连接会占用带宽,如果预连接后10s内不请求的话,浏览器会关闭连接。 | 参考:https://web.dev/articles/efficiently-load-third-party-javascript #### 2.2.3. 分包调整 在vite.config.js里,通过manualChunks属性自定义创建共享包块(chunk)。合适的分包能降低首屏资源的加载体积,从而提高性能指标。 #### 2.3. 代码层面 代码层面通常要具体页面具体分析了,建议结合"性能"面板里的工具分析。 比如,首页图片比较多,可以考虑采用LazyLoad,避免将图片一次性加载完,降低LCP时间。 ## 3. 总结 ### 3.1. 总结上述用到的优化方法 1. 优化图片体积 2. 尽可能压缩代码 3. 删除重复依赖 4. 对重要资源做预连接 5. 调整manualChuncks 6. 使用LazyLoad、定时器做延迟加载,提高LCP 7. 减少页面发生偏移的情况 ### 3.2. 代码建议 1. 优先使用Fragment组件减少DOM深度,避免DOM元素数量过大。复杂的布局可能会影响用户交互体验,Lighthouse 会对超过800个DOM节点的网页发出警告。 2. 简化CSS选择器有助于加快网页的CSS计算速度。[参考](https://web.dev/articles/reduce-the-scope-and-complexity-of-style-calculations?hl=zh-cn "参考") ```css .box:last-child .title { /* styles */ } .final-box-title { /* styles */ } ``` 3. 在滚动、拖拽、resize等短时间进行大量操作DOM的场景下,避免卡顿的方式有四种: a. 使用防抖节流降低函数触发频率 b. 将读操作和写操作分开处理,在大多数情况下,应该是先读后写: ```javascript // 例1,先写后读(不推荐) function logBoxHeight () { box.classList.add('super-big'); // 先添加新的类 // 因为添加新的类后直接读取offsetHeight,所以浏览器会在当前帧立刻重新计算样式(强制同步布局)。 console.log(box.offsetHeight); } // 例2,如果新的类不影响offsetHeight的值,建议先读后写 function logBoxHeight () { // 浏览器会拿上一帧的布局值 console.log(box.offsetHeight); // 先读取offsetHeight box.classList.add('super-big'); // 后添加新的类 } ``` c. 基于b方法,使用requestAnimationFrame封装函数,要求浏览器在下次重绘前调用函数。 d. 引入三方库FastDOM解决意外触发"强制同步布局"的问题。 常见引发重排重绘的属性和方法:offsetLeft、clientLeft、getBoundingClientRect等,详细请看https://gist.github.com/paulirish/5d52fb081b3570c81e3a 4. 引入依赖包尽量少用\`import \* from xxx\` ## 4. 附录 ### 4.1. png转webp方式 使用 Google开源的工具[Squoosh](https://squoosh.app/ "Squoosh"),gif转mp4:使用[Online GIF to MP4 Video converter](https://ezgif.com/gif-to-mp4 "Online GIF to MP4 Video converter")。 Squoosh不支持批量处理。[AnyWebp](https://anywebp.com/ "AnyWebp")可以批量处理图片,缺点是不可以自定义输出质量。 如果想批量处理png转webp,并且要自定义输出图片质量,可以采用本地转换的方式: 先安装[cwebp库](https://developers.google.com/speed/webp/docs/precompiled?hl=zh-cn "cwebp库"),本地配置系统环境变量。先测试单图转换:\`cwebp -q 100 image.png -o image.webp\`,如果没问题可以新建一个bat文件做批量转换: ```bash # 不一定要用这个代码,根据自己想要的交互让AI生成也很不错的! # 新建一个convert.bat文件,复制以下内容。 # 通过命令调用:./convert.bat [Image Folder Path] # 该bat支持对文件夹内的所有png格式转成webp @echo off echo Starting PNG to WebP conversion... REM Check if a folder path is provided if "%~1"=="" ( echo Usage: convert.bat [Image Folder Path] pause exit /b ) set "inputDir=%~1" REM Check if the specified folder exists if not exist "%inputDir%" ( echo Error: Folder "%inputDir%" does not exist. pause exit /b ) REM Iterate through all .png files in the specified folder for %%i in ("%inputDir%\*.png") do ( echo Converting %%i ... cwebp -q 100 "%%i" -o "%%~dpi%%~ni.webp" if errorlevel 1 ( echo Error: Failed to convert %%i. ) else ( echo Success: %%i has been converted to %%~dpi%%~ni.webp ) ) echo All conversions completed. Pause  ``` ### 4.2 获取中文版的lighthouse性能报告 如果devtools设置的是英文或者短暂设置成中文,通过devtools的lighthouse生成的报告可能不是中文,不方便解决性能问题。所以可以通过还有第二种方法生成中文报告。 ![](https://i-blog.csdnimg.cn/direct/2b68407ef02c422f8a7c12d03b2798ad.png) ### 4.3 参考链接 [https://web.dev/learn/performance/welcome](https://web.dev/learn/performance/welcome "https://web.dev/learn/performance/welcome") [https://developer.chrome.com/docs/performance?hl=zh-cn](https://developer.chrome.com/docs/performance?hl=zh-cn "https://developer.chrome.com/docs/performance?hl=zh-cn") [https://developer.chrome.com/docs/lighthouse/performance/mainthread-work-breakdown?utm_source=lighthouse\&utm_medium=node\&hl=zh-cn](https://developer.chrome.com/docs/lighthouse/performance/mainthread-work-breakdown?utm_source=lighthouse&utm_medium=node&hl=zh-cn "https://developer.chrome.com/docs/lighthouse/performance/mainthread-work-breakdown?utm_source=lighthouse&utm_medium=node&hl=zh-cn") [https://developer.chrome.com/docs/devtools/lighthouse?hl=zh-cn#main](https://developer.chrome.com/docs/devtools/lighthouse?hl=zh-cn#main "https://developer.chrome.com/docs/devtools/lighthouse?hl=zh-cn#main") [https://github.com/GoogleChrome/lighthouse/blob/main/docs/throttling.md](https://github.com/GoogleChrome/lighthouse/blob/main/docs/throttling.md "https://github.com/GoogleChrome/lighthouse/blob/main/docs/throttling.md") [https://ethcar.github.io/lighthouse/docs/throttling.html](https://ethcar.github.io/lighthouse/docs/throttling.html "https://ethcar.github.io/lighthouse/docs/throttling.html") [https://developer.chrome.com/docs/devtools/performance/reference](https://developer.chrome.com/docs/devtools/performance/reference "https://developer.chrome.com/docs/devtools/performance/reference")

相关推荐
zero13_小葵司3 小时前
JavaScript性能优化系列(八)弱网环境体验优化 - 8.2 离线支持:Service Worker实现基本离线功能
开发语言·javascript·性能优化
电商API_180079052476 小时前
淘宝详情数据 API 返回字段全解析:核心字段说明 + 开发避坑指南
大数据·数据库·性能优化·数据挖掘·数据分析·网络爬虫
心态还需努力呀17 小时前
CANN 特性能力解析-以 ACLNN 为核心的算子性能优化之道
性能优化
趁你还年轻_17 小时前
PGVector 检索性能优化完整指南
性能优化
han_18 小时前
前端性能优化之CSS篇
前端·javascript·性能优化
haofafa1 天前
JavaScript性能优化实战
开发语言·javascript·性能优化
songgeb1 天前
[WWDC 21]Detect and diagnose memory issues 笔记
性能优化·swift
云飞云共享云桌面2 天前
如何降低非标自动化工厂的研发软件采购成本
运维·服务器·网络·数据库·性能优化·自动化
超级战斗鸡2 天前
React 性能优化教程:useMemo 和 useCallback 的正确使用方式
前端·react.js·性能优化