关于 webpack 打包后文件过大的那些事……

24

react 配合 webpack 打包固然好用,但比较尴尬的是打包过后的 react 文件的体积……

首屏加载过慢,怎么办?慢慢优化呗……
一般正常的网站首屏应该在1s左右加载出来,这个体验性简直极好的。
既然优化那就先从资源文件大小开始。
可能有的人会说既然优化,那就做个按需。这确实是个好主意,但是如果你打包后的文件不是很大的话,其实没必要做按需。

首先配置全局变量

告诉 webpack 我要发布 production 了,按照 production 方式去打包。

   new webpack.DefinePlugin({
        'process.env': {
            //注意一个单引号一个双引号…… 这里是要将 "production" 替换到文件里面
            NODE_ENV: '"production"'
        }
    })

1. 注意 devtool 中的 source-map。

如果你打包后的文件莫名其妙的好几 MB的大小…… 看到这个文件心里真是一万只奔腾的……

如果好几 MB, 那不用想了肯定是 source-map 的问题, 注意 source-map 的那种几种类型使用.

webpack sourcemap 选项多种模式的一些解释
https://webpack.github.io/docs/configuration.html#devtool

source map 在开发调试的时候确实是好用,但也只是开发的时候……
生产环境没多大必要去用这个了,当然也有人选择在生产环境开启 source-map ,方便调试, 但我觉得真心没必要, 在生产环境调试的方法多的是,没必要用这个方式.

可以试一下,当开启 devtool打包后的文件

devtool: "inline-source-map"

打包后3.9MB...

瞬间高潮了,这个js挂在服务器上没有10s出不来的,记得当我第一次在服务器上打包后,满怀期待的打开页面后的场景……

其实了解下 source-map 的不同方式就知道了, inline-source-map 为每一个文件添加 sourcemap 的 DataUrl,注意这里的文件是打包前的每一个文件而不是最后打包出来的,同时这个 DataUrl 是包含一个文件完整 souremap 信息的 Base64 格式化后的字符串,而不是一个 url。

建议在production环境打包的时候关闭 devtool.

如果非得在线上使用 source-map, 可以配置为

devtool: "#source-map",

这样只会在文件后面跟一个 url,这样对源文件影响就很小了

这样还有1.52MB

可以看到使用#source-map后 vendor.js 已经从3.9M 减到 1.52MB。
如果非要在生成环境使用 source-map, 请严谨选择。

2. 使 css 剥离 js 文件, 将 css 单独打包。

依赖插件 npm install --save-dev extract-text-webpack-plugin 先安装再使用

    var ExtractTextPlugin = require('extract-text-webpack-plugin');
    
    //在 plugins 中配置
    plugins: [ new ExtractTextPlugin('[name].[contenthash].css') ]

把 css 单独打包出来,免得以后只修改 css 导致 浏览器端 js 的缓存也失效了。
这里使用了 contenthash, webpack 会按照内容去生成 hash 值。

3. 压缩, 去除注释

注意如果开启了source-map选择inline-source-map压缩后依然好几MB的

    //在 plugins 中添加
    new webpack.optimize.UglifyJsPlugin({
        comments: false,        //去掉注释
        compress: {
            warnings: false    //忽略警告,要不然会有一大堆的黄色字体出现……
        }
    })

最好开启去掉代码注释。
代码压缩后提升简直不是一点两点的……

压缩后只有410kb

哇塞很赞哎. 其实还是不行的,这样首屏加载还会慢点, 怎么办 gzip 咯。

4. 开启 gzip 压缩

依赖插件 npm install --save-dev compression-webpack-plugin

git 地址:compression-webpack-plugin

    var CompressionWebpackPlugin = require('compression-webpack-plugin');

    //在 plugin 中添加
    new CompressionWebpackPlugin({ //gzip 压缩
        asset: '[path].gz[query]',
        algorithm: 'gzip',
        test: new RegExp(
            '\\.(js|css)$'    //压缩 js 与 css
        ),
        threshold: 10240,
        minRatio: 0.8
    })

