对我们的下一本书感兴趣吗?了解更多关于使用 React 构建大型 JavaScript Web 应用程序

性能模式

捆绑拆分

在构建现代 Web 应用程序时,捆绑器(如WebpackRollup)会获取应用程序的源代码,并将它们捆绑成一个或多个捆绑包。当用户访问网站时,会请求并加载捆绑包,以将数据显示在用户的屏幕上。

JavaScript 引擎(如V8)能够解析和编译用户请求的数据,并在加载过程中进行。虽然现代浏览器已经发展到能够尽可能快地解析和编译代码,但开发者仍然需要负责优化过程中的两个步骤:所请求数据的加载时间和执行时间。我们希望确保执行时间尽可能短,以防止阻塞主线程。

即使现代浏览器能够在数据到达时流式传输捆绑包,在用户设备上绘制第一个像素之前,仍然可能需要相当长的时间。捆绑包越大,引擎到达第一个渲染调用所在的代码行所需要的时间就越长。在此之前,用户必须一直盯着空白屏幕,这可能会非常令人沮丧!

我们希望尽可能快地将数据显示给用户。更大的捆绑包会导致更长的加载时间、处理时间和执行时间。如果我们可以减小捆绑包的大小,那么速度将会加快。

与其请求一个包含不必要代码的巨大捆绑包,不如将捆绑包拆分成多个较小的捆绑包!

通过对应用程序进行捆绑拆分,我们可以减少加载、处理和执行捆绑包所需的时间!通过减少加载和执行时间,我们可以减少在用户屏幕上绘制第一个内容(即首次内容绘制)所需的时间,以及在用户屏幕上渲染最大组件(即最大内容绘制)所需的时间。

虽然能够在屏幕上看到数据很棒,但我们不仅仅想看到内容。为了让应用程序能够完全运行,我们希望用户也能够与之交互!只有在捆绑包加载并执行后,UI 才能变成可交互的。从所有内容绘制到屏幕上并变成可交互状态到所需的时间,被称为可交互时间。

更大的捆绑包并不一定意味着更长的执行时间。我们可能会加载一大堆用户根本不会使用的代码!也许捆绑包中的某些部分只会在用户交互时执行,而用户可能不会进行这种交互!

引擎仍然需要加载、解析和编译用户在看到屏幕上的任何内容之前甚至没有使用的代码。虽然由于浏览器处理这两个步骤的高效方式,解析和编译成本几乎可以忽略不计,但获取比必要更大的捆绑包会影响应用程序的性能。低端设备或网络速度较慢的用户会看到捆绑包获取之前的加载时间明显增加。

即使引擎只使用了文件的最后部分,但第一部分仍然需要加载和处理。与其一开始就请求在当前导航中没有高优先级的代码部分,不如将这些代码与渲染初始页面所需的代码分开。

通过将大型捆绑包拆分成两个较小的捆绑包,main.bundle.jsemoji-picker.bundle.js,我们通过获取更少的数据量来减少初始加载时间。

在这个项目中,我们将介绍一些方法,这些方法允许我们将应用程序捆绑拆分成多个较小的捆绑包,并以最有效和高效的方式加载资源。