webpack性能优化主要有两方面:构建速度优化,产出速度优化

对生产环境产出代码合理分包,不重复加载,使其体积更小,速度更快,内存使用更少。浏览器加载页面时用的时间越短越好所以构建出的文件越小越好,减少浏览器需要发起请求的数量,减少下载静态资源的时间。webpack在生产环境构建时会做一些额外工作如代码压缩等,可优化前端资源加载性能。

构建速度优化-开发体验和效率

优化babel-loader
开启babel-loader缓存。babel-loader后加?cacheDirectory如果es6代码没有改,不会重新编译
控制babel编译范围。用include确定包含的范围,或者exclude确定不包括的范围。(排除node_modules)
项目中配置babel-loader
webpack.config.common.js文件 webpack生产环境中配置

module: {rules: [{test: /.\ts$/,exclude: /node_modules/,use: ['babel-loader',{loader: 'ts-loader',options: {// 此处为了ts-loader第一次命中就把所有options被缓存到appendTsSuffixTo: [/\.vue$/],},},],},{test: /.\js$/,exclude: /node_modules/,loader: 'babel-loader',options: {cacheDirectory:true,},},]
}

IgnorePlugin避免引入无用模块
如引入moment,js,只需要中文和英文的模块
业务代码中手动引入中文和英文的语言包,webpack配置中

new webpack.IgnorePlugin(/\.\/locale/, /moment/),

忽略掉moment里的locale语言包,可以减少无用模块引入

noParse避免重复打包
如社区中min.js这种一般是已经打包过的,无需再次打包。可在module.noParse中配置不需打包的文件。注意,react.min.js不能使用,没有采用模块化,需要打包

noParse和Ignore区别:Ignore直接用不引入,代码中没有。noParse会引入,但不打包。两个都能提高构建速度,Ignore还可以优化线上性能。

happyPack多进程打包 是plugin
js是单线程,webpack实际也是单线程打包。

比如要将babel的解析放在新进程中,那么module.rule中对js的解析需要改成:

        {test: /\.js$/,// 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例use: ['happypack/loader?id=babel'],include: srcPath,// exclude: /node_modules/},

然后需要在plugin中配置babel的happyPack实例:

    new HappyPack({// 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件id: 'babel',// 如何处理 .js 文件,用法和 Loader 配置中一样loaders: ['babel-loader?cacheDirectory']}),

ParallelUglifyPlugin多进程压缩JS
webpack本身内置了uglify压缩JS,压缩JS本身成本较高,可以多进程开启,直接plugin实例化。

根据需要开启多进程,不一定需要。如果项目较大,打包较慢,开启多进程可提高速度。但开启多进程本身就需要成本时间,小项目没必要,打包时间反而会增加

热更新HotModuleReplacementPlugin
自动刷新和热更新区别:
自动刷新速度较慢,状态会丢失
热更新不会刷新,状态不丢失,新代码可立刻生效

webpack.config.dev.js文件 webpack本地环境中配置
plugin中实例化,devSever中设置hot为true

devServer: {host: '0.0.0.0',port,openPage: `http://${ip}:${port}/${publicPath}`,hot: true,inline: true,liveReload: true,historyApiFallback: {rewrites: [{from: /.*/g,to: `/${publicPath}`,},],},
},
plugins: [// Only update what has changed on hot reloadnew webpack.HotModuleReplacementPlugin(),new UrlLogPlugin(),
],

DLLPlugin动态链接库插件
webpack内置了DLLPlugin,主要包含两个插件:
DllPlugin:打包出dll文件,先进行一遍预打包,生成dll文件
DLLReferencePlugin:在开发环境使用dll文件

一般需单独定义一个dll.config.js

output: {path: path.join(__dirname, '../build'), // 放在项目的/build目录下面filename: '[name].dll.js', // 打包文件的名字library: '[name]_library' // 可选 暴露出的全局变量名// vendor.dll.js中暴露出的全局变量名。// 主要是给DllPlugin中的name使用,// 故这里需要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
},pluginnew webpack.DllPlugin({path: path.join(__dirname, '../build', '[name]_manifest.json'), // 生成上文说到清单文件,放在当前build文件下面,这个看你自己想放哪里了。name: '[name]_library',context: __dirname,}),

定义dll命令,进行dll打包
最后输出dll和manifest文件。dll文件就是所有打包的文件内容。manifest作用为索引,负责引导实际对于dll里模块的引用

实际应用中,需要在dev的html中进行script引用,可用DLLReferencePlugin插件引用manifest文件,AddAssetHTMLPlugin引用dll文件即可

产出速度优化

webpack优化产出代码-产品性能提高

核心:代码体积更小,合理分包,不重复加载,速度更快,内存使用更少

小图片用base64编码
url-loader 设置limit值控制图片大小,(小于该文件大小的图片转为base64格式)将处理后的图片引入项目,减少http请求

{test: /\.(png|svg|jpg|gif)$/,use: {loader: 'url-loader',options: {limit: 3*1024 // 3k}}
}

bundle需要加hash
根据文件内容算hash值,客户端可实现缓存管理使用。js代码如果没有变化,再次上线也可以复用没变的bundle块

bundle:webpack打包后的各个文件,一般和chunk(代码块)一对一关系,bundle就是对chunk进行编译压缩打包等处理后的产出。

懒加载
webpack支持异步加载模块的特性。

按需加载:如一个应用有3个页面,首页加载时只加载首页的逻辑,其他两个页面跳转到页面后在异步加载。

原理:动态向页面找那个插入script标签。

webpack支持实现方式有两种:
commonjs形式的require
es6的异步import()

// 普通加载
import xxx from './xxx'
懒加载(按需加载)
const xxx = () => import('./xxx')

提取公共代码
抽离一些通用代码和第三方的。

webpack 3.x前版本用CommonsChunkPlugin做代码分离,4.x把相关功能包在optimization里的splitChunks

参数:
chunks选项,决定要提取那些模块。
默认是async:只提取异步加载的模块出来打包到一个文件中。
异步加载的模块:通过import(‘xxx’)或require([‘xxx’],() =>{})加载的模块。

initial:提取同步加载和异步加载模块,如果xxx在项目中异步加载了,也同步加载了,那么xxx这个模块会被提取两次,分别打包到不同的文件中。
同步加载的模块:通过 import xxx或require(‘xxx’)加载的模块。

all:不管异步加载还是同步加载的模块都提取出来,打包到一个文件中。

minSize选项:规定被提取的模块在压缩前的大小最小值,单位为字节,默认为30000,只有超过了30000字节才会被提取。
maxSize选项:把提取出来的模块打包生成的文件大小不能超过maxSize值,如果超过了,要对其进行分割并打包生成新的文件。单位为字节,默认为0,表示不限制大小。
minChunks选项:表示要被提取的模块最小被引用次数,引用次数超过或等于minChunks值,才能被提取。
maxAsyncRequests选项:最大的按需(异步)加载次数,默认为 6。
maxInitialRequests选项:打包后的入口文件加载时,还能同时加载js文件的数量(包括入口文件),默认为4。
先说一下优先级 maxInitialRequests / maxAsyncRequests <maxSize<minSize。
automaticNameDelimiter选项:打包生成的js文件名的分割符,默认为~。
name选项:打包生成js文件的名称。
cacheGroups选项,核心重点,配置提取模块的方案。里面每一项代表一个提取模块的方案。下面是cacheGroups每项中特有的选项,其余选项和外面一致,若cacheGroups每项中有,就按配置的,没有就使用外面配置的。
test选项:用来匹配要提取的模块的资源路径或名称。值是正则或函数。
priority选项:方案的优先级,值越大表示提取模块时优先采用此方案。默认值为0。
reuseExistingChunk选项:true/false。为true时,如果当前要提取的模块,在已经在打包生成的js文件中存在,则将重用该模块,而不是把当前要提取的模块打包生成新的js文件。
enforce选项:true/false。为true时,忽略minSize,minChunks,maxAsyncRequests和maxInitialRequests外面选项

项目中配置

optimization: {splitChunks: {chunks: 'async',  // 决定提取哪些模块minSize: 0, // 超过该值才会被提取,单位字节,默认30000maxSize: 30000, // 打包生成的文件最大值,如果超过则分隔打包生成新文件。单位字节,默认0表不限制大小minChunks: 1, // 被提取的模块最小被引用次数,引用次数超过或等于该值才能被提取maxAsyncRequests: 6, // 最大按需加载次数,默认6maxInitialRequests: 4, // 打包后入口文件加载时同时加载的js文件数量(包括入口文件)默认4automaticNameDelimiter: '~', // 打包生成的js文件名的分隔符,默认~cacheGroups: {  // 核心重点!配置提取模块的方案,每一项代表一个提取模块的方案vendors: {name: `chunk-vendors`, // 打包生成文件名test: /[\\/]node_modules[\\/]/,  // 匹配提取的模块资源路径或名称,值为正则或函数priority: -10,  // 优先级,值越大优先级越高。默认值0chunks: 'initial',},common: {name: `chunk-common`,minChunks: 2,priority: -20,chunks: 'initial',reuseExistingChunk: true, // true时,如果要提取的模块,打包文件已存在,则重用该模块,不重新打包enforce: false, // true时,忽略minSize,minChunks,maxAsyncRequests,maxInitialRequests外面选项},},},},

IngorePlugin减少打包内容

cdn加速 内容分发网络
原理:优化物理链路层传输过程中的网速有限,丢包等问题提升网速。通过在各地部署服务器,形成cdn集群,提高访问速度,把资源部署到各地,用户访问是就近原则向离用户最近的服务器获取资源。

tree-shaking移除没用的js代码
打包过程中移除js上下文没引用的代码。依赖于es6的import和export语句,用来检测代码模块是否被导入,导出,被 js文件引用。

es6 Module的模块依赖解析在代码静态分析过程中进行,可在编译阶段就获取到整个依赖树(不是运行时)这一点webpack提供tree-shaking功能进行代码静态分析层面的优化。
webpack.config.js里Module为production自动开启tree-shaking。但只有用es6 Module才可生效,不能用commonjs。
原因:commonjs动态引入,执行时引入。es6 Module静态引入,编译时引入。

用Scope Hosting
该插件只适用于webpack直接处理es6模块。
针对NPM中第三方模块优先采用jsnext:main中指向es6模块化语法的文件

大型工程中模块引用层级一般较深,产生较长引用链,Scope Hosting可将纵深的引用链拍平,使得模块本身和其引用的其他模块作用域处同级,可去掉一部分webpack附加代码减小资源体积。

作用:代码体积更小,创建函数作用域更少,代码可读性更好。

使用方式:
引入webpack内部插件 ModuleConcatenationPlugin插件(默认在生产模式下已启用,若要在其他模式下启用concatenation,可手动添ModuleConcatenationPlugin或用optimization.concatenateModules选项)

module.exports = {resolve: {mainFields: ['jsnext:main', 'browser', 'main'] // 针对npm中的第三方模块优先采用jsnext:main中指向的ES6模块化语法的文件},plugins: [new webpack.optimize.ModuleConcatenationPlugin() // 开启Scope Hoisting]
}

webpack性能优化相关推荐

  1. webpack性能优化全方案

    提升webpack性能优化无非从两个方面入手: 1.如何构建速度 2.如何优化打包后的文件 如何文件构建速度 webpack构建的过程,其实是把,从入口开始,通过AST语法树分析,把所有依赖的模块,结 ...

  2. 前端面试超全整理3(webpack性能优化及监控)

    21.Webpack 性能优化 核心概念 Entry :入口 output:出口 Plugins: 插件,执行范围更广的任务.插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量 Loader ...

  3. 【Webpack 性能优化系列(1) - HMR 热模块替换】

    webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(8) - PWA]使用渐进式网络应用程序为我们的项目添 ...

  4. 【Webpack 性能优化系列(6) - code splitting 】通过代码分割来获取更小的 bundle,优化资源加载

    webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(8) - PWA]使用渐进式网络应用程序为我们的项目添 ...

  5. Webpack性能优化---构建速度

    Webpack性能优化---构建速度 一.优化babel-loader 二.Noparse 三.IgnorePlugin 四.happyPack多进程打包 五.ParallelUglifyPlugin ...

  6. 【Webpack 性能优化系列(8) - PWA】使用渐进式网络应用程序为我们的项目添加离线体验

    webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(7) - 懒加载和预加载] [Webpack 性能优化 ...

  7. (六)构建优化(揭开webpack性能优化的内幕)

    构建优化 webpack的优化配置[了解这些优化配置才敢说会用webpack] Tree-shaking JS压缩 作用域提升 Babel的优化配置 webpack的依赖优化 noParse(不解析) ...

  8. Vue进阶(贰零柒):Webpack 性能优化措施汇总

    文章目录 一.前言 二.优化方案 2.1 优化 Loader 2.2 DllPlugin 2.3 代码压缩 2.4 一些小的优化点 2.5 减少 Webpack 打包后的文件体积 2.5.1 按需加载 ...

  9. webpack性能优化-optimization.splitChunks.chunks中的“all“、“async“和“initial“

    最初,chunks(以及内部导入的模块)是通过内部 webpack 图谱中的父子关系关联的.CommonsChunkPlugin 曾被用来避免他们之间的重复依赖,但是不可能再做进一步的优化. --摘自 ...

  10. 前端性能优化的七种方法

    前端性能优化主要有七种方法,包括减少请求数量.减少资源大小.优化网络连接.优化资源加载.减少重绘回流.使用性能更好的API和webpack优化 1.减少请求数量 1.1 图片处理 1.1.1 雪碧图 ...

最新文章

  1. java数据结构读书笔记--引论
  2. comsol计算数据导出matlab,comsol4.2怎样在matlab中通过函数输出数据
  3. 慢慢聊Linux AIO
  4. MVC之AJAX异步提交表单
  5. No slave process to process jobs, aborting 报错!!!
  6. Golang 交叉编译
  7. Wpf 数据绑定简介、实例1
  8. netfilter数据流图 | 转
  9. Bailian2790 迷宫【DFS】
  10. document.ready 与 onload 的区别
  11. python中的pylab_Python数值计算:一 使用Pylab绘图(1)
  12. WinHTTP Web Proxy Auto-Discovery Service
  13. 【git】git强制覆盖单个文件
  14. alanwang[GDOU] 直接插入排序法简单演示
  15. CSS gird布局
  16. 移动端APP测试总结--转
  17. Read research papers and career advice | 怎么读论文/职场建议
  18. 居然有人能把5G解释的这么清楚
  19. PID原理及python简单实现与调参
  20. Windows和Ubuntu双系统完全独立(双硬盘)的安装方法

热门文章

  1. matlab中grid相关知识
  2. 路由策略—直连路由引入实验
  3. Java HotSpot VM参数大全
  4. 小米路由器4A千兆版c341编程器刷breed.bin详细教程
  5. word中的表格复制到html代码,怎样将Word中的表格复制到Excel中还保持原有内容和格式?...
  6. 推荐 | 南方医院历时4年构建新HIS系统
  7. HttpClient RestTemplate
  8. 认知电子战 (1.3):认知电子战概述
  9. 如何使用shell限制指定用户shell程序的网络带宽
  10. 如何使用Win10原生的截图工具Snipping Tool?