这个就很满意……

只有115KB了

gzip

这个截图是请求服务器上的 js。之前这个 js 要10多秒的……(云服务器最低配置的那种)
请求截图

从3.9MB 到 115KB!!! 真是极好的。

5. 压缩 html, 自动添加上面生成的静态资源。

依赖插件 npm install --save-dev html-webpack-plugin

git 地址:html-webpack-plugin

    var HtmlWebpackPlugin = require('html-webpack-plugin');
    
    new HtmlWebpackPlugin({
        filename: 'react.html',    //生成的文件,从 output.path 开始 output.path + "/react.html"
        template: '../client/react.html',  //读取的模板文件,这个路径是相对于当前这个配置文件的
        inject: true, // 自动注入
        minify: {
            removeComments: true,        //去注释
            collapseWhitespace: true,    //压缩空格
            removeAttributeQuotes: true  //去除属性引用
            // more options:
            // https://github.com/kangax/html-minifier#options-quick-reference
        },
        //必须通过上面的 CommonsChunkPlugin 的依赖关系自动添加 js,css 等
        chunksSortMode: 'dependency'
    })

这样就大功告成了, css,js 开启 gzip 压缩后, 会将生成的文件名自动注入到 html 中。 如果有多个 html 配置再添加一个 new HtmlWebpackPlugin() 即可。

小结

  1. 确定不会在生产环境打包多余的代码, 比如 热加载 只是举个例子

  2. 检查只在 dev 使用的配置,在生产环境将其去掉. 可使用配置文件,灵活配置,灵活切换

  3. 去除所有注释, 压缩所有可压缩的资源文件.

  4. 开启 gzip压缩.

总而言之为了让文件变小,为了让浏览器加载的更快,我们真的要无所不用其极……

以上, 致那颗骚动的心……

如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

21 条评论
lujs · 2017年02月16日

页面模版引入的还是.js后缀而不是js.gz后缀。请问这个要在哪里配置呢

回复

0

引入 .js 后缀就是对的。 服务器会把 gzip 的文件返回

悠扬小Q 作者 · 2017年02月16日
0

第四步你配置好了?配置好以后好像还要写个方法让访问js文件的请求访问.js.zg文件

水滴石穿 · 2017年02月16日
0
水滴石穿 · 2017年02月16日
elevensky · 2017年03月15日

这个webpack中开启gzip的意义是什么,这事不是nginx的么?

回复

0

都可以,ng也可以去做gzip。

悠扬小Q 作者 · 2017年03月15日
supercoder · 2017年03月15日

开启gzip以后,服务端要是再去做gzip压缩,体积还会再减少吗?

回复

黑色技术 · 2017年05月26日

我用vux的,打包后出现奇怪的东西,之前没模块打包才1M多,分模块打包后4M多,其中1-2个文件1M多,那个模块文件也没引用到什么东西,很简单的几个页面...完全不知道是怎么打包的...奇怪的数据都打进去了.

回复

0

像这种文件大小倍增的情况一般都是source-map的问题, 你用的类型不对吗

悠扬小Q 作者 · 2017年05月26日
0

这问题有点尴尬,这个map已经关闭了,好像我的打包有点问题.主要是那个页面没有什么js效果,却把http://hammerjs.github.io/ `http://photoswipe.com,还有{name:"芜湖县",value:"340221",parent:"340200"}`这种东西...一脸懵逼,不知道是不是把vux的东西全打包进去了,我都是模块引入的.

黑色技术 · 2017年05月26日
0

@黑色技术 按模块引入也是把整个第三方库打包进去的。

hugojing · 2018年08月24日
liufeisprit · 2018年01月22日

webpack打包出了 gzip的东西后 怎么用啊 后台怎么改

回复

JackieZhang · 2月14日

gzip打包把 原本从3.9MB 到 115KB 这么厉害啊!

回复

载入中...