这篇文章分享了从遇到前端业务性能问题,到分析、解决并且梳理出通用的Vue 2.x 组件级懒加载解决方案(Vue Lazy Component )的过程。

初始加载资源过多

问题起源于我们的一个页面,下面是这个页面的截图和初次请求的瀑布图。

初始加载的时候,一共请求了155个资源,请求的瀑布图就快要和页面一样长了?

初始加载的资源过多导致在 domInteractive 之后,页面花费了大量时间加载子资源,导致页面的 load 时长被严重拖长,达到了 5.6s 。

来看看这些子资源都是什么,根据请求资源的类型,我们找到了最多的类型是图片,这是显而易见的,页面上到处都是大图片,其次是 js 文件,由第三方的业务插件和一些 JSONP 的接口组成。

问题分析

再回到最初的这个页面,结合上面的数据情况我们得出了这个页面的问题总结结论:页面由大量模块组成

每个模块部分由首页自主维护,部分由业务方通过插件维护

所有模块是同时进行加载

模块中图片内容较多

每个模块的依赖资源较多(包括js文件、接口文件、css文件等)

解决思路

我们提出了下面两个主要的解决思路:

组件化分治思想

为了方便后续的优化,我们必须要求每个模块之间降低耦合,将相关的逻辑(比如请求接口、请求相关的依赖资源)都封装在内部,在 Vue 里落实成组件的形式。将各模块拆分为组件粒度

将组件依赖的资源全部封装在组件内部进行调用

加载优先级

在完成了组件化的拆分,确保模块之间不会互相影响和产生耦合之后,我们可以方面地调整加载策略。加载的策略是根据可见性来处理优先级问题。优先加载首屏可见模块

其余不可见模块懒加载,待可见或即将可见时加载

有了上面的解决思路,我们开始思考具体的实现:

如何解决判断可见性问题?

从前我们都是通过监听滚动事件、resize 事件来判断模块是否可见,代码不仅繁琐,而且一不小心没有函数去抖就又可能导致严重的性能问题。

现在我们有了更好的选择—— IntersectionObserver API ,IntersectionObserver 允许你配置一个回调函数,每当 target ,元素和设备视口或者其他指定元素发生交集的时候该回调函数将会被执行。这个 API 的设计是异步的,而且保证你的回调执行次数是非常有限的,而且回调是会在主线程空闲时才执行,在性能方面表现更优,使用起来也更简单。

目前是现代浏览器支持,低版本浏览器可以通过 polyfill 兼容。

如何尽可能懒的条件渲染?

在解决了加载条件的判断之后,我们需要解决加载条件为假的情况下不去渲染、加载条件为真的时候才渲染的问题,这里的答案非常简单:使用 Vue.js 提供的 v-if 指令,就可以做到真正的惰性渲染。

如果可见后进行初始渲染,可见前如何显示?

如果在判断加载条件为假的时候,什么都不渲染,就会带来一系列问题:用户体验比较差,最开始是白屏,然后突然又渲染出现内容。

最致命的是我们判断可见性是需要一个目标来观察的,如果什么不都渲染,我们就无从观察。

这里引入一个骨架屏的概念,我们为真实的组件做一个在尺寸、样式上非常接近真实组件的组件,叫做骨架屏。

骨架屏的作用有:提升用户感知体验

保证切换的一致性

提供可见性观察的目标对象

如何提升切换时的体验?

在真实组件开始渲染的时候,需要一定的时间和空间,时间指的是真实组件从创建到渲染的时间,包括请求接口、请求资源和渲染的时间,空间指的是页面布局中需要给真实组件留出刚好的位置,避免产生抖动。

这里我们可以使用 Vue.js 内置的 transition 组件自定义骨架组件和真实组件的进入和离开效果,通过合理的布局和定位,减少切换时的抖动,

通过设置过渡效果给真实组件留出一定的加载时间。

上面的问题都有了答案之后,我们很容易就可以实现一个通用的方案,来解决组件的懒加载问题。

Vue组件懒加载方案介绍

这个是我们基于上面的思考做的一个通用的解决方案,下面简单介绍一下特性、使用以及 API 方面的知识,后面结合 5 个具体的 DEMO 来讲解更高级的用法。

特性支持 组件可见或即将可见时懒加载

支持 组件延时加载

支持 加载组件前展示组件骨架,提高用户体验

支持 懒加载组件分包异步加载

安装和使用

npm i @xunlei/vue-lazy-component方式1 利用插件方式全局注册

方式2 局部注册

方式3 独立版本引入,自动全局注册

用法

Props

Events

