性能优化之首屏加载优化
首屏时间(First Contentful Paint),指浏览器从响应用户输入地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但要展示当前视窗需要的内容,首屏加载可以说是用户体验中最重要的环节。
一、首屏时间计算
DOMContentLoaded 事件在 HTML 文档完全加载和解析后触发。计算首屏时间如下:
document.addEventListener('DOMContentLoaded', (event) => {
console.log('first contentful painting', event);
});
输出:

Performance 可以获取到当前页面中与性能相关的信息,可用于计算白屏时间:
performance.timing.responseStart - performance.timing.navigationStart
二、首屏加载慢的原因
- 网络延时问题
- 资源文件体积是否过大
- 资源是否重复发送请求
- 加载脚本时渲染内容堵塞
三、首屏优化常用方法
- 减小入口文件体积
- 静态资源本地缓存
- 引用库的按需加载
- 图片资源的压缩
- 启用 gzip 压缩
- 使用 SSR 服务端渲染
1、减小入口文件体积
常用的手段是路由懒加载,把不同路由对应的组件分割成不同的代码块,等路由被请求时会单独打包路由,使入口文件变小,提高加载速度:

举个例子:
在 Vue Router 配置路由时,采用动态加载路由懒加载的形式:
src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../components/Home.vue'
import About from '../components/About.vue'
const routes = [
{
path: '/',
component: Home,
component: () => import('../components/Home.vue')
},
{
path: '/about',
component: About,
component: () => import('../components/About.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
以函数的形式加载路由,这样就可以把各自的路由文件分别打包,只有在解析给定的路由时,才会加载路由组件。
2、静态资源本地缓存
后端返回的资源,可以:
- 采用 HTTP 缓存,设置 Cache-Control,Last-Modified,Etag 等响应头;
- 采用 Service Worker 离线缓存;
- 合理利用 localStorage。
3、引用库的按需加载
4、图片资源的压缩
页面上使用到的 icon,可以使用在线字体图标或雪碧图,以减轻 HTTP 请求压力。
对于体积较大的图片,可以单独进行压缩。
5、启用 gzip 压缩
工作原理:

- 浏览器请求 url,并在请求头中设置属性
accept-encoding:gzip
,表明浏览器支持 gzip; - 服务器收到浏览器发送的请求后,会返回压缩后的文件,并在响应头中加上 content-encoding: gzip,如果没有压缩文件,服务器会返回未压缩的请求文件;
- 浏览器接收服务器的响应,根据 content-encoding: gzip 响应头使用 gzip 策略去解压资源,通过
content-type
内容类型决定怎么编码读取该文件的内容。
启用方法:
- Webpack 通过使用 CompressionWebpackPlugin 插件来启用 gzip;
- Vite 通过设置 build.reportCompressedSize 来启用 gzip。
6、使用 SSR 服务端渲染
四、更多方案
页面渲染优化 | 优化 HTML 代码 |
|
优化 JS、CSS 代码 |
| |
优化动画效果 |
| |
资源加载优化 | 减少资源大小 |
|
减少 HTTP 请求 |
| |
提高 HTTP 请求响应速度 |
| |
优化资源加载时机 |
|