近期利用 reactjs 搭建了一个单页面应用,使用 webpack 前端开发工具, 打包出来的 bundle.js 文件超大,有 4M 之巨,前端加载那个慢啊,必须得优化
网上有很多优化的建议,这里按照自己的实践来说下,优化主要有三步
一,webpack 配置优化
webpack 官网有给出开发环境 development 和生产环境 production 的打包配置优化文件,其中 production 的配置优化主要通过两个插件
plugins: [ // 设置生产环境全局变量,以便告诉所有类库,多虑不必要的代码 new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify('production') } }), // 压缩代码,去掉评论注释等 new webpack.optimize.UglifyJsPlugin({ output: { comments: false, }, compress: { warnings: false } }) ]
webpack 重新 build 下,bundle.js 文件立马减少到 1M , 效果显著啊,但前端加载文件还是很慢,继续折腾
二,代码使用类库优化
bundle.js 文件 1M 那么大,究竟是哪些包大了,得通过工具类分析下
webpack 打包会生成一个 json 文件记录 bundle.js 中各个包的信息,通过分析这个文件就可以知道 bundle.js 究竟哪个类库比较大啦
有个不错的工具来分析webpack-bundle-size-analyzer , 在 webpack 配置文件通过插件形式使用
const WebpackBundleSizeAnalyzerPlugin = require('webpack-bundle-size-analyzer').WebpackBundleSizeAnalyzerPlugin ... plugins: [ new WebpackBundleSizeAnalyzerPlugin('./plain-report.txt') ]
webpack 打包后在 dist 的目录下会生成 plain-report.txt,惊喜都在那里啦
.15.4.2@react-dom: 508.77 KB (27.3%) .0.17.4@material-ui: 468.43 KB (25.2%) .2.18.1@moment: 400.92 KB (24.76%) .2.18.1@moment-timezone: 368.92 KB (20.76%) .................
什么情况,前四个包就已经占了 bundle.js 90% 多了
react-dom 是 reactjs 必须得用的,不能去掉;material-ui 前端 UI ,也不能去掉;
moment 和 moment-timezone 是什么鬼,那么大,不就是一个 js 时间日期处理插件吗?
网上一查,果然很多人吐槽 momentjs 在 webpack 打包时太大了,听说原因是加载了不必要的类,以及时区文件
就连 momentjs 贡献者也看不下去了,直接找 webpack 的贡献者帮忙一起想办法解决
刚开始我就想着优化下时区文件,不再加载
plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) ]
但是只是去掉 moment-timezone , 但是 moment 本身就很大
项目中 moment 只是把时间转换成 timeago, 类似 1 second ago , 1 day ago ,于是直接换成更轻量的 timeagojs
重新打包看看 plain-report.txt 中 timeagojs 在 bundle.js 占比大小
.3.0.1@timeago.js: 2.13 KB (0.122%)
我去,这么小啊,果断去掉 momentjs,使用 timeagojs
三,nginx 压缩优化
以上两个优化都在代码层面,其实静态文件还可以通过压缩传输和CDN方式来优化,CDN不再本文章中范围,这里说下压缩传输
压缩传输是 web 服务器和 browser 浏览器之间的优化协议,在服务器压缩后,传输到浏览器再解压的过程
目前大部分浏览器支持这个压缩优化协议,Nginx 作为流行的 web 服务器,提供 gzip 压缩
在 Nginx 静态文件的 server 下添加以下配置即可
gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_comp_level 2; gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; gzip_vary off; gzip_disable "MSIE [1-6]\.";
经过 gzip 压缩,bundle.js 又减少了
四,最后给出优化的流程图
4M ->( webpack 配置优化 )-> 1M -> (代码使用类库优化) -> 570KB -> (nginx 压缩) -> 176KB
Leave a Reply