使用过vuejs的开发者一定对vue-cli不陌生,这个命令行工具提供了几个常用的搭建项目的模板,目前官方支持6个模板:
- webpack
- webpack-simple
- browserify
- browserify-simple
- pwa
- simple
而使用得最多也是Github上start数最多的模板则是webpack
这个模板,它包含的内容也非常丰富:语法校验、css预处理、测试框架等,相对于其它模板而言更适合搭建大型项目。
更为良心的是连npm脚本都写好了,开发的时候直接输入npm run dev
,开发完成则输入npm run build
生成对应的可部署文件。
但是当我们真正开始用于大型项目的时候,尤其在引入一些第三方模块之后就会发现一个问题~
这是我的一个项目使用默认配置编译后生成的文件目录截图。
其中有1个vendor.xxxx.js文件显示颜色为黄色,后面给出一个[big]的警告,文件大小达到981kB!
更可怕的是 app.xxx.js 和 vendor.xxx.js 在首次加载的时候浏览器都会请求,js文件下载完成之后才开始渲染页面。直接后果就是首屏加载时间大大增加,用户浏览网页时需要长时间等待,体验相当糟糕。
定位问题
我们来看看这个vendor.xxx.js
是怎么形成的。
全局搜索一下”vendor”即可找到 build 目录下的 webpack.prod.conf.js 文件,看到下面几行:
|
|
这里用到了webpack的一个插件CommonsChunkPlugin
来提取entry对应文件(所有编写的业务代码)中的公共代码,其中 minChunks 的配置项对应的函数为提取代码块规则,规定将node_modules中的所有依赖模块都打包到一个叫vendor的文件中。
解决问题
最终目的是减小文件体积,途径有两个:
- 减少依赖。
- 分割文件。
对于第一种方式通常会随着项目代码量增大而难度增大,而且除非引入了较多的不需要的垃圾模块,否则效果不会很明显。而引入不适用的模块一般在编译时校验规则无法通过就会报错,这种情况几乎不会出现。
所以考虑第二种方式。我们将首屏需要的第三方模块提取出来优先加载,让页面快速渲染,其它模块延迟加载或懒加载。
要做到这一点我们首先需要回归打包工具webpack,通过查看官方文档可以找到code splitting
的描述和我们所需的场景较为匹配——它可以用来分割成更小的模块和控制资源加载的优先级,如果使用正确的话可以极大地提升加载速度。
同时文档上提供了3种实现方式:
- 通过entry配置项手动分割。
- 通过CommonsChunkPlugin插件提取公用代码。
- 动态引入模块。
第一种方式:将首页依赖的模块手动配置成entry并不会奏效,因为CommonsChunkPlugin插件仍然会将部分模块抽取出来,配置形同虚设。
第二种方式:这种方式尝试了很久,一直想把首页的第三方模块单独抽取出来。后来仔细思考因为main.ts文件中始终会引用首页组件,也就是说两个entry配置的文件有包含关系,注定了在抽取公共模块的时候会把这些模块一起抽取出来,所以这种方式行不通。
第三种方式:使用vuejs的异步组件特性,再加上webpack的import函数实现。但是使用ts转成ES5时会出现报错:不支持模块懒加载。需要引用第三方库,比如require.js或者system.js。最后代码如下:
|
|
换一种思路
有没有简单粗暴的方法?有!
在服务端开启gzip,可以有效地减小文件体积。具体操作需要根据不同服务器进行配置。
本文使用了nginx作为Web服务器,并开启了最高压缩级别地gzip,上述vendor.xxx.js压缩后体积:
608kB => 154kB
体积减少了74.67%,效果相当可观。
当然实际生产环境不会把压缩级别调到这么高,避免过多消耗CPU资源。
总结
这些年Web前端的发展越来越变得工程化和专业化,从最初的使用空的种子项目来快速搭建框架,到聚集各类框架模板的脚手架平台yeoman,再到框架使用专有的命令行工具(vue-cli, angular-cli等)。
不少模板、种子项目虽然都做到了“开箱即用”,但是这个“可用性”更多的是相对于开发测试而言,对于生产部署往往需要开发者花费心思去改进、优化,纯粹的“拿来主义”不可取~
一部由众多技术专家推荐, 帮你成为具有全面能力和全局视野工程师的进阶利器—— 《了不起的JavaScript工程师》出版了! 点击下方链接即刻踏上进阶之路!
- 淘宝:https://detail.tmall.com/item.htm?id=600756390664
- 京东:https://item.jd.com/12562349.html?dist=jd
- 当当:http://product.dangdang.com/27922044.html