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格式。对比:

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计算速度。参考

css 复制代码
<!-- 浏览器需要一点时间来确认"一个类为title的元素,它父元素的类是box的最后一个元素" -->
.box:last-child .title {
  /* styles */
}

<!-- 如果可以,定义更具体的类会更好 -->
.final-box-title {
  /* styles */
}
  1. 在滚动、拖拽、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

  1. 引入依赖包尽量少用`import * from xxx`

4. 附录

4.1. png转webp方式

使用 Google开源的工具Squoosh,gif转mp4:使用Online GIF to MP4 Video converter

Squoosh不支持批量处理。AnyWebp可以批量处理图片,缺点是不可以自定义输出质量。

如果想批量处理png转webp,并且要自定义输出图片质量,可以采用本地转换的方式:

先安装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生成的报告可能不是中文,不方便解决性能问题。所以可以通过还有第二种方法生成中文报告。

4.3 参考链接

https://web.dev/learn/performance/welcome
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/devtools/lighthouse?hl=zh-cn#main
https://github.com/GoogleChrome/lighthouse/blob/main/docs/throttling.md
https://ethcar.github.io/lighthouse/docs/throttling.html
https://developer.chrome.com/docs/devtools/performance/reference

相关推荐
JacksonMx6 小时前
@Transactional 最佳实践
java·spring boot·spring·性能优化
梵得儿SHI15 小时前
Vue3 项目实战与性能优化:组合式 API 进阶、响应式高级用法、可复用逻辑封装与新特性全解
性能优化
小小编程路16 小时前
架构与性能优化
性能优化·架构
之歆1 天前
Day16_JavaScript 轮播图与事件工程实战(下篇)
服务器·开发语言·前端·javascript·网络·性能优化
UWA1 天前
5秒快速开玩:小游戏性能优化实战
性能优化·游戏开发·minigame·particlesystem
MU在掘金916951 天前
让LLM按维度自动切换分析策略:SmartInspector 的 Prompt Skill 系统
性能优化
2501_916007471 天前
iOS应用性能优化全面指南:从内存管理到工具使用
android·ios·性能优化·小程序·uni-app·iphone·webview
代码小书生1 天前
Windows系统优化设置,电脑系统工具箱!支持远程桌面控制、性能优化调节、功能选项增强设置、驱动安装更新、系统更新管理、安全配置与系统维护!
windows·性能优化·系统优化·电脑系统·电脑技巧·windows10·电脑优化
光泽雨2 天前
ADO.NET 进阶知识与实战坑位深度解析
性能优化·架构·.net