乐趣区

关于javascript:面试三板斧-之-代码分割上


译:https://medium.com/dailyjs/we…

背景

代码宰割是前端性能优化中非常常见的优化伎俩。

提到代码宰割,往往离不开 webpack 中的一项配置,它就是 splitChunks

当初比拟多的我的项目用的都是 webpack4, webpack 4 舍弃了之前的 commonChunkPlugin,减少了 SplitChunksPlugin

对于这个插件,它的 option 选项有:

  1. initial
  2. async
  3. all

三个值。

对于这三个值,哪怕是工作多年的老司机,能记得清,辨别的清的恐怕不是很多。

我最近也在做性能优化,通过简略的几行配置,白屏工夫就缩短了将近 600 ms, 非常喜人。

before :

after:

Load 时长由 2.3s 升高至 1.57s, 还是不错的。

具体的剖析过程以及优化办法我将在 下一篇实战篇 中介绍。

回归正题,咱们先理解一下根底原理。

注释局部翻译自 Medium, 原文地址:

https://medium.com/dailyjs/we…

注释

这是我的一个粗略尝试,通过一个常见的例子来了解和帮忙你应用 SplitChunksPlugin选项。

作为晚期的爱好者,我试图了解代码宰割 (Code-Spliting) 背地的魔法。

文档说 splitChucnks 能够承受三个非法的值,它们别离是:

  • initial
  • async
  • all

我有点困惑,更加进步了我的好奇心。

我深入研究了文档的 Github 历史记录和 WebpackOptions 概要,并发现:

“There are 3 values possible”initial”,”async”and”all”. When configured the optimization only selects initial chunks, on-demand chunks or all chunks.”— Github History

“Select chunks for determining shared modules (defaults to“async”,“initial”and“all”requires adding these chunks to the HTML)”
— WebpackOptions Schema

这里的想法是有 a.js 和 b.js 两个入口文件 ,而后 援用雷同的 node_modules

其中的一些 module 会被动静引入,用来 测验代码宰割 (Code-Spliting) 的行为

咱们应用 Webpack Bundle Analyzer Plugin 来帮忙咱们了解咱们的 node_modules 是如何被宰割的。

a.js:

只有 lodash 是动静引入的

b.js:

我选这样的配置的次要起因是为了了解当存在公共库时,Webpack 配置的体现是如何的:

  • 在一个入口文件动静引入,另一个则不是 – React
  • 在两个入口文件都动静引入 – lodash
  • 在两个入口文件中都不动静引入 – jquery

咱们将放弃这些文件不变,并通过 chunks 的值来更改 webpack 的配置。

1. chunks : async — Optimization over async module

打包之后的构造:

chunks: async 通知 webpack:

”hey,webpack!我只关怀动静导入的模块的优化。你能够保留非动静模块“

当初,让咱们一步一步看看产生了什么:

webpack 会从 b.js 提取出 react,并挪动到一个新文件,但放弃 a.js 中的 react 不动。

这个优化只会作用到动静模块。

import('react') 申明会产生独立的文件

import 'react' 则不会。

webpack 从 a.js 中提取 lodash,并挪动到一个新文件,该文件也被 b.js 援用了。

这里不会对 jquery 进行优化,只管 a.js 和 b.js 都援用了。

2. chunks : initial — Optimization over Sync Module

打包之后:

chunks: initial 通知 webpack:

hey,webpack!我不关怀动静引入的模块,你能够为每一个模块别离创立文件。然而,我心愿将所有非动静引入的模块放在一个 bundle 中,只管它们还须要引入其余的非动静引入的木块,我筹备与其余文件共享和分块我的非动静导入模块。

当初,让咱们一步一步看看产生了什么:

  • a.js 中的 react 会被挪动到node_vendors~a.bundle.js
  • b.js 中的 react 会被挪动到0.bundle.js
  • a.js 和 b.js 中的 lodash 会被挪动到1.bundle.js

为什么?

因为这是一个 动静引入 的模块。

jquery 是一个非动静导入的公共模块,会挪动到 node_vendorsab.bundle.js,被 a.js 和 b.js 共享

3. chunks : all — Optimization over Async and Sync Module

打包之后:

chunks: all 通知 webpack:

hey,webpack!我不关怀这是一个动静还是非动静引入的模块。都对它们进行优化。但要确保 …… 你足够聪慧这样做。

当初,让咱们一步一步看看产生了什么:

  • react 在 a.js 中是非动静引入的模块,在 b.js 中是动静引入的。因而,它转到单个文件 0.bundle.js,它将由两者援用。
  • lodash 在两个文件中都是动静引入的,所以它显然失去一个独自的文件 1.bundle.js
  • jquery 是非动静导入的,因而它转到公共共享模块 node_vendorsab.bundle.js,并将由两者援用。

由此可见,选用不同的值,将间接影响 webpack 的打包行为, 打来带来不同的后果。

明天在看这部分的文档,发现有这样一句形容:

Providing all can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.

官网明示的几乎不要太显著。

但如何选用不同的值,来实现最优成果呢?

这点咱们将在下一篇详细分析。

明天这篇就先到这,心愿对大家有所帮忙,谢谢大家。


如果你感觉这篇内容对你挺有启发,能够:

  1. 点个「在看」,让更多的人也能看到这篇内容。
  2. 关注公众号「前端 e 进阶 」,把握前端面试重难点,公众号后盾回复「 加群」和小伙伴们畅聊技术。

更多精彩:

「面试三板斧」之 HTTP(下)

「面试三板斧」之 HTTP(上)

「面试三板斧」之缓存 (下)

「面试三板斧」之缓存 (上)

「面试三板斧」之框架

「面试三板斧」之  this

退出移动版