关于页面渲染的一些优化方案分享(懒加载、虚拟列表)

关于页面渲染的一些优化方案分享(懒加载、虚拟列表)

《工欲善其事,必先利其器》

关于页面渲染的一些优化方案分享(懒加载、虚拟列表)_第1张图片
(图片取自百度,侵删。)

关于前端性能优化,是我们老生常谈的一个知识点了。性能优化的概念非常多,诸如 FP(First Paint)FCP(First Contentful Paint)LCP(Largest Contentful Paint)TTI(Time To Interactive)TBT(Total Blocking Time) 等等。

但仅仅了解概念是不够的,实际工作上需要如何落地这些优化方案,对我们开发还是有着一定的难度,这也是前端进阶之路上必然需要经历的。否则你将永远无法晋升为中级/高级前端工程师。接下来我会就其中几点,发表一些自己的看法和优化方案。

我自认为我还是不成熟的,如果文中有地方描述的不正确的地方,我愿意接受大家的指正,也非常欢迎大家一起共同探讨更优的方案!

一、首屏渲染

首屏渲染 优化常用的手段是使用加载画面,待首屏加载完成之后,取消加载画面。这个功能的实现我们可以通过 Performance API 来获取其加载的时间,从而控制加载画面的显隐。

虽然它有存在的必要,但却并不是长久之计,当首页的网络请求很多时,为了用户的体验着想,我们可不能让用户的界面一直停在那里转圈圈哦。

当首页需要加载多个网络请求

采用分片请求加载数据

何为分片请求?例如首页总共有10个网络请求,我们没有必要等待10个网络请求全部加载完之后,再取消加载画面。

相反的,我们可以优先加载2个比较重要的网络请求,利用这2个网络请求,来控制加载画面。也就是说,相比于上面加载全部的网络请求,我只需要加载2个,这两个网络请求加载完成之后,取消加载画面,执行回调函数,继续请求其他网络请求。

采用可视区域加载数据

实际上,这个知识点是懒加载。利用这一点,我们可以实现:组件懒加载和内容的懒加载。

而关于如何实现懒加载,网络上也是五花八门。我这里总结了几个比较靠谱的实现方式,大家可以一起来看一看:

  • el.offsetTop - document.documentElement.scrollTop - T <= el.clientHeight。其中,变量 T 是前置高度,即如果你不想让视图滚动到区域顶部加载,而是提前多少像素高度加载;
  • el.getBoundingClientRect() 可以获取这个元素的长宽距离顶部等参数,计算的方式与上一条是相同的;
  • new IntersectionObserver() 交叉观察对象 API。如果两个对象交叉重叠了,就会执行回调函数。这种方式的好处就是可以不用监听滚动和元素对象,缺点是需要调整浏览器的兼容性。

关于页面渲染的一些优化方案分享(懒加载、虚拟列表)_第2张图片

  • 使用 vue-lazyload 插件。这款插件帮我们做了兼容,可以选择是否使用 IntersectionObserver。vue3 版本使用 vue-lazyload-next
  • 使用 vueuse 插件库。同 IntersectionObserver 一样,vueuse 也封装了这个 API,我们可以直接只用 useIntersectionobserver 实现可视区域交叉的判断。
采用划分布局权重优化

或许你听说过 “圣杯布局” ?还是听说过 “双飞翼布局” ?如果听说过那么使用它的意义又是什么?

关于页面渲染的一些优化方案分享(懒加载、虚拟列表)_第3张图片

由于 JavaScript 是单线程自上往下执行的,那么考虑到数据太多的情况下,加载的顺序会受到影响,我们需要先让 js 引擎加载重要的内容,因此就产生了圣杯布局和双飞翼布局。

如上图,我们实现布局权重时,需要把中间栏的代码块,放在左右部分的代码块之前,就能稍微提升用户的使用体验。

采用 script 标签的 async、defer 属性

所有 script 标签会严格按照他们在网页中出现的次序被解析。而使用 defer 属性可以把脚本推迟到文档渲染完毕之后再执行,相反 async 属性则是异步加载,两者作用不同。但对于单页面应用用处不大,因为单页面应用一般是通过 script 标签引入 JavaScript 来渲染 DOM 的。

二、列表渲染

列表渲染常用的优化方式是分片渲染,也就是分页。

属于数量不定的叠加网络请求

DOM 结构简单,数据量不多,采用分片渲染+图片懒加载+骨架屏

关于页面渲染的一些优化方案分享(懒加载、虚拟列表)_第4张图片

就像掘金网站采用的优化方案,分片渲染+图片懒加载+骨架屏。图片懒加载的作用是列表翻页之后,图片加载过慢时代替的方案;而骨架屏:一是为了用户进入网站时加载过慢的首屏优化(其实就是加载动画);二是防止用户滚动速度过快而产生的空白断层,从而提升用户体验。

DOM 结构复杂,数据量极多,采用虚拟列表+骨架屏或模拟滚动条

注意,懒加载和虚拟列表是不同的概念和方案,不能混为一谈。前者更多的是防止由网络不稳定情况导致的用户体验问题,而后者更多的是防止 DOM 渲染过度的性能问题导致用户的体验问题,两者的侧重点不同。

关于页面渲染的一些优化方案分享(懒加载、虚拟列表)_第5张图片
(图片取自百度,侵删。)

在实际的工作中,列表项必然不会仅仅只由一个 li 标签组成,必然是由复杂 DOM 节点组成的。那么可以想象的是,当列表项数过多并且列表项结构复杂的时候,同时渲染时,会在 Recalculate Style 和 Layout 阶段消耗大量的时间。

而虚拟列表就是解决这种问题的一种方案,即只对可见区域进行渲染,对非可见区域中的数据不渲染或部分渲染的技术,从而达到极高的渲染性能。

如上图,假设有1万条记录需要同时渲染,我们屏幕的可见区域的高度为500px,而列表项的高度为50px,则此时我们在屏幕中最多只能看到10个列表项,那么在首次渲染的时候,我们只需加载10条即可。

考虑到成千上万条复杂的 DOM 节点形成的列表,必然会导致浏览器的重绘,消耗的性能无法估量。因此,当滚动发生时,虚拟列表将动态的通过计算获得可视区域内的列表项,并将非可视区域内存在的列表项删除。

骨架屏也是为了防止用户滚动过快而导致的页面空白断层,而防止这一种现象的产生可以使用模拟滚动条,控制用户的滚动速度,来间接的提升用户的体验。

三、图片渲染

属于网页的重要元素之一

采用图片懒加载

关于页面渲染的一些优化方案分享(懒加载、虚拟列表)_第6张图片

如上图,当网页中图片加载过慢时,我们可以使用一张前置静默图片来代替图片的加载的空白期,从而提升用户体验(其实也就是我们上面提到的可视区域加载)。可以是网站的标志性图片,也可以是标志性动图,大部分是使用 loading 动画。

当然,当图片加载失败时,我们也可以使用 其他图片代替,这也能稍微提升用户体验。

四、总结

用户体验要考虑的地方实在是太多啦,目前我学习到的仅仅是以上一些比较常用的知识点,后续会继续学习,继续分享,本篇文章到此就完结了,非常感谢你的阅读!

希望你的未来一片光明。

你可能感兴趣的:(javascript,前端,javascript)