在高速发展的前端领域中,各式各样有趣的、能够帮助开发者更加迅速地开发出非常精良的前端页面的组件层出不穷。因此,前端资源文件也越来越大。如何缩小前端资源文件,是提升用户浏览器加载资源文件性能至关重要的方法。
本文使用的样例是一个基于Vue的前端项目,webpack版本为3.6.0。其中生产环境下的还需保留的依赖如下所示:
package.json文件
"dependencies": {
"axios": "^0.18.0",
"element-ui": "^2.4.8",
"vue": "^2.5.2",
"vue-router": "^3.0.1"
}
vue
是Vue项目的基础依赖vue-router
是Vue项目用于SPA(单页应用)的路由的组件element-ui
是饿了么公司开发出的一套采用 Vue 2.0 作为基础框架实现的组件库,它面向企业级的后台应用,能够帮助快速地搭建网站(项目网站)axios
是用于Vue项目想后端发送http请求的网络组件echarts
是百度公司开发出的一个使用 JavaScript 实现的开源可视化库,这个依赖是我直接在网站上下载的源代码进行导入,因为cnpm install echarts --save
下载的不能显示开发时的警告和错误提示(项目网站)
分析第一次编译后的资源文件
使用命令npm run build --report
编译前端项目,--report
参数可以给出一个对项目编译结果的分析报告,根据依赖划分不同的文件块,支出每个依赖对应的文件大小。
在没做任何优化的时候进行第一次代码编译,得到的分析报告图如下所示:
从上图可以看出,生成的资源文件中,最大的是app.762d20a99df11e4aafc0.js
和vendor.8dbb6959d78b700a1775.js
这两个js文件。
文件中包括了上面所提及的生产环境中保留的依赖代码。从文件块大小关系可以看出,echarts.js、element-ui组件库和Vue组件相关代码占了比较大的磁盘空间。因此提出以下方法来减小资源文件以提升前端加载的性能优化。
使用CDN引入相关库的方式
由于之前是使用webpack打包的方式,因此上面所提及的依赖都会编译到一个文件中,即vendor.8dbb6959d78b700a1775.js
(echarts是我直接下载下来源代码引入,因此另当别论)。因此浏览器下载这个文件时,会占据一个线程比较长的时间来下载,延长了加载时间。因此,使用CDN引入相关库,能够将依赖分散成各个不同的文件,相当于把一个大的文件拆分成多个小的文件并行下载,理论上能够提高加载速度。同时,热门的代码文件依托在CDN上提供下载本来就比和其他前端资源文件一起直接下载要快很多。下面介绍使用CDN引入的方法。
- 删除原有的依赖
在package.json
文件中,删除vue
、vue-router
和axios
三个依赖(为什么不删除element-ui
后面会讲到),并删除下载的echarts.js
文件 - 在
index.html
中添加cdn引入js代码的语句
这里,开发者可以引入文件名中包含min的js代码,表示我引入的是用于生产环境中的代码包,这些代码包由于没有或较少错误检测等开发环境的代码,因此整体文件大小会更小,加载速度更快
<script src="https://cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
<script src="https://cdn.bootcss.com/echarts/4.2.0-rc.1/echarts.min.js"></script>
- 在
webpack.base.conf.js
中添加模块信息
webpack文档:
为了防止将某些import 的包(package)打包到bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'axios': 'axios',
'echarts': 'echarts'
}
...
}
注意,这里添加的(key,value)值表示的是(代码包名称,导入名称),都是代码中预先定义好的,因此添加这个配置的时候需要阅读代码包的官方要求,否则有可能找不到对应的代码包。与此同时,开发者需要注意在router
目录下的index.js
文件中,一般vue-cli默认生成的是import Router from 'vue-router'
,而webpack.base.conf.js
中写的是VueRouter
,记得修改即可。
4. 再次编译,查看结果
从上图可以看出之前的大文件已经不复存在了,只剩下没有利用CDN导入的element-ui
相关代码文件,其他的依赖代码包文件将在运行时从CDN下载导入。此时的项目文件详情如下图所示:
较之前的文件大小已经减少了三倍。
Element-UI按需引入
原本element-ui
也是可以使用上一种方法引入,但后来发现官方推荐的按需引入的方式更加合理,而且需要传输的代码最少,因此element-ui
部分的优化单独介绍。
element-ui:
借助babel-plugin-component,开发者可以只引入需要的组件,以达到减小项目体积的目的。
- 首先,安装babel-plugin-component
npm install babel-plugin-component -D
- 修改根目录下的.babelrc
{
...
"plugins": ["transform-vue-jsx", "transform-runtime", [
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
- 在main.js中应用需要的组件。
在样例项目中我需要的组件有Container
、Header
、Main
和MessageBox
。完整组件列表和引入方式(完整组件列表以components.json为准)。在main.js
中修改代码为如下所示,注释部分为原来的代码。:
// import ElementUI from 'element-ui'
import { Container, Header, Main, MessageBox } from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
// Vue.use(ElementUI);
Vue.use(Container)
Vue.use(Header)
Vue.use(Main)
Vue.prototype.$prompt = MessageBox.prompt;
- 再次编译,查看结果
可以看出,现在已经没有大块的element-ui
的代码了,说明按需加载得到了正确地效果。此时的项目文件详情如下图所示:
是上一节的文件大小的约10%。
至此,关于减小资源文件大小的优化方式已介绍结束,从最开始的4.47MB到现在的135.45KB,已经有了飞跃的进步。
利用Gzip压缩资源文件
Gzip是一种比较流行的用来改进WEB应用程序性能的技术,大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。本文的样例项目是以Nginx作为Web服务器,因此可以通过修改Nginx的配置文件,来开启Gzip压缩的功能。
环境:CentOS 6.8
Nginx配置文件:/etc/nginx/nginx.conf (注意,这里修改的是Nginx的总的配置文件)
# 开启gzip
gzip on;
# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,一般来说1或者2足矣,再往后的效果就没那么明显了
gzip_comp_level 2;
# 进行压缩的文件类型。javascript有多种形式。
# 其中的值可以在 mime.types 文件中找到。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 禁用IE 6 gzip
gzip_disable "MSIE [1-6]\.";
然后执行命令重启nginx服务,即可开启
sudo service nginx restart
在webpack的代码编译后分析页面可以预测到Gzip压缩后的资源文件大小:
相比上一章最后减小到的135.45KB的文件大小,Gzip压缩过后的14,78又是倍数级的下降。
然而,优化前端加载性能的方式远远不止本文所提及的几点,还有CDN静态资源加载、路由懒加载等技术也可以帮助加快前端资源文件的加载,不过笔者使用上述技术,将前端页面加载时间从136秒降低到2.87秒,已经心满意足了……