DEMO 1 超长页面懒加载

通过上面这种简单的使用方式就可以实现组件即将可见时自动加载。

DEMO 2 延时加载

`

如果有时候仅仅是希望某些组件稍后渲染,而不一定要等到可见时,可以通过这种方式。

比如我们业务中可能会有些运营性质的挂件,就可以采取延时加载的方式。

DEMO 3 自定义过渡效果

如果觉得 Vue Lazy Component 自带的淡入淡出的过渡效果太丑,或者需要调整淡入淡出效果的时长,就可以通过自定义样式来改变过渡效果。这个例子演示了另外一种过渡效果,transition 的生命周期可以参考 Vue.js 的 transition 组件的文档。

DEMO 4 webpack 分包

DEMO1 演示了如何懒加载模块,但其实只是推迟了模块的渲染和模块内的资源的加载,如果我们需要更进一步,连模块本身的代码也是懒加载,就像 AMD 那样异步按需加载,这个也是可以做到的。

这里可以利用Vue.js的异步组件,将每个真实组件都注册成异步组件,在异步组件的工厂函数里使用 Webpack 的 AMD 版本的 require ,就可以实现真实组件可以分成独立的 bundle 加载,脱离页面 js 的bundle。

但是这里会有个问题,就算模块是可见时才渲染,在打开页面的时候会发现模块不可见之前它的 bundle 已经加载了,这并没有实现按需加载。

这个例子演示了一种做法,Vue Lazy Component 可以在即将切换真实组件前通过 Scoped Slots 传递一个 loading 属性给真实组件,真实组件只要是根据这个 loading 来条件渲染就可以避免非按需加载,这个和 Vue.js 对组件的解析机制有关,例子里有相应的的代码,有兴趣的同学可以深入研究下。

DEMO 5 特定视口内懒加载

在某些场景下,我们要解决滚动容器内的组件懒加载,这个时候可见性是相对与这个视口来的,这个例子演示了如何指定聊天窗口作为观察的视口。

这里吐槽下Vue.js的 $parent 、$refs 的设计,它们都不是响应式的,如果需要动态获取这些组件引用上的 $el ,必须要等到 mounted 事件发生之后,所以例子的代码稍微有一点繁琐。

应用效果

首先 Vue Lazy Component 的设计虽然是说组件级的,其实它的粒度可大可小,大的比如页面不同的区域,小的就像 DEMO5 里的只是一个用户头像,所以适用性非常强,只要有懒加载需求的场景基本都可以采用。

另外,在终端方面,不仅可以兼容PC端的项目,在移动端也是可以使用的,当然,需要解决 IntersectionObserver API 的兼容性问题,在项目 Readme 里提到了 w3c 的 polyfill 的地址。

应用业务

我们目前应用在迅雷的两个项目中,一个是 PC 迅雷的首页项目,一个是 PC 迅雷的组队加速项目,后期预计会推广到更多的业务中去。

优化后请求瀑布图

我们再来看看开始那个页面的情况,在使用了 组件懒加载技术后,请求数变成了只有 31 个,瀑布图变得比较短了。

数据对比

我们把前后的数据进行一个对比:

请求数变成之前的 1 / 5,优化效果比较明显

请求大小相比之前降低不太明显

load 时长也同样不太明显

分析主要是有较多图片未按照使用尺寸裁剪和压缩,导致请求大小较大,同时造成了 load 时长的拖长。

后续性能优化方向

后续我们会继续来优化这个页面,主要的方向有两个:

图片尺寸适配和压缩

通过图片的裁剪和压缩,解决请求资源大小较大子资源加载时间较长导致 load 时间拖长的问题

预渲染

采用预渲染插件将页面的主要 css 、js 进行内联,将骨架架屏通过预渲染生成出来,这样可以避免 SPA 首屏可见关键路径较长的问题,在页面解析完 dom 树以后即可保证首屏可见。

懒加载方案 ROADMAP

Vue Lazy Component 懒加载方案还有些地方做得还不够好,计划在后期的几个小版本里支持以下的特性:SSR 支持 v1.1.0

UI单元测试 v1.2.0

减少性能开销 v1.3.0重绘

FPS

后记

这篇文章分享了从遇到业务实际性能问题,到分析、解决并梳理出通用的解决方案的过程,重点其实不是最终的实现代码实现,而是解决问题的角度和过程。

微信搜索 蜂鸟前端 关注迅雷前端公众号

vue延迟渲染组件_性能优化之组件懒加载: Vue Lazy Component 介绍相关推荐

  1. vue 图片拖动加载 类似于地图_前端性能优化之图片懒加载(附vue自定义指令)...

    作者:lzg9527 链接:https://juejin.cn/post/6903774214780616718 在类电商类项目,往往存在大量的图片,如 banner 广告图,菜单导航图,美团等商家列 ...

  2. 性能优化之图片懒加载

    本文在github做了收录 github.com/Michael-lzg- demo源码地址 github.com/Michael-lzg- 为什么要进行图片懒加载 我们先来看一下页面启动时加载的图片 ...

  3. 小程序性能优化之页面预加载方案——让你的小程序运行如飞 进阶篇

    小程序性能优化之页面预加载方案 进阶篇 转载请注明出处:https://blog.csdn.net/sinat_27612147/article/details/80798452 写在前面 预加载方案 ...

  4. 前端性能优化学习 08 资源加载优化

    图片延迟加载 什么是延迟加载 首先来想象一个场景,当浏览一个内容丰富的网站时,比如电商的商品列表页.主流视频网站的节目列表等,由于屏幕尺寸的限制,每次只能查看到视窗中的那部分内容,而要浏览完页面所包含 ...

  5. 前端性能优化——如何提高页面加载速度?

    1.将样式表放在头部 首先说明一下,将样式表放在头部对于实际页面加载的时间并不能造成太大影响,但是这会减少页面首屏出现的时间,使页面内容逐步呈现,改善用户体验,防止"白屏". 我们 ...

  6. 小程序性能优化之页面预加载方案——让你的小程序运行如飞 集成篇

    小程序性能优化之页面预加载方案 集成篇 转载请注明出处:https://blog.csdn.net/sinat_27612147/article/details/80802725 前言 之前看到一篇文 ...

  7. 性能优化——图片压缩、加载和格式选择

    本文首发于政采云前端团队博客:性能优化--图片压缩.加载和格式选择 https://www.zoo.team/article/images-compress 前言 相信大家都听说过 "258 ...

  8. vue首屏性能优化,解决页面加载时间过长(白屏)方法

    vuecli做了个spa项目,大概有几十个个路由 直接 npm run build打包出来,有一个 1M的巨大 js文件,导致首页白屏时间过长 分析工具 vuecli 2.x自带了分析工具,只要运行 ...

  9. web前端页面性能优化(提升页面加载速度)

    我们都知道,对于web应用来说性能很重要,然而性能的优化相关知识非常庞大而复杂,对于性能优化我们需要做些什么,或者瓶颈是什么通常是我们不太了解的.(当然技术大牛除外) 通过查阅相关资料,了解到了一些关 ...

最新文章

  1. pandas使用sort_values函数将dataframe按照指定数据列的内容对dataframe的数据行进行排序(sort dataframe rows by a specific column
  2. SQL语言基本语句介绍
  3. 小白学数据分析-----从购买记录分析道具支付环节
  4. Java Selenium Actions模拟鼠标拖动dragAndDrop总结
  5. nodejs调试ndb_如何开始使用NDB调试NodeJS应用程序
  6. java applet socket_Java swing applet中使用的套接字
  7. 双向循环链表【数据结构】
  8. oracle高效分页存储过程(百万数据级)
  9. unity使用屏幕后处理实现闪烁特效,创建新的shader文件过程
  10. 如何安装suse linux操作系统,SUSE Linux Enterprise Server 11 SP3安装教程详解
  11. COCO2017 数据集分类统计
  12. 开源的物理引擎_开源物理引擎
  13. 今日,华为重磅发布6大创新产品及服务!
  14. linux 2048移动代码,2 的威力,Linux 的威力:终端中的 2048
  15. 导出android app安装包,Android app导出apk方法
  16. woocommerce-paypal-payments/modules/ppcp-button/src/Assets/SmartButton.php如何解决AVADA主题
  17. NVIDIA TensorRT (python win10)安装成功分享
  18. 微信小程序:40029错误(invalid code)
  19. SpringCloud Admin监控界面解释
  20. 盘点 8 款好用的 API 接口文档管理工具

热门文章

  1. 用JS操作FRAME中的IFRAME及其内容
  2. S9-魔方方法与模块
  3. FarmersWorld 农民世界—同时体验农耕乐趣和赚钱
  4. Python-冒泡排序函数
  5. Rocket MQ 问题集
  6. hive表信息查询:查看表结构、表操作、建表语句
  7. 股票自选股基本函数大全-1
  8. dir-612b虚拟服务器,D-Link DIR 612B路由器设置上网教程
  9. x86、x86-64、x64和amd64的区别(转)
  10. Onedrive如何同步文件夹