博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
webpack4.0打包优化策略
阅读量:4086 次
发布时间:2019-05-25

本文共 4580 字,大约阅读时间需要 15 分钟。

打包优化策略

提取公共代码与第三方代码

将多个入口重复加载的公共资源提取出来

  • 相同的资源被重复的加载,浪费用户的流量和服务器的成本;
  • 每个页面需要加载的资源太大,导致网页首屏加载缓慢,影响用户体验。 如果能把公共代码抽离成单独文件进行加载能进行优化,可以减少网络传输流量,降低服务器成本
  • 在webpack4.0 optimization.splitChunks替代了CommonsChunkPlugin

webpack.base.config.js提取配置

optimization: {    // runtimeChunk: {    //     name: "manifest"    // },    splitChunks: {        cacheGroups: {            commons: {                chunks: 'initial',                minChunks: 2,                maxInitialRequests: 5,                minSize: 0            },            vendor: { // 将第三方模块提取出来                test: /node_modules/,                chunks: 'initial',                name: 'vendor',                priority: 10, // 优先                enforce: true            }        }    }}复制代码

optimization参数介绍:

  • webpack根据下述条件自动进行代码块分割:
  • 新代码块可以被共享引用,OR这些模块都是来自node_modules文件夹里面
  • 新代码块大于30kb(min+gziped之前的体积)
  • 按需加载的代码块,最大数量应该小于或者等于5
  • 初始加载的代码块,最大数量应该小于或等于3
optimization: {    splitChunks: {       chunks: "initial",         // 代码块类型 必须三选一: "initial"(初始化) | "all"(默认就是all) | "async"(动态加载)       minSize: 0,                // 最小尺寸,默认0      minChunks: 1,              // 最小 chunk ,默认1      maxAsyncRequests: 1,       // 最大异步请求数, 默认1      maxInitialRequests: 1,     // 最大初始化请求书,默认1      name: () => {},            // 名称,此选项课接收 function      cacheGroups: {                // 缓存组会继承splitChunks的配置,但是test、priorty和reuseExistingChunk只能用于配置缓存组。        priority: "0",              // 缓存组优先级 false | object |        vendor: {                   // key 为entry中定义的 入口名称          chunks: "initial",        // 必须三选一: "initial"(初始化) | "all" | "async"(默认就是异步)          test: /react|lodash/,     // 正则规则验证,如果符合就提取 chunk          name: "vendor",           // 要缓存的 分隔出来的 chunk 名称          minSize: 0,          minChunks: 1,          enforce: true,          reuseExistingChunk: true   // 可设置是否重用已用chunk 不再创建新的chunk        }      }    }  }复制代码

在满足下述所有条件时,那些从相同代码块和缓存组来的模块,会形成一个新的代码块(译注:比如,在满足条件下,一个vendoer可能会被分割成两个,以充分利用并行请求性能)。

有四个选项可以用于配置这些条件:

  • minSize(默认是30000):形成一个新代码块最小的体积
  • minChunks(默认是1):在分割之前,这个代码块最小应该被引用的次数(译注:保证代码块复用性,默认配置的策略是不需要多次引用也可以被分割)
  • maxInitialRequests(默认是3):一个入口最大的并行请求数
  • maxAsyncRequests(默认是5):按需加载时候最大的并行请求数。

懒加载(按需加载)

是一种很好的优化网页或应用的方式。这种方式实际上是先把你的代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载。

lazy.js

export default 'lazy loader';复制代码

main.js 当点击按钮时 再加载lazy.js 输出里面内容

let output = () => {    import('./lazy').then(module => {        console.log(module.default);    });};ReactDOM.render(    
, document.querySelector('#root'))复制代码

vue中懒加载

const Login = () => import(/* webpackChunkName: "login" */'./login')new VueRouter({  routes: [    { path: '/login', component: Login }  ]})复制代码

react中懒加载

babel-plugin-syntax-dynamic-import plugin. This is a syntax-only plugin, meaning Babel won’t do any additional transformations. The plugin simply allows Babel to parse dynamic imports so webpack can bundle them as a code split. Your .babelrc should look something like this:{  "presets": [    "react"  ],  "plugins": [    "syntax-dynamic-import"  ]}react-loadable is a higher-order component for loading components with dynamic imports. It handles all sorts of edge cases automatically and makes code splitting simple! Here’s an example of how to use react-loadable:import Loadable from 'react-loadable';import Loading from './Loading';const LoadableComponent = Loadable({  loader: () => import('./Dashboard'),  loading: Loading,})export default class LoadableDashboard extends React.Component {  render() {    return 
; }}复制代码

开启Scope Hoisting

在webpack4中当mode为production时默认开启了Scope Hoisting 可以让webpack打包出来的代码文件更小、运行更快,它又译作“作用域提升”。

好处: • 代码体积更小,因为函数申明语句会产生大量代码; • 代码在运行时因为创建的函数作用域更少了,内存开销也随之变小

scope.js

export default 'scope hoisting'复制代码

main1.js

import scope from './scope';console.log(scope);复制代码

webpack3 配置scope Hoisting

new webpack.optimize.ModuleConcatenationPlugin()复制代码

开启scope hoisting后的代码

// CONCATENATED MODULE: ./src/scope.js/* harmony default export */ var scope = ('scope hoisting');// CONCATENATED MODULE: ./src/main1.jsconsole.log(scope);复制代码

ES6的静态模块分析,分析出模块之间的依赖关系,尽可能地把模块放到同一个函数中。

同时,考虑到 Scope Hoisting 依赖源码需采用 ES6 模块化语法,还需要配置 mainFields。因为大部分 Npm 中的第三方库采用了 CommonJS 语法,但部分库会同时提供 ES6 模块化的代码,为了充分发挥 Scope Hoisting 的作用,需要增加以下配置

mainFields用于配置第三方模块使用那个入口文件

module.exports = {  resolve: {    // 针对 Npm 中的第三方模块优先采用 jsnext:main 中指向的 ES6 模块化语法的文件    mainFields: ['jsnext:main', 'browser', 'main']  },};复制代码

对于采用了非 ES6 模块化语法的代码,Webpack 会降级处理不使用 Scope Hoisting 优化

源码参考

参考

作者:wenli
链接:https://juejin.im/post/5ac76a8f51882555677ecc06
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的文章
泡泡堂 DirectX11 Demo 2016.8.14 v1.2更新
查看>>
算法导论 简单顺序栈
查看>>
算法导论 顺序循环队列
查看>>
算法导论 顺序双向栈——两个栈共享同一存储空间
查看>>
算法导论 顺序循环双向队列
查看>>
算法导论 使用两个栈实现队列
查看>>
算法导论 使用两个队列实现一个栈
查看>>
算法导论 单链表
查看>>
算法导论 使用单链表实现栈
查看>>
算法导论 使用单链表实现队列
查看>>
算法导论 循环单链表
查看>>
算法导论 循环双链表
查看>>
算法导论 合并两个链表
查看>>
算法导论 O(n)时间内反转单链表
查看>>
深入理解按位异或运算符
查看>>
XOR Linked List – A Memory Efficient Doubly Linked List
查看>>
算法导论 XOR双向循环链表——内存高效链表
查看>>
3D数学 方向、方位和角位移
查看>>
3D数学 RotationMatrix
查看>>
3D数学 欧拉角编程
查看>>