资讯专栏INFORMATION COLUMN

Vue.js应用性能优化:第一部分---介绍性能优化和懒加载

ZweiZhao / 2956人阅读

摘要:我的目标是使本系列成为关于应用程序性能的完整指南。代码分割就是将应用程序分割成这些延迟加载的块。总结延迟加载是提高应用程序性能并减少其大小的最佳方法之一。在本系列的下一部分中,我将向您展示如何使用和路由来分割应用程序代码。

当“移动优先”(mobile-first)的方式逐渐成为一种标准,而不确定的网络环境因素应该始终是我们考虑的一点,因此保持让应用程序快速加载变得越来越困难。在本系列文章中,我将深入研究Vue性能优化技术,我们在 Vue Storefront 中已经使用了这些技术,您也可以在Vue.js应用程序中使用这些技术,使它们能够立即加载并顺利运行。我的目标是使本系列成为关于Vue应用程序性能的完整指南。

Part 1 — Introduction to performance optimization and lazy loading.

Part 2 — Lazy loading routes and vendor bundle anti-pattern.

Part 3 — Lazy loading Vuex modules

Part 4 — Delivering good waiting experience and lazy loading individual components — soon

Part 5 — Lazy loading libs and finding smaller equivalents — soon

Part 6 — Performance-friendly usage of UI libraries

Part 7 — Making use of Service Worker cache — soon

Part 8 — Prefetching

Webpack 打包工作原理

本系列的大部分技巧将集中于使我们的JS包更小。要理解这一点,首先我们需要理解 Webpack 是如何打包(bundling)我们所有的文件的。当打包我们的资源时,Webpack 创建了被成为依赖图(dependency graph)的东西,它是一个基于入口,链接我们所有文件的图。假设我们在webpack配置中指定了一个名为 main.js 的文件作为入口点,它将是依赖关系图的根。现在,我们将在此文件中导入的每个js模块将成为图中的节点,并且在此节点中导入的每个模块都将成为其节点。Webpack 正是使用这个依赖关系图来检测输出的包中应该包含哪些文件。输出包只是一个包含依赖关系图中所有模块的 Javascript 文件(或后面的部分将看到多个)。

我们可以图解这个过程,像这样:

现在,当我们知道打包是如何工作的,很明显我们的项目越多,初始的 javascript 包体积会变的越大。包太大,下载和解析的时间就会越长,用户过很长时间才能看到有意义的东西。用户等待的时间越长,他/她就越有可能离开我们的网站。

简而言之,更大的bundle = 更少的用户。至少在大多数情况下是这样。

延迟加载

因此,当我们仍然需要添加新特性和改进应用程序时,我们如何能够减少包的大小?答案很容易-延迟加载和代码分割。

顾名思义,延迟加载就是延迟加载应用程序的某些部分。换句话说,只有在我们真正需要的时候才加载它们。代码分割就是将应用程序分割成这些延迟加载的块。

在大多数情况下,您不需要在用户访问您的网站后立即从Javascript文件中获得所有代码。即使我们的应用程序中会有3个不同的路由,不管用户最终会在哪个路由上,他/她总是需要下载、解析和执行文件中三个路由的代码,即便是只需要访问一个路由。多么浪费时间和精力!

延迟加载允许我们分割包(split the bundle),并只提供所需要的部分,这样用户就不会浪费时间下载和解析不被使用的代码。

要查看我们的网站实际使用了多少JavaScript代码,我们可以到开发者工具 -> cmd+shift+p -> type coverage -> 点击 "record"。现在我们应该能够看到实际使用了多少下载的代码。

所有标记为红色的东西都是当前路由上不需要的,可以延迟加载。如果您正在使用源码映射(source maps ),您可以单击此列表中的任何文件,查看它的哪些部分没有被调用。我们可以看到,即使是 vuejs.org 也有很大的改进空间。

通过延迟加载适当的组件和库,我们设法将 Vue Storefront 的文件大小减少了60%!

好了,我们知道什么是延迟加载,它非常有用。

现在来看看如何在Vue.js应用程序中使用它。

动态导入 (Dynamic imports)

我们可以轻松地用 webpack dynamic imports 加载应用程序的某些部分。让我们看看它们是如何工作的,以及它们与常规导入有何不同。

如果我们将以这样的标准方式导入JS模块:

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

它将作为 main.js 的一个节点添加到依赖关系图中,并与之打包在一起。

但是,如果我们仅在某些情况下需要 ModuleA,例如对用户交互的响应,那该怎么办呢?将这个模块与初始文件打包在一起不是一个好主意,因为可能根本不需要它。我们需要一种方法来告诉应用程序何时应该下载这段代码。

这就是动态导入可以帮助我们的地方!现在看看这个例子:

