导引:
近十年前端新技术层出不穷,令人目不暇接.道德经曰:万变不离其宗,极致用户体验一直是前端孜孜追求的目标,其中页面性能是一个和用户体验直接相关的因素,直接影响着公司的收入,因此做好页面的性能优化非常重要.但是另一方面,性能优化涉及面广,优化手段繁杂.从dns预加载到浏览器缓存优化,从组件异步和http管道复用,这么多方案多的让前端开发者无所适从,如何从这些令人眼花缭乱的方向中挑选出来适合自己项目使用的方案,颇费一番功夫.本篇文章试着从基本的浏览器渲染原理开始,找出项目性能瓶颈,找到合适优化方案,最终优化之.本文重点在如何找到性能问题,以及相关的优化思路,希望本篇文章能给有性能优化的Jser带来一点启示.
本篇文章的目录如下:
授之以鱼不如授之以渔.万丈高楼平地起,也先要有扎实的基础.好的基础能让后来的优化之路少些坎坷多些坦途.
性能优化本质上来说是让网页在浏览器或者其他类浏览器容器中运行的尽量快,那么了解网页在浏览器是怎么渲染的就至关重要.了解了浏览器是怎么一步步渲染出来网页的,方便接下来对各个主要节点进行观察,并找到性能瓶颈.
回到一个老生常谈的问题: 浏览器从输入url到页面渲染出来,经过了哪些过程?
从图上我们可以看出,大致经历了缓存查找、dns查找、 建立tcp、 发送http请求、 服务器处理并返回结果 、下载资源、 解析文档、 布局渲染等节点.如果我们可以取到每个重点的时间节点之间的耗费时间,我们就可以分析出来整个路径中的性能瓶颈,具体每个重要时间节点的时间如何算,请参阅本文的第二部分:找问题-性能测试指标
那么浏览器拿到资源之后是如何解析成用户看到的页面.下面详细介绍这部分内容.
了解浏览器渲染页面的过程,方便我们优化浏览器渲染html文档的性能.
html通过词法分析,语法分析成为解析树.css规则解析生成css规则树.二者再结合成渲染树,经过布局之后给浏览器绘制展示.那么为了提高性能,写出简单的css规则,布局合理不复杂,重复绘制少,那么页面的性能体验就会比较好.
浏览器解析文档的过程中,不光有样式代码,html文档,还有脚本资源的下载和解析会影响页面的性能.那么脚本是如何影响文档的加载,样式和脚本以及dom的解析三者之间有什么相互影响,这就涉及到浏览器的阻塞机制.
我们知道页面运转过程中有两个线程,一个js执行线程,一个是ui线程,因为js可能会操作dom,cssom来影响界面ui展示,为了数据安全,这两个线程互斥.
js引擎线程执行的时候,ui线程挂起,反之亦如此.
因此,在编译js的时候,dom的解析将停止.
又因为js可能会修改dom树,不能操作脚本之后的dom,因此为了逻辑时序正确,js下载也会阻塞dom解析.
因此我们得到下面两条结论.
结论1.JS脚本将阻塞HTML解析,必须等待脚本的下载和解析
结论2.JS解析应用前,CSS需要解析完毕
了解了页面是如何渲染的之后,我们只要找到关键的节点渲染花费的时间,把耗费时间多的瓶颈给解决掉,就完成了页面的性能优化.那么如何把页面的渲染过程给分割成合适的片段呢? 第一个想法就是,可以通过代码手动埋点的方式,把页面关键的节点时间记录下来.虽说可行,但是比较麻烦.w3c很早就提出了Performance接口,当前浏览器大多已经实现了此接口,借助于它我们能很方便计算各个关键节点的耗费时间.
整个过程分为了 前一个页面卸载、重定向、获取缓存、dns查找、建立tcp链接、请求与响应资源、加载页面资源、触发页面load事件等过程.
我们可以通过此接口可以很方便的计算各个重要节点的耗费时间.
首字节耗时: performance.timing.responseStart - performance.timing.navigationStart
tcp连接建立耗时: performance.timing.connectEnd - performance.timing.connectStart
页面加载耗时: performance.timing.connectEnd - performance.timing.navigationStart
首次可交互耗时: performance.timing.domInteractive - performance.timing.navigationStart
DNS查找耗时: performance.timing.domainLookupStart - performance.timing.domainLookupEnd
从这个关键时间点我们可以分析各个时间段的时间占比,我们很容易找出项目的优化着眼点.
从上面的时间我们能拓展出更丰富的性能评价标准,常见的性能评价标准有如下几个指标:
秒开率是1 秒之内打开页面的页面数 / 总页面加载数 的比率.
计算的时候一般取的是 domContentLoaded在一秒内的页面数除以页面的总pv的比率.
一般要求简单页面的秒开率在90%以上.
T90时间是统计意义上的概念.是指将所有指标值从小到大排序,位于90%分数位的值即T90.
为什么不全部数据的平均值,而要统计90%分数位? 是为了排除掉极端值对统一结果的影响.比如说99个资产只有10万美元的普通民众和600亿资产的比尔盖茨一起平均的化,大家的平均资产将达到60亿,这个数字反应不了实际的情况,因此通过排除掉10%的最高值,算出来平均资产10万美元才能反应出来真实的资产情况.
常见的T90值主要是三个:
上面的指标都有一些缺陷,在spa单页应用盛行的今天,页面加载完毕,可能页面上没有有意义的内容展示出来.因此首次绘制时间在某些时间对用户来说更有意义.
FP: 首次绘制,视觉上不同于导航前的页面内容,可通过 PerformanceObserver获取.
FSP: 首屏绘制时间,用户视野内的内容渲染完毕,owl可以自动计算并上传.
FCP: 首次内容绘制 dom第一位内容绘制的时间点,可能是文本,图片等,可通过 PerformanceObserver获取.
FMP: 首次主要内容绘制,比如说商品的信息,文章的内容,视频控件等等.可以用FSP来代替.
通过这些指标,我们可以综合判断出来到底我们页面的有哪些性能的问题.
限于篇幅,本篇暂时到此为止.下面还有讲解 定目标-决定修复哪些问题、 找原因-通过工具查找问题的具体原因、破瓶颈-性能优化手段等内容,明天继续.