虽然如今网络环境和电子设备变得愈来愈好,可是保持应用程序快速加载变得愈来愈困难。在本系列中,我将深刻研究咱们在实践中使用的Vue性能优化技术,而且您能够在Vue.js应用程序中使用它们,使应用程序快速加载并顺利执行。个人目标是让这个系列成为关于Vue应用程序性能的全面而完整的指南。javascript
Webpack bundling 打包机制
本系列中的大多数技巧都将集中在如何使咱们的JS包更小。要了解它,首先咱们须要了解Webpack如何打包全部文件。vue
打包咱们的资源(assets)时,Webpack会建立一个依赖图。它是一个基于导入连接全部文件的图表。假设咱们在webpack配置中指定了一个名为main.js的文件做为入口点,它将成为咱们依赖图的根。如今,咱们将在此文件中导入的每一个js模块将成为图中的节点,而且在这些节点中导入的每一个模块都将成为其节点。java
Webpack使用此依赖关系图来检测它应该包含在输出包中的文件。输出包只是一个(或咱们将在后面的部分中看到的多个)javascript文件,其中包含依赖图中的全部模块。webpack
这个bundle包本质上是咱们整个应用程序的JavaScript。web
咱们能够用下图来讲明这个过程:性能优化
如今咱们知道webpack是如何打包的,很明显咱们的项目越大,初始JavaScript包就越大。网络
越大的初始bundle,下载和解析,咱们的用户所需的时间就越长。用户必须等待的时间越长,他离开咱们网站的可能性就越大。事实上,据搜索引擎统计,53%的移动用户留下的页面加载时间超过3秒。异步
总而言之,更大的bundle=更少的用户,这能够直接转化为潜在收入的损失。有关案例统计,延迟2秒致使每位访客的收入损失4.3%。函数
延迟加载
那么当咱们仍然须要添加新功能并改进咱们的应用程序时,咱们如何削减budle包大小?答案很简单 - 延迟加载和代码分割。工具
顾名思义,延迟加载是一个懒惰地加载应用程序的部分(块)的过程。换句话说 - 只有在咱们真正须要它们时加载它们。代码拆分只是将应用程序拆分为多个延迟加载的代码块的一种处理方式。
在大多数状况下,当用户访问您的网站时,您不须要当即使用Javascript包中的全部代码。
例如,咱们不须要花费宝贵的资源来为首次访问咱们网站的访客加载“个人页面”区域。或者可能存在每一个页面上不须要的模态,工具提示和其余零件和组件。
当只须要几个部分时,在每一个页面加载时下载,解析和执行整个包的全部内容都是浪费。
延迟加载容许咱们拆分捆绑包并仅提供所需的部分,这样用户就不会浪费时间下载和解析不会使用的代码。
要查看咱们网站中实际使用了多少JavaScript代码,咱们能够转到devtools - > cmd(ctrl) + shift + p - >输入coverage - >点击Performance instrument coverage 。如今咱们应该可以看到实际使用了多少下载的代码。
标记为红色的全部内容都是当前路由上不须要的东西,能够延迟加载。若是您正在使用source maps,则能够单击此列表中的任何文件,并查看那些未调用部分。正如咱们所看到的,甚至vuejs.org还有很大的改进空间)。
经过延迟加载适当的组件和库,咱们设法将Vue Storefront的捆绑大小减小了60%!这多是得到性能提高的最简单方法。
如今咱们知道延迟加载是什么,它很是有用。如今是时候看看咱们如何在咱们本身的Vue.js应用程序中使用延迟加载。
动态导入
咱们可使用webpack的动态导入,轻松地加载咱们应用程序的某些部分。让咱们看看它们的工做原理,以及它们与常规导出模块的区别。
若是咱们以这样的标准方式导入JavaScript模块:
它将做为main.js的节点添加到依赖关系图中并与之捆绑在一块儿。
可是,若是咱们仅在某些状况下须要咱们的Cat模块,例如对用户交互的响应,该怎么办?将此模块与咱们的初始bundle包捆绑在一块儿是一个坏主意,由于它不是一直须要的。咱们须要一种方法告诉咱们的应用程序何时应该下载这段代码。
这是动态导入能够帮助咱们的地方!如今看一下这个例子:
咱们来看看这里发生的事情:
咱们建立了一个返回import()函数的函数,而不是直接导入Cat模块。如今,webpack会将动态导入的模块的内容捆绑到一个单独的文件中。表示动态导入模块的函数返回一个Promise,它将使咱们在Promise resolve后,能够访问导出的模块成员。
而后,咱们能够在须要时下载此可选块。例如,做为对某个用户交互的响应(如路由更改或单击)。
经过动态导入,咱们基本上将给定节点(在这种状况下为Cat)隔离,当咱们决定须要时,它将被添加到依赖图并下载此部分(这意味着咱们也砍掉了一些Cat.js 中导入的模块)。
让咱们看另外一个更好地说明这种机制的例子。
假设咱们有一个很是小的网上商店,有4个文件:
main.js 做为咱们的主要bundle包
product.js 用于产品页面中的脚本
productGallery.js 用于产品页面中的产品库
category.js 用于类别页面中的脚本
在上面的代码中,根据当前路由,咱们动态导入产品或类别模块,而后运行由它们二者导出的init函数。
了解动态导入的工做方式以后,咱们知道产品和类别最终会以单独的bundle包形式出现,可是未动态导入的productGallery模块会发生什么?正如咱们所知,经过动态导入模块,咱们削减了依赖图中的一部分。此部件中导入的全部内容都将捆绑在一块儿,所以productGallery将与产品模块位于同一个bundle包中。
换句话说,咱们只是为依赖图建立某种新的入口点。
延迟加载Vue components
如今咱们知道延迟加载是什么,以及为何须要它。如今是时候看看咱们如何在Vue应用程序中使用它了。
好消息是它很是简单,咱们能够懒加载整个vue单一文件组件(SFC),vue文件语法和HTML, CSS同样。不熟悉的话,去看看官方文档。
如今只有在请求时才会下载组件。如下是调用Vue组件动态加载的最经常使用方法:
请注意,仅当请求的组件在模板中渲染时,才会调用lazyComponent函数。例如这段代码:
在DOM中须要渲染组件以前,组件将不会加载。想要加载,只要v-if值更改成true便可。
总结
延迟加载,是使您的Web应用程序更高效并减小js bundle大小的最佳方法之一。咱们已经学习了如何使用Vue组件进行延迟加载。
在本系列的下一部分中,我将向您展现在任何Vue.js应用程序上得到显着性能提高的最有用(也是最快)的方法。
您将学习如何使用异步路由拆分Vue代码,以及此过程当中推荐的最佳实践。