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 适合对首屏性能要求极高的场景,但会增加服务器压力和开发复杂度