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,
}
解答
路由懒加载
将不同路由对应的组件分割成不同代码块,按需加载:
routes: [
{
path: 'Blogs',
name: 'ShowBlogs',
component: () => import('./components/ShowBlogs.vue')
}
]
静态资源缓存
后端设置 HTTP 缓存头:
Cache-Control, Last-Modified, Etag
前端使用 localStorage 或 Service Worker 离线缓存。
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)
Vue.use(Pagination)
避免组件重复打包
在 webpack 配置中设置 CommonsChunkPlugin:
minChunks: 3
将使用 3 次及以上的包抽离到公共依赖文件。
图片资源优化
- 压缩图片资源
- 使用字体图标或雪碧图替代小图标
- 减少 HTTP 请求数量
开启 Gzip 压缩
安装插件:
npm i compression-webpack-plugin -D
配置 webpack:
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,
deleteOriginalAssets: false
})]
}
}
}
服务端配置(Express):
const compression = require('compression')
app.use(compression())
使用 SSR
服务端渲染可以直接返回 HTML 字符串,Vue 应用推荐使用 Nuxt.js 实现。
关键点
- 路由懒加载减小入口文件体积,按需加载组件
- 合理使用缓存策略(HTTP 缓存、localStorage、Service Worker)
- UI 框架按需引入,避免加载无用代码
- 开启 Gzip 压缩可显著减小资源体积
- 图片优化和避免重复打包能有效减少请求数量
目录