//main.js
const getModuleA = () => import("./module_a.js")
// 作为对某些用户交互的响应调用
getModuleA()
  .then({ doStuff } => doStuff())

让我们快速看看这里发生了什么:

我们没有直接导入 module_a.js,而是创建了一个返回 import() 函数的函数。现在webpack将动态导入模块的内容打包到一个多带带的文件中,除非函数被调用,否则不会导入也不会下载文件。在稍后的代码中,我们下载了这段可选代码,作为对某些特定用户交互的响应(如路由更改或单击)。

通过动态导入,我们基本上隔离了将添加到依赖关系图中的给定节点(在本例中是 module_a),并在确定需要时下载这一部分(这意味着我们还切断了在module_a.js中导入的模块)。

让我们看另一个例子,它将更好地说明这种机制。

假设我们有4个文件: main.js, module_a.jsmodule_b.jsmodule_c.js。要了解动态导入的工作原理,我们只需要 mainmodule_a 的源代码:

//main.js
import ModuleB from "./mobile_b.js"
const getModuleA = () => import("./module_a.js")
getModuleA()
  .then({ doStuff } => doStuff()
)
//module_a.js
import ModuleC from "./module_c.js"

通过使 module_a 成为一个动态导入的模块,我们把 module_a 及其所有的子模块从依赖图切割成一部分。当 module_a 被动态导入时,它与其中导入的模块一起加载。换句话说,我们只是为依赖关系图创建了一个新的入口点。

这就是我们的依赖关系图和文件包在给定设置下的样子。

延迟加载Vue组件

我们知道什么是延迟加载,以及为什么需要它。现在看看如何在Vue应用程序中使用它。

好消息是它非常简单,我们可以延迟加载整个SFC(译者注:Vue Single-File Component -- 单文件组件)以及它的css和html,语法与之前一模一样!

const lazyComponent = () => import("Component.vue")

这就是你所需要的! 现在只有在请求时才会下载组件。 以下是调用Vue组件动态加载的最常用方法:

调用带有导入的函数

const lazyComponent = () => import("Component.vue")
lazyComponent()

组件请求后渲染


请注意,只有当组件被请求要在模板中渲染时,才会调用 lazyComponent 函数。
例如下面的代码:

 

这样不会动态导入组件,因为它并没有添加到DOM中(但是当值变为true时就会动态导入,这是一种延迟加载Vue组件的好方法)。

总结

延迟加载是提高web应用程序性能并减少其大小的最佳方法之一。我们学习了如何使用Vue组件的延迟加载。在本系列的下一部分中,我将向您展示如何使用 Vue-routerasync 路由来分割Vue应用程序代码。

如果对你有帮助,请关注【前端技能解锁】:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110215.html

相关文章

  • 前端每周清单第 10 期:Firefox53、React VR发布、Microsoft Edge现代

    摘要:新闻热点国内国外,前端最新动态发布近日,正式发布新版本中提供了一系列的特性与问题修复。而近日正式发布,其能够帮助开发者快速构建应用。 前端每周清单第 10 期:Firefox53、React VR发布、JS测试技术概述、Microsoft Edge现代DOM树构建及性能之道 为InfoQ中文站特供稿件,首发地址为这里;如需转载,请与InfoQ中文站联系。从属于笔者的 Web 前端入门...

    MingjunYang 评论0 收藏0
  • vue项目搭建以及全家桶的使用详细教程

    摘要:前言是现阶段很流行的前端框架,很多人通过官方文档的学习,对的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎么更好的管理自己的项目,如何去引入一些框架以及全家桶其他框架的使用,以下将详细地介绍本人在处理工程文件构建的过程对 前言 vue是现阶段很流行的前端框架,很多人通过vue官方文档的学习,对vue的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎...

    simon_chen 评论0 收藏0
  • vue项目搭建以及全家桶的使用详细教程

    摘要:前言是现阶段很流行的前端框架,很多人通过官方文档的学习,对的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎么更好的管理自己的项目,如何去引入一些框架以及全家桶其他框架的使用,以下将详细地介绍本人在处理工程文件构建的过程对 前言 vue是现阶段很流行的前端框架,很多人通过vue官方文档的学习,对vue的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎...

    curlyCheng 评论0 收藏0
  • vue项目搭建以及全家桶的使用详细教程

    摘要:前言是现阶段很流行的前端框架,很多人通过官方文档的学习,对的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎么更好的管理自己的项目,如何去引入一些框架以及全家桶其他框架的使用,以下将详细地介绍本人在处理工程文件构建的过程对 前言 vue是现阶段很流行的前端框架,很多人通过vue官方文档的学习,对vue的使用都有了一定的了解,但再在项目工程化处理的时候,却发现不知道改怎...

    xi4oh4o 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<