webpack 性能优化方案 - 代码分离(分包)

摘要

代码分离(分包)

概念:将代码分离到不同的产物包中,之后可以通过按需或者并行的方式来加载这些文件。

Webpack 常用的代码分离方式:

1-多入口起点:配置多入口:使用entry配置不同的入口文件。手动来分离代码。

2-动态导入:动态导入:import() 语法动态导入模块

3-防止重复:使用Entry Dependencies或者SplitChunksPlugin去重和分离代码。

optimization

optimization.chunkIds:用于告知webpack模块的id采用什么算法生成。

optimization.runtimeChunk:配置runtime相关的代码,决定是否将其抽取到一个单独的chunk中

Prefetch和Preload

  • prefetch(预获取):在浏览器空闲时进行低优先级的资源预加载。
  • preload(预加载):用于提示浏览器尽早加载某些资源。

实践经验:

  • 开发中推荐使用 prefetch。prefetch会在浏览器闲置时下载并缓存,从而在用户导航到需要这些资源的页面时能够更快地加载。

CDN

概念:内容分发网络,是一种通过分布式的服务器来加速网络内容交付的技术。

使用场景:

  • 部署静态资源到CDN服务器上,然后引入对应资源
  • CDN引入依赖包



代码分离

概念

问题背景:

Webpack打包后只有一个文件 bundle.js,然后将它引入到用户界面。

问题是,bundle.js 这个文件很大,浏览器加载会很耗时间,就会有一个白屏显示。

image.png

**解决方案:**代码分离(Code Splitting)


概念:

代码分离(Code Splitting)的主要目的是将代码分离到不同的bundle中,之后可以通过按需或者并行的方式来加载这些文件。

举例:

比如默认情况下,所有的JavaScript代码(业务代码、第三方依赖、暂时没有用到的模块)在首页全部都加载,就会影响首页 的加载速度。

代码分离可以分出更小的bundle,以及控制资源加载优先级,提供代码的加载性能。

Webpack中常用的代码分离有三种:

多入口起点:使用entry配置手动分离代码。

动态导入:通过模块的内联函数调用来分离代码。

SplitChunks 防止重复:使用Entry Dependencies或者SplitChunksPlugin去重和分离代码。



多入口起点

配置多入口

**概念:**配置多入口。

**具体操作:**比如配置一个index.js和main.js的入口。要点如下:

  • 配置 entry,设定分包
  • 配置 output,设定分包产物的名称 filename: '[name]-bundle.js'

webpack.config.js

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development',
  devtool: false,
  /***************************************************************************/
  entry: {
    index: './src/index.js',
    main: './src/main.js'
  },
  output: {
    path: path.resolve(__dirname, './build'),
    filename: '[name]-bundle.js', 
    clean: true
  },
  /***************************************************************************/
  resolve: {
  },
  devServer: {
  },
  module: {
  },
  plugins: [
  ]
}

index.html 进行包的引入

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script defer src="./build/index-bundle.js"></script>
  <script defer src="./build/main-bundle.js"></script>
</head>
<body>
  
  <div id="root"></div>
</body>
</html>

入口依赖

问题背景:

假如我们的index.jsmain.js都依赖两个库:lodash、dayjs

如果我们单纯地进行入口分离,那么打包后的两个bunlde都会有一份lodash和dayjs。

这样会造成资源重复占用。

**解决方案:**入口依赖(Entry Dependencies)

通过 shared 来让两份入口文件共享相同包。

具体操作:

webpack.config.js

entry: {
  index: {
    import: './src/index.js',
    dependOn: 'shared'
  },
  main: {
    import: './src/main.js',
    dependOn: 'shared'
  },
  shared: ['lodash', 'dayjs']
},

npm run build 之后的产出如下:

.
├── index-bundle.js
├── index.html
├── main-bundle.js
└── shared-bundle.js

可以发现,产物中多了一份 shared-bundle.js ,该文件是 index.jsmain.js 产物文件的共享的依赖包。

另外一个代码拆分的方式是动态导入:



动态导入

**概念:**webpack提供两种动态导入的方式:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值