打包时如何减少 React 应用程序构建时间和理解 webpack 的行为

Din*_*tta 7 lazy-loading heap-memory build-time reactjs webpack

最近我正在尝试优化 Web 应用程序(React)的性能。假设它有点重,因为它由代码编辑器、Firebase、SQL、AWS SDK 等组成。所以我集成了react-loadable它将延迟加载组件,之后,我得到了这个 Javascript 堆内存不足的问题。

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory in React

经过一些研究(从朋友那里),我开始知道如果我们保留太多延迟加载,webpack 会尝试并行捆绑它们这可能是导致 Javascript 堆内存问题的原因,以确认我删除了所有延迟加载路由在我的应用程序中构建。现在构建成功。后来按照社区的建议,我增加了 Node 堆空间大小并获得了以下见解

首先,我将其增加到8 GB(8192),然后构建成功,我的构建时间约为72 分钟,从下一次开始,我获得了大约20 分钟。然后我将堆内存大小减少到4 GB(4096)并且构建成功大约需要15 - 20 分钟。系统配置为2vCPU, 16GB RAM(AWS EC2 Instance r5a.large)

接下来,我继续构建另一个系统(Mac book pro, i5, 8 GB RAM, 4 Cores)现在花了30 分钟,第二次花了20 分钟

所以从这些数据点,我有几个问题

  1. 每当我们添加一些代码时,我们是否需要不断增加堆空间?如果是,社区中的平均堆内存大小是多少
  2. 这些类型的重型应用程序的构建系统的通常配置是什么,为什么因为现在我不确定是否增加内核或 RAM 或堆空间的数量,或者与我们的应用程序代码有关。
  3. webpack 是否提供任何类型的解决方案来避免堆内存问题,例如限制并行进程或任何插件?
  4. 如果它与我们的应用程序代码有关,是否有任何标准流程可以调试占用内存的位置并基于此进行优化

PS:有些人建议GENERATE_SOUCREMAP=false让它继续工作,但我们需要源映射,因为它们将有助于调试生产问题

Din*_*tta 3

最后,我可以heap out of memory在不增加堆内存空间的情况下解决这个问题。

正如问题中提到的,如果我删除所有惰性路由,构建就会成功,或者我必须保留 4GB 堆空间,才能在充足的构建时间下成功。当使用 4GB 堆空间构建成功时,我观察到近 8 - 10 个块文件大小接近 1MB。所以我使用Source map explorer分析了所有这些块。在所有块中都包含几乎相同的库代码(在我的例子中,这些代码是 Firebase、视频播放器等,这些代码都很重)

因此,在我的假设中,当 webpack 尝试捆绑所有这些块时,它必须在每个块中构建所有这些库依赖关系图,这反过来会导致堆内存空间问题。所以我使用Loadable 组件来延迟加载这些库。

延迟加载所有这些库后,所有块文件大小几乎减少了一半,并且构建在不增加任何堆空间的情况下取得了成功,并且构建时间也减少了。

优化后,如果我继续在6vCPU、i7 系统中构建,大约需要3 - 4 分钟,我观察到,根据系统中可用的核心数量,构建时间正在减少。如果我继续构建 2vCPU 系统,有时会花费大约 20 - 25 分钟