Vue性能优化:延迟加载和代码拆分

本文探讨了Vue应用的性能优化,重点关注延迟加载和代码拆分。通过理解Webpack捆绑的工作原理,文章揭示了随着项目增长,初始JavaScript捆绑包的增大可能导致用户等待时间增加。为了解决这一问题,文章介绍了延迟加载和代码拆分的概念,如动态导入和基于路由的代码拆分。在Vue中,延迟加载组件可以显著减少捆绑包大小。此外,文章还讨论了Vuex模块的动态注册和代码拆分,以减少不必要的代码下载。通过这些技术,可以提高应用程序的加载速度,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Webpack 捆绑的工作原理

延迟加载

动态导入

延迟加载 Vue 组件

应用程序增长

Vue 生态系统中的代码拆分

第三方捆绑反模式

Vuex 模块的两种类型

Vuex 模块的代码拆分

延迟加载 Vuex 模块


Webpack 捆绑的工作原理

首先需要了解 Webpack 如何捆绑文件。在捆绑文件时,Webpack 会创建一个叫作依赖图的东西。它是一种图,链接所有导入的文件。假设 Webpack 配置中有一个叫作 main.js 的文件被指定为入口点,那么它就是依赖图的根。这个文件要导入的每个 JS 模块都将成为图的叶子,而这些叶子中导入的每个模块都将成为叶子的叶子。

Webpack 使用这个依赖图来决定应该在输出包中包含哪些文件。输出包是一个 JavaScript 文件,包含了依赖图中指定的所有模块。

这个过程就像这样:

 

在知道了捆绑的工作原理之后,我们就可以得出一个结论,即随着项目的增长,初始 JavaScript 捆绑包也会随着增大,下载和解析捆绑包所需的时间也会越长,用户等待的时间也会变长,他们离开网站的可能性也就越大。

简单地说,更大的捆绑包 = 更少的用户,至少在大多数情况下是这样的。

延迟加载

那么,在添加新功能和改进应用程序的同时,我们如何减小捆绑包的大小?答案很简单——延迟加载和代码拆分。

顾名思义,延迟加载就是延迟加载应用程序的部分内容。换句话说——只在真正需要它们时加载它们。代码拆分是指将应用程序拆分成可以延迟加载的块。

在大多数情况下,你不需要在用户访问网站后立即使用 JavaScript 包中的所有代码。假设应用程序中有三个不同的路由,无论用户最终要访问哪个更难,总是要下载、解析和执行所有这些路由,即使他们只需要其中的一个路由。多么浪费时间和精力!

延迟加载允许我们拆分捆绑包,并只提供必要的部分,这样用户就不会浪费时间下载和解析无用的代码。

要想知道网站实际使用了多少 JavaScript 代码,我们可以转到 devtools -> cmd + shift + p -> type coverage -> 单击“record”,然后应该能够看到实际使用了多少下载的代码。

标记为红色的都是当前路由不需要的东西,可以延迟加载。如果你使用了源映射,可以单击列表中的任意一个文件,看看是哪些部分没有被调用到。可以看到,即使是 vuejs.org 也还有很大的改进空间。

通过延迟加载适当的组件和库,我们将 Storefront 的捆绑包大小减少了 60%!

接下来,让我们来看看如何在 Vue 应用程序中使用延迟加载。

动态导入

我们可以使用 Webpack 动态导入(https://webpack.js.org/guides/code-splitting/)来加载应用程序的某些部分。让我们看看它们的工作原理以及它们与常规导入的区别。

标准的 JS 模块导入:

// main.js
import ModuleA from './module_a.js'
ModuleA.doStuff()

它将作为 main.js 的叶子被添加到依赖图中,并被捆绑到捆绑包中。

但是,如果我们仅在某些情况下需要 ModuleA 呢?将这个模块与初始捆绑包捆绑在一起不是一个好主意,因为可能根本就不需要它。我们需要一种方法来告诉应用程序应该在什么时候下载这段代码。

这个时候可以使用动态导入!来看一下这个例子:

//main.js
const getModuleA = () => import('./module_a.js')
// invoked as a response to some user interaction
getModuleA()
  .then({ doStuff } => doStuff())

我们来看看这里都发生了什么:

我们创建了一个返回 import() 函数的函数,而不是直接导入 module_a.js。现在 Webpack 会将动态导入模块的内容捆绑到一个单独的文件中,除非调用了这个函数,否则 import() 也不会被调用,也就不会下载这个文件。在后面的代码中,我们下载了这个可选的代码块,作为对某些用户交互的响应。

通过使用动态导入,我们基本上隔离了将被添加到依赖图中的叶子(在这里是 module_a),并在需要时下载它(这意味着我们也切断了在 module_a.js 中导入的模块)。

让我们看另一个可以更好地说明这种机制的例子。

假设我们有 4 个文件:main.js、module_a.js、module_b.js 和 module_c.js。要了解动态导入的原理,我们只需要 main 和 module_a 的源代码:

//main.js
import ModuleB from './mobile_b.js'
const getModuleA = () => import('./module_a.js')
getModuleA()
  .then({ doStuff } =&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值