前端性能优化,不得不提的就是这个首屏渲染优化
首屏渲染优化
其实更具体点,应该是:首次加载首屏渲染优化,原因是某些应用,比如微信有缓存机制,首次加载了,第二次进入都会先加载本地缓存。
言归正传,首屏渲染加载优化,其实通俗说起来就是:“刚进页面加载快点”。其实这话也很笼统,专业点来说,其实是有如下几个指标的:
- FP(全称“First Paint”,翻译为“首次绘制”)
- FCP(全称“First Contentful Paint”,翻译为“首次内容绘制”)
- FMP(全称“First Meaningful Paint”,翻译为“首次有效绘制”)
- LCP(全称“Largest Contentful Paint”) 表示可视区“内容”最大的可见元素开始出现在屏幕上的时间点。
- TTI(全称“Time to Interactive”,翻译为“可交互时间”) 表示网页第一次 完全达到可交互状态
有点专业,但其实配合英文也是挺好理解的
优化首屏渲染不外乎几个思考点:
- 减少首屏渲染的体积大小,尤其是SPA应用,不加处理往往体积都会比较大
- 减少首屏渲染从开始到可交互的时间
- 从开始到可交互的时间里,其实dom已经加载了,在这里可以进行一些UI上的渲染,让客户看得到页面变化,让客户感知到确实网站是在加载中的
第一二点在我的其他文章有详细赘述了基本的实现方案,不外乎是:nginx服务器配置、代码级别的优化比如代码分片、懒加载、CDN等
这里想主要讲的是第三点,即实现用户感知上的优化,从空白到有正确元素渲染的时间
现状
一般的SPA,从技术上决定了不加任何处理的情况下,现状是:
- FP到LCP,为首屏空白
- LCP到TTI,由于基本采用异步交互形式,此时页面基本会已经加载好了页面的所有元素
所以了,优化用户感知上的体验,这里主要是探讨
FP到LCP的这个短短的时间,虽然短,但是优化后,体验感知会更优(起码不是白屏一大段时间了吧,虽然实际上正常情况下,最多也才0.5s左右)
First Paint 到 Largest Contentful Paint
题外话
Light House评分
其实,基本上参考我之前的文章实现Nginx,懒加载/代码分片,CDN后,light house评分基本都能到90以上
而这里要探究的,是即使在这基础上,再次进行体验的优化,也就是所谓的"1s甚至更短时间"之内的事情
First Paint - First Contentful Paint
要处理这一部分,就需要理解一个前置背景知识
无论是Vue还是React,在脚手架搭建起来后,都是mount在html某个DOM上,以React 为例子:
create-react-app构建的项目public目录里的index.html会是这样的<body> <div id="root"></div> </body>
实际上项目里的index.js也是挂载在这个root元素上,也就意味着当该页面正确挂载所有js之前,都是渲染的空
<div id="root"></div>
html页面
有了上述的前置知识,是不是有想法了大家,其实说来也简单,就是在FP之前的事情我们决定不了(一定程度上,就是服务器加载基本html的速度)而FP之后到FCP之间这段时间,我们可以通过一些方法来展示内容给用户
比如,京东的H5,淘宝H5,知乎H5,都有对应初次loading的动画,一般是自家的Icon,有兴趣的话,网购的时候自己留意下
数据说话
image.png
如上图,约224ms左右,完成html资源的加载,相当于用户只等待了0.224s就看到页面有反应了,且此时的样子,是可以作为一个挺好的“广告时间”,比如加上自己家的logo等
如果有杠精说这个0.224s优化,那我就只能说:是不是值得投入人力物力去优化这个0.224s了,毕竟这涉及到DNS解析,网站服务器响应,网络路由等问题了
0.224s之前是白屏
0.224s之前.png
0.224s之后是预加载动画
0.224s之后.png
First Contentful Paint - Largest Contentful Paint
接下来就是FCP到LCP部分了,有一些聪明又爱偷懒的小伙伴肯定会想:其实就保持FP的预加载动画直到LCP就好啦。
说实话是可以的哈,但既然是在谈优化,就看“感知上”能怎么优化到最好吧。
之前有提到“代码分片/懒加载",其实可以做到:
预加载动画 --> 分片加载的suspend动画 --> LCP
此时当首屏加载的时候,会先加载预加载动画,然后加载代码分片的suspend动画,最后渲染真实需要的DOM
- 优势在于,在弱网环境下,用户可以感知得到页面在加载中而不是一个动画一直在load,安抚用户
分片加载的suspend动画一般可以用骨架屏来实现
224ms前224ms后
793ms后
990ms后
即:0.2s白屏 -> 0.6s预加载动画 -> 0.2s代码分片骨架屏动画,就完成了LCP
一份 Akamai 的研究报告,当时总共采访了大约 1048 名网上购物者,得出了这样的结论:
- 大约有 47% 的用户期望他们的页面在两秒之内加载完成。
- 如果页面加载时间超过 3s,大约有 40% 的用户选择离开或关闭页面。
回过头来看看我们的结果
如果不加预加载动画、分片代码骨架屏动画,从进入页面到展示内容,归总花了1s左右客户才能看到页面从白屏到有内容
加入后,只花了0.2s客户就看到页面有内容展示了(当然具体情况要看现实条件,此处为同一情况下浏览器实践数据)
网友评论