在前端面试中,首屏优化一直是常见的前端性能面试题。
我们可以先用 performance 相关API
来统计下页面的 DOM 加载时间
。
旧版统计方法,使用 performance
:
js
// 旧版统计性能 performance.timing 已废弃,不推荐使用
window.onload = () => {
console.log(performance.timing.domComplete - performance.timing.navigationStart);
}
新版统计方法,使用 PerformanceObserver
(推荐使用):
js
// 新版统计性能 推荐使用
window.onload = () => {
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.log(entry.domComplete);
})
})
observer.observe({ entryTypes: ['navigation'] })
}
如果 DOM加载时间
过长,比如超过 1s,就需要考虑进行优化了,优化的话主要从以下几个方向进行:
- 网络资源请求
- 构建工具
- 渲染
- 用户体验
一、网络资源请求
1.1 减少请求个数
- 图片采用
雪碧图(CSS Sprites)
,base64
,WebP
,图片懒加载,只加载可视区域内的图片。 - 某些关键 CSS 可以采用
style
标签内联的方式,减少 CSS 资源请求数量。 - 某些数据及时性要求没那么高,可以增加接口缓存,减少请求次数。
1.2 加快请求速度
- 将图片进行压缩,减少图片大小
- 将静态资源
html、css、js 以及图片
都上传到cdn
。
二、构建工具
这里以 webpack
为例。
2.1 按需打包
对于一些第三方包,我们有时候并不会用到包里全部的内容,这时候就可以根据自己使用的部分进行按需打包,以减少打包后的文件体积。比如 Element-UI、Vant
等组件库、lodash、moment
等三方包。
2.2 代码分割 splitChunks
可以手动配置 splitChunks
进行代码分割:
- 将一些不怎么变动的包提取到一起,提高缓存复用率。
- 一些比较大的包,可以单独进行代码分割,按需加载
- 使用异步组件 和异步路由会自动进行代码分割,推荐将路由都设置为异步加载,一些比较大的组件,可以定义为异步组件,按需再加载。
2.3 配置 externals
externals
的作用是可以让某些特定的依赖不打包到最终的 bundle
中,这样可以大大减少打包后的包体积。
2.4 开启 tree-shaking
tree-shaking
摇树优化能消除未使用的代码,减少打包体积。
2.5 开启 gzip 压缩
可以使用 compression-webpack-plugin
在打包过程中对资源文件进行压缩,并在服务器开启 gzip
,比如如果前端静态资源服务器用的 nginx
,就需要修改 nginx
配置。
三、渲染层面
3.1 预渲染(Prerendering)
预渲染就是在构建时生成静态的 HTML,相比于单页应用需要在加载完 javascript 后再通过 js 渲染的方式,预渲染的首屏加载速度会快很多,而且 SEO 也更友好。
适用场景:内容基本静态的页面,且需要更好的用户体验和 SEO 友好。
3.2 服务端渲染(Server-Side Rendering)
服务端渲染(Server-Side Rendering,简称 SSR)是一种在服务器端将 Vue
组件渲染成HTML 字符串
的技术。它在服务端拼接好 HTML字符串
,然后发送给客户端,客户端无需等待下载和执行 javascript
,可以直接渲染页面,这样能极大提升首屏渲染速度,SEO也更为友好。
适用场景:需要优化 SEO,对首屏性能敏感,内容安全性高,能接受服务端渲染需要的额外服务器成本。
四、用户体验
4.1 骨架屏(Skeleton Screen)
骨架屏是在内容加载前展示页面的大致结构框架,用于提升用户感知性能。
注意点:骨架屏最好是需要在打包时直接注入到 html 中,那种组件库里面的骨架屏组件的渲染太靠后了,比如 Vant 的
<van-skeleton>
组件,其效果会差很多。
4.2 懒加载
- 图片懒加载: 只加载可视区域内的图片。
- 路由懒加载: 只加载当前路由的资源。
- 组件懒加载: 只加载当前用到的组件。
- 第三方库懒加载: 使用动态 import 加载第三方库。
- 按需加载样式/脚本: 以动态创建
script标签/link标签
的方式按需加载脚本/样式。
小结
本文介绍了首屏优化的一些思路和方案,主要从 网络资源请求
、构建工具
、渲染
和 用户体验
四方面进行优化。
- 网络资源请求:减少请求个数和加快请求速度。
- 构建工具:通过按需打包、代码分割、externals、tree-shaking、gzip 等方式进行优化。
- 渲染:通过预渲染/服务端渲染提高首屏速度。
- 用户体验:通过骨架屏和懒加载,提高用户体验。