首发于 迅雷前端
性能优化之组件懒加载: Vue Lazy Component 介绍

性能优化之组件懒加载: Vue Lazy Component 介绍

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


初始加载资源过多

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


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



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



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



问题分析



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

解决思路

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

组件化分治思想

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

加载优先级

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

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

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

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

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



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

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

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

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

如果在判断加载条件为假的时候,什么都不渲染,就会带来一系列问题:

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



骨架屏的作用有:

如何提升切换时的体验?

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

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

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

Vue组件懒加载方案介绍

项目Github地址: github.com/xunleif2e/vu

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

特性

安装和使用

用法



Props

Events

DEMO 1 超长页面懒加载

xunleif2e.github.io/vue

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

DEMO 2 延时加载

xunleif2e.github.io/vue



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

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

DEMO 3 自定义过渡效果

xunleif2e.github.io/vue



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

DEMO 4 webpack 分包

xunleif2e.github.io/vue



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

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

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

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

DEMO 5 特定视口内懒加载

xunleif2e.github.io/vue



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

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

应用效果

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

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

应用业务

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



优化后请求瀑布图

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



数据对比

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



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

后续性能优化方向

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

图片尺寸适配和压缩

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

预渲染

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

懒加载方案 ROADMAP

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


后记

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

最后欢迎大家通过提交 issue 或者 PR 的方式参与贡献,项目 Github 地址: github.com/xunleif2e/vu




玻璃钢生产厂家温州玻璃钢造型生产厂家酒泉玻璃钢装饰造型定做哈密玻璃钢花盆生产厂家滁州玻璃钢摆件生产厂家无锡不锈钢花盆生产厂家本溪玻璃钢天花吊顶厂家直销乐山玻璃钢花坛厂家阳泉玻璃钢人物雕塑多少钱株洲玻璃钢人物雕塑批发晋城玻璃钢家具厂家太原玻璃钢公仔雕塑哪家好汉中玻璃钢景观雕塑加工陕西玻璃钢树池坐凳定制湖州玻璃钢人物雕塑定制芜湖玻璃钢花钵批发湖州玻璃钢垃圾桶加工扬州玻璃钢浮雕定制山南玻璃钢前台绵阳不锈钢家具价格巴中玻璃钢花箱生产厂家安阳玻璃钢公仔雕塑厂家直销东营玻璃钢座椅厂营口玻璃钢坐凳厂佛山商业美陈定做惠州玻璃钢座椅厂家绥化玻璃钢家具公司徐州玻璃钢坐凳生产厂家济南玻璃钢雕塑定做西安玻璃钢餐桌椅生产厂家襄阳商业美陈价格香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化