Webpack学习笔记之性能优化

Posted 四月鸟凉

tags:

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

 coding  |   旅行  |  书法 |   健身  |   随笔



当你的才华还撑不你的野心时,那你应该静下心来学习!

——鸟哥哥


最近一周,经历的事情有点多,副主管离职了,甚是忐忑,后盾一个个离我而去,而后的问题只能靠自己搞定了。还记得公主(副主管)在职的时候总是搞笑说,‘有问题啊,重启电脑就好了,不行,再重启,呵呵呵’,很幽默很有活力的一位可爱程序员。从他身上还是能学到很多东西,虽然他是后端我是前端,他解决问题的方式比我多,动手能力也很强,关键是他喜欢思考问题,这样做的后果是什么,考虑得比我周全,很佩服!

这周的工作还是cnc,主要做的两件事:1.项目所需依赖升级,最主要的是webpack1.3升级到最新版webpack3.6.1,当然还有vue-loader升级到13.0等等 2.vue组件懒加载,其他的都是优化代码,小修小补的,记得比较深的知识点就是关于js属性的可枚举属性和不可枚举属性,后面也要写一篇博客记录一下历程。今天这篇博客,主要是记录自己学习webpack过程,有一部分是整合前辈总结过的方法。我觉得这种比较偏业务的代码,最后的形式就是结合实例,很有说服力,且最好上图,图文并茂最好了。

目前亟待解决的知识点疑惑:1.正则表达式 RegExp;2.This/call/apply/bind模糊;3.prototype原型属性,进入正文…

项目刚开始跑的时候,run build之后,app.hash.js达到2M多,oh,WTF,那还玩个毛豆,正常访问肯定会有问题,特别是第一次访问,没有缓存的情况下,超慢的。为此,还出现app.hash.js因为文件太大,加之网站访问速度慢,文件被截取了,导致报错。为了干掉这个bug,只好去看看官方vue-cli和webpack,看看哪些地方能优化的。极力推荐杨少侠的博文,总结得很到位!大神!!


按需加载模块

在vue官网路由懒加载这块,讲得很明白:

当打包构建应用时,javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割(coding splitting)功能,轻松实现路由组件的懒加载。

webpack(2.0以上) 也是内置对这方面的支持; 假如,你使用的是 Vue,将一个组件(以及其所有依赖)改为异步加载,所需要的只是把:

1

import ASIDE from  'components/common/xzAside'

改成

1

const ASIDE = () => import(/* webpackChunkName: "xzAside" */'components/common/xzAside')


同时配合webpack.base.conf.js中的entry,把每个组件加载的名称标注好,chunkFilename: ‘[name].chunk.js’,

1

2

3

4

5

6

7

output: {

path: config.build.assetsRoot,

publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,

filename: '[name].js',

// add chunk name. We can use lazy loading Component by import syntax

chunkFilename: '[name].chunk.js',

},

最后的效果就是代码被分割成一块块的,而且对各个组件的大小一目了然。其中有一点需要注意,vue-loader超过13.0的版本不支持require方式引入js,作为采坑者,郁闷了一上午!!



Webpack3 新功能: Scope Hoisting


本人在项目中实践过,效果感觉不明显,可能还需要其他的配置参数,Webpack在 3.0 版本,提供了一个新的功能:Scope Hoisting,又译作“作用域提升”。只需在配置文件中添加一个新的插件,就可以让 Webpack 打包出来的代码文件更小、运行的更快:

1

2

3

4

5

module.exports = {

plugins: [

new webpack.optimize.ModuleConcatenationPlugin()

]

}


引入 DllPlugin 和 DllReferencePlugin

提供了以大幅度提高构建时间性能的方式拆分软件包的方法。其中原理是,将特定的第三方NPM包模块提前构建,然后通过页面引入。这不仅能够使得 vendor 文件可以大幅度减小,同时,也极大的提高了构件速度。鉴于篇幅,具体用法可参见DLLPlugin配置



