Webpack体积篇优化记录

Posted 撩前端

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Webpack体积篇优化记录相关的知识,希望对你有一定的参考价值。

从产品层来讲,如何使得构建的包体积小、运行快,这有必要不断摸索实践,提炼升级,使之臻于最佳。本文将从以下些许方面,对 Webpack 打包体积方面,做下优化探讨(备注 Webpack 实践版本: 3.10.0):


不BB,拿结果说话。

old


new

Webpack体积篇优化记录

直接减少接近4秒



项目生产编译文件大小

Webpack体积篇优化记录



使用 Webpack3 新功能:Scope Hoisting

Webpack 在 3.0 版本,提供了一个新的功能:Scope Hoisting,又译作“作用域提升”。只需要在配置文件中添加一个新的插件,就可以让 Webpack 打包出来的文件更小、运行的更快:

module.exports = {

  plugins: [

    new webpack.optimize.ModuleConcatenationPlugin()

  ]

}

Webpack体积篇优化记录

其实体积变化是微乎其微的。



查看项目打包

接下来,我们详细看看大文件处理。

这是个人文件配置:webpack.config.js

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

plugins: [

    new BundleAnalyzerPlugin(),

],


官方说明:

var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

new BundleAnalyzerPlugin({

//  可以是`server`,`static`或`disabled`。

//  在`server`模式下,分析器将启动HTTP服务器来显示软件包报告。

//  在“静态”模式下,会生成带有报告的单个html文件。

//  在`disabled`模式下,你可以使用这个插件来将`generateStatsFile`设置为`true`来生成Webpack Stats JSON文件。

    analyzerMode: 'server',

//  将在“服务器”模式下使用的主机启动HTTP服务器。

    analyzerHost: '127.0.0.1',

//  将在“服务器”模式下使用的端口启动HTTP服务器。

    analyzerPort: 8888,

//  路径捆绑,将在`static`模式下生成的报告文件。

//  相对于捆绑输出目录。

    reportFilename: 'report.html',

//  模块大小默认显示在报告中。

//  应该是`stat`,`parsed`或者`gzip`中的一个。

//  有关更多信息,请参见“定义”一节。

    defaultSizes: 'parsed',

//  在默认浏览器中自动打开报告

    openAnalyzer: true,

//  如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成

    generateStatsFile: false,

//  如果`generateStatsFile`为`true`,将会生成Webpack Stats JSON文件的名字。

//  相对于捆绑输出目录。

    statsFilename: 'stats.json',

//  stats.toJson()方法的选项。

//  例如,您可以使用`source:false`选项排除统计文件中模块的来源。

//  在这里查看更多选项:https://github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21

    statsOptions: null,

    logLevel: 'info' //日志级别。可以是'信息','警告','错误'或'沉默'。

})


这是用webpack-bundle-analyzer插件展示的效果。

Webpack体积篇优化记录

这里说一下,左侧还有缩略图。(点击左边区域)

列出了项目中较大的包,剩下的事情就是想办法如何减小这些包的体积(将一个大包拆成多个小包)。

  • 项目中产生较大的包的原因可以从两个方面去考虑:

    1.项目中引入的依赖包过于庞大;

    2.业务代码集中在一块写,或者是业务代码写的比较繁琐;


  • 对于这两个问题,我们可以从两个方面着手解决:

    1.抽离项目中公共依赖的、不常变动的、体积较大的包;

    2.将一个较大的业务代码文件,拆成多个较小的文件,异步加载(或者优化业务代码)。


这里面第二项涉及到改动业务代码,具体的情况就不同了,适合查看 如何优化JS代码。

我们来讨论第一种方法,在不改动业务代码的情况下,如何减小公共依赖。

要知道这些依赖是我们需要的,不可能排除不引入。

但是他们都是全局依赖的,万年不变的,可以使用浏览器自己的缓存来实现不重复加载。


  • 具体做法就是:

    将项目中需要的一些公共依赖包,并且不常变动的,单独取出,不再每次都打包编译(如React,Redux等)。

    而是通过使用script标签形式cdn引入,这样在有缓存的情况下,这些资源均走缓存,不必加载。



CDN方式

从上图可以看出包文件很大,重点处理一下几个文件 lodashreact-dommomentantd

尝试结果是只成功了 lodashreact-dom

Webpack体积篇优化记录


具体配置:

webpack.config.js

Webpack体积篇优化记录

index.html

Webpack体积篇优化记录

另外一些包文件如 Antd库文件,整个包较大,但是每次用什么取什么的话,库文件也会按需加载,不必单独取出。

还有这类库文件不建议单独取出,因为里面可能会有bug,需要更新。



DLL 方式

dll 全称是:dynamic link library(动态链接库)

dll方式也就是通过配置,告诉webpack指定库在项目中的位置,从而直接引入,不将其打包在内。

上面介绍的方式是将包放到cdn上,build的时候不在引入对应的包;

dll方式就是指定包在项目中,build的时候不在打包对应的包,使用的时候引入。

webpack通过webpack.DllPluginwebpack.DllReferencePlugin两个内嵌插件实现此功能。

接下来尝试用 DLL 方式看能否解决这两项。

这里直接减少3MB

Webpack体积篇优化记录

生产环境编译对比:

Webpack体积篇优化记录

Webpack体积篇优化记录

具体配置:

新建webpack.dll.config.js

Webpack体积篇优化记录

webpack.DllPlugin选项:

  • path:manifest.json文件的输出路径,这个文件会用于后续的业务代码打包;

  • name:dll暴露的对象名,要跟output.library保持一致;

  • context:解析包路径的上下文,这个要跟接下来配置的 webpack.config.js 一致。

在package.json,添加命令。

Webpack体积篇优化记录

运行:webpack --config webpack.dll.config.js

生成两个文件,一个是打包好的bundlejs,另外一个是bundle.mainifest.json。

bundle.mainifest.json文件大致内容如下:


配置webpack.config.js


webpack.DllReferencePlugin的选项中:

  • context:需要跟之前保持一致,这个用来指导webpack匹配manifest.json中库的路径;

  • manifest:用来引入刚才输出的manifest.json文件。

参考链接:

    1、webpack 打包优化解决方案

    2、webpack 打包优化之体积篇

    3、webpack 之前端新能优化

End

谢谢观看,欢迎交流


以上是关于Webpack体积篇优化记录的主要内容,如果未能解决你的问题,请参考以下文章

webpack优化篇(四十一):体积分析:使用 webpack-bundle-analyzer

Webpack 打包优化之体积篇

Webpack 打包优化之体积篇

[转] Webpack 打包优化之体积篇

webpack优化篇(五十):使用动态 Polyfill 服务

Webpack 打包优化之速度篇