大家好,我是前端架构师 ,关注微信公众号【程序员大卫】,免费领取精品前端资料。
背景
我将分享一些我在公司项目中实际操作的优化方法,最终使得项目的首屏加载速度显著提升。以下是优化前后的对比。
性能对比:
| 指标 | 优化前 | 优化后 |
|---|---|---|
| JS 文件大小 | 32MB | 4MB |
| 首屏加载时间 | 12秒 | 2秒 |
从上面的对比可以看到,优化后项目加载速度有了质的飞跃,首屏加载时间从 11 秒降到了 1 秒,JS 文件的体积也减少了 80%以上。
优化步骤解析
接下来,我会详细讲解我在项目中实施的优化措施。
1. 分析打包体积,找出性能瓶颈
通过使用 webpack-bundle-analyzer 插件,我们可以直观地查看项目打包后各个文件的体积分布,并发现哪些模块占用了过多的空间。比如,element-plus、echarts 等文件的体积非常庞大,这些文件直接影响了加载速度和构建时间。
可以使用按需加载 element-plus 组件,echarts 不要全局引入,按模块需要引入。
安装 webpack-bundle-analyzer 插件:
bash
npm install webpack-bundle-analyzer -D
配置 webpack 以启用分析:
javascript
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
module.exports = {
configureWebpack: {
plugins: [
new BundleAnalyzerPlugin() // 用于展示各个模块的大小和依赖关系
]
}
};
2. 使用cdn加载第三方js
使用 CDN 加速是常见的优化方式,它能显著减少项目的打包体积、提高页面加载速度并减少服务器带宽压力。
1. 将 CDN 资源提取到配置文件中
首先,你可以将 CDN 配置提取到一个独立的文件中(如 cdn-config.js),并在 vue.config.js 中动态加载。这种方式更灵活且易于维护,尤其是当项目有多个环境(开发、测试、生产)时。
cdn-config.js 示例:
javascript
module.exports = {
vue: 'https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.min.js',
'element-ui': 'https://cdn.jsdelivr.net/npm/element-ui@2.15.0/lib/index.js',
echarts: 'https://cdn.jsdelivr.net/npm/echarts@5.1.2/dist/echarts.min.js',
css: {
'element-ui': 'https://cdn.jsdelivr.net/npm/element-ui@2.15.0/lib/theme-chalk/index.min.css',
},
};
2. 动态加载 CDN 链接
然后,在 vue.config.js 中动态加载这些 CDN 配置,并通过 chainWebpack 插入到 HTML 中。这种方式可以减少硬编码,提高可维护性,并且更灵活地切换 CDN。
vue.config.js 示例:
javascript
const cdn = require('./cdn-config.js');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
configureWebpack: {
externals: isProduction ? {
vue: 'Vue',
'element-ui': 'ELEMENT',
echarts: 'echarts'
} : {}
},
chainWebpack: config => {
config.plugin('html').tap(args => {
args[0].cdn = {
js: Object.values(cdn).filter(url => url.endsWith('.js')),
css: Object.values(cdn.css || {})
};
return args;
});
}
};
3. 在 HTML 模板中插入 CDN 资源
在 index.html 中,我们使用 html-webpack-plugin 插入 CDN 资源。通过 htmlWebpackPlugin.options.cdn 动态注入这些资源,使得 HTML 模板更加灵活,且无需硬编码每个 CDN 资源。
index.html 示例:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack CDN Example</title>
<!-- 动态插入 CSS -->
<% for (var css of htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= css %>">
<% } %>
</head>
<body>
<div id="app"></div>
<!-- 动态插入 JS -->
<% for (var js of htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= js %>"></script>
<% } %>
</body>
</html>
4. 版本控制和 CDN 服务选择
使用 jsdelivr 或 unpkg 这种公共 CDN 服务时,注意加上版本号,以确保兼容性。如果项目中有多个依赖项需要加载,最好选择那些稳定且提供长期支持的 CDN 服务,避免因为 CDN 服务问题导致的资源加载失败。
5. fallback 机制(备用方案)
为了保证 CDN 加载失败时,页面能正常工作,你可以为 CDN 资源提供一个 fallback 机制。当 CDN 资源无法加载时,可以从本地文件或其他备份源加载。
例如,在 HTML 中加一个简单的 fallback:
html
<script>
if (!window.Vue) {
document.write('<script src="/path/to/local/vue.min.js"><\/script>');
}
if (!window.ELEMENT) {
document.write('<script src="/path/to/local/element-ui.js"><\/script>');
}
</script>
3. 懒加载优化
对于一些不常用的库或功能,我们可以通过懒加载来避免它们在首次加载时被下载。例如,Table2Excel 和 exceljs 只是某些功能的依赖,并不会在页面加载时立刻用到。我们采用了 import() 异步加载这些模块。
javascript
download() {
import('table2excel.js').then((Table2Excel) => {
new Table2Excel.default('#table').export('filename');
});
}
通过这种方式,只有在需要时才会加载 Table2Excel 和 exceljs,有效减轻了首次加载的压力。
4. 压缩并优化 Moment.js
Moment.js 是一个常用的时间处理库,但它的体积较大。我们通过忽略掉不必要的语言包,减少了它的体积。
在 vue.config.js 中配置:
javascript
module.exports = {
chainWebpack: config => {
config.plugin('ignore')
.use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)); // 忽略 moment 的其他语言包
}
};
然后在 main.js 中手动引入所需的语言包:
javascript
import moment from 'moment';
import 'moment/locale/zh-cn'; // 只引入中文语言包
moment.locale('zh-cn');
这种做法将 Moment.js 的体积从几百 KB 降低到了 174KB。
5. Gzip 压缩文件
最后,为了进一步减小文件体积并提高加载速度,我们使用了 compression-webpack-plugin 插件对 JS 和 CSS 文件进行 Gzip 压缩。
javascript
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
chainWebpack: config => {
if (isProduction) {
config.plugin('compressionPlugin').use(new CompressionPlugin({
test: /\.(js|css)$/, // 只压缩 JS 和 CSS 文件
threshold: 10240, // 压缩大于 10KB 的文件
minRatio: 0.8, // 压缩比率
deleteOriginalAssets: true // 删除原始文件
}));
}
}
};
经过这些优化,项目的打包文件大小从 3MB 减少到 860KB,加载速度得到了显著提升。
服务器端也得配置 nginx 开启静态压缩
总结
这些看似简单的优化方法,在实际应用中却能带来显著的性能提升。虽然这些优化技术不是什么新鲜事,但要在实际项目中实施却需要一定的时间和精力。