SPA 首屏加载优化
解决单页应用首屏加载速度慢的实用方案
问题
SPA(单页应用)首屏加载速度慢,影响用户体验。首屏时间(First Contentful Paint)指从用户输入网址到首屏内容渲染完成的时间。
可以通过以下方式计算首屏时间:
// 方案一:DOMContentLoaded
document.addEventListener('DOMContentLoaded', (event) => {
console.log('first contentful painting');
});
// 方案二:Performance API
performance.getEntriesByName("first-contentful-paint")[0].startTime
// 返回结构:
// {
// name: "first-contentful-paint",
// entryType: "paint",
// startTime: 507.80000002123415,
// duration: 0,
// }
加载慢的主要原因:网络延时、资源文件体积过大、重复请求资源、脚本加载阻塞渲染。
解答
1. 路由懒加载
通过动态导入减小入口文件体积,按需加载路由组件:
routes: [
{
path: 'Blogs',
name: 'ShowBlogs',
component: () => import('./components/ShowBlogs.vue')
}
]
2. 静态资源缓存
后端设置 HTTP 缓存头:
// 设置 Cache-Control、Last-Modified、Etag
// 或使用 Service Worker 离线缓存
前端使用 localStorage 缓存数据。
3. UI 框架按需加载
避免引入整个 UI 库,只导入使用的组件:
// 不推荐
import ElementUI from 'element-ui'
Vue.use(ElementUI)
// 推荐
import { Button, Input, Pagination, Table, TableColumn, MessageBox } from 'element-ui'
Vue.use(Button)
Vue.use(Input)
4. 避免组件重复打包
配置 webpack 的 CommonsChunkPlugin,提取公共依赖:
minChunks: 3 // 使用 3 次及以上的包会被抽离到公共文件
5. 图片资源优化
- 压缩图片文件
- 使用字体图标或雪碧图替代小图标
- 减少 HTTP 请求数量
6. 开启 Gzip 压缩
安装并配置 compression-webpack-plugin:
cnpm i compression-webpack-plugin -D
在 vue.config.js 中配置:
const CompressionPlugin = require('compression-webpack-plugin')
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.mode = 'production'
return {
plugins: [new CompressionPlugin({
test: /\.js$|\.html$|\.css/,
threshold: 10240, // 对超过 10k 的数据压缩
deleteOriginalAssets: false
})]
}
}
}
服务端配置(Express):
const compression = require('compression')
app.use(compression()) // 在其他中间件之前调用
7. 使用 SSR
服务端渲染(Server Side Rendering)在服务器生成 HTML,直接发送给浏览器。Vue 应用推荐使用 Nuxt.js 实现 SSR。
关键点
- 路由懒加载可以显著减小入口文件体积,提升首屏加载速度
- HTTP 缓存和 localStorage 能有效减少重复请求
- UI 框架按需加载可以减少 30%-50% 的打包体积
- Gzip 压缩能将文件体积压缩至原来的 30% 左右
- SSR 适合对首屏性能要求极高的场景,但会增加服务器压力和开发复杂度
目录