合理配置 CommonsChunkPlugin

推荐webpack-bundle-analyzer —— Webpack 插件和 CLI 实用程序,她可以将内容束展示为方便交互的直观树状图,让你明白你所构建包中真正引入的内容。
webpack的资源入口通常是以entry为单元进行编译提取,那么当多entry共存的时候,CommonsChunkPlugin的作用就会发挥出来,对所有依赖的chunk进行公共部分的提取,但是在这里可能很多人会误认为抽取公共部分指的是能抽取某个代码片段,其实并非如此,它是以module为单位进行提取。

假设我们的页面中存在entry1,entry2,entry3三个入口,这些入口中可能都会引用如utils,loadash,fetch等这些通用模块,那么就可以考虑对这部分的共用部分机提取。通常提取方式有如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

//有选择的提取公共代码

new webpack.optimize.CommonsChunkPlugin('common.js',['entry1','entry2']);

只提取entry1节点和entry2中的共用部分模块, 生成一个common.js

//将entry下所有的模块的公共部分(可指定引用次数)提取到一个通用的chunk中

new webpack.optimize.CommonsChunkPlugin({

name: 'vendors',

minChunks: function (module, count) {

return (

module.resource &&

/\.js$/.test(module.resource) &&

module.resource.indexOf(

path.join(__dirname, '../node_modules')

) === 0

)

}

});

提取所有node_modules中的模块至vendors中,也可以指定minChunks中的最小引用数;

//抽取enry中的一些lib抽取到vendors中

entry = {

vendors: ['fetch', 'loadash']

};

new webpack.optimize.CommonsChunkPlugin({

name: "vendors",

minChunks: Infinity

});

添加一个entry名叫为vendors,并把vendors设置为所需要的资源库,CommonsChunk会自动提取指定库至vendors中。


其他野路子

开启productionGzip:true

1

2

3

4

5

6

// Gzip off by default as many popular static hosts such as

// Surge or Netlify already gzip all static assets for you.

// Before setting to `true`, make sure to:

// npm install --save-dev compression-webpack-plugin

productionGzip: false,

productionGzipExtensions: ['js', 'css'],

如果是nginx已经开启了gzip压缩的话,这可也可以开启,只需gzip_static:on,不过这个需要Nginx支持这个配置项:-with-http_gzip_static_module这个模块,实在不行,nginx服务器直接开启gzip压缩,大约能压缩三分之一,哇,不错!

devtool: ‘cheap-module-source-map’

生产环境调试工具用的,官方推荐是’#source-map’,其实你在开发环境如果自信的话可以不用,主要的作用就是报错的代码能看到在哪行那列

uglify丑化你的代码

使用配置也非常简单,只需要将我们原来webpack中自带的uglifyPlugin配置:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

new webpack.optimize.UglifyJsPlugin({

exclude:/\.min\.js$/

mangle:true,

compress: { warnings: false },

output: { comments: false }

})

修改成如下代码即可:

const os = require('os');

const UglifyJsParallelPlugin = require('webpack-uglify-parallel');

new UglifyJsParallelPlugin({

workers: os.cpus().length,

mangle: true,

compressor: {

warnings: false,

drop_console: true,

drop_debugger: true

}

})

谷歌官方自带的cli配置

由于使用官方推荐的vue-cli所以,webpack里的配置已经是帮你配好了,不过,自己也要知道这些插件分别对应什么作用,如何更改参数配置等


四月鸟凉

幸福就像花开,开到荼蘼

coding | 旅行 | 健身 | NBA

以上是关于Webpack学习笔记之性能优化的主要内容,如果未能解决你的问题,请参考以下文章

非常全面的webpack之前端性能优化的实现分享

Webpack 性能优化

网站性能优化实战之—— gzip (webpack, vite 开启gzip 部署)

网站性能优化实战之—— gzip (webpack, vite 开启gzip 部署)

前端性能优化之按需加载(React-router+webpack)

Elasticsearch笔记九之优化