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

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

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

首先配置全局变量

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

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

1. 注意 devtool 中的 source-map。

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

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

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

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

能够试一下,当开启 devtool打包后的文件github

devtool: "inline-source-map"web

打包后3.9MB...

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

其实了解下 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压缩.

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

以上, 致那颗骚动的心……
相关文章
相关标签/搜索