页面操作的流畅度:
在 PC 的 CPU 越来越牛逼、内存越来越大的时候,前端的代码复杂度也在上升。
以往我们都默认认为只要资源加载好了、只要资源加载快了那么我们的页面性能就是棒棒哒的,现在不再是这样。
这里涉及到两个问题:
PC 端的 CPU 性能、内存的性能虽然很高了,但是前端代码也更复杂了;除了 PC,还有无线端;
于是我们的性能指标多了一项:页面流畅度。
页面流畅度如何感知:
卡顿的感受会在很多地方出现,比如:
你在逛某个页面的时候愉快的的滚动鼠标滚轮,但是页面会突然的顿一下。
你在打开手机上直接访问 PC 页面(或者 H5 页面)的时候,发现浏览器就像死掉了一样。
卡顿就是这样的感觉,但是怎么来衡量这个卡顿的程度呢?
总不能让用户直接说吧,就像两个页面:有人开心的时候会说都很流畅,要是不开心的时候他会说两个都有点卡顿。这样的评价太主观了。
如何客观的度量页面卡顿程度:
首先要知道页面为什么会卡顿呢?看看浏览器里面的 Timeline;
一般我们要求页面要达到 60 FPS( 60 帧/秒)如果按照 60 FPS 计算,那么每一帧执行时间为 1/60s,也就是 16.7ms。
为什么页面会看起来比较卡:
浏览器的渲染是单线程的,在某一个时刻要么在进行 JS 运算,要么在进行 UI 渲染。不会同时进行。
如果我们的脚本在改变 UI 那么这个脚本的执行时间不要超过了 16.7ms,否则页面在这个周期中无法进行 UI 变化,那么看起来就是跳帧(卡顿)了。
如何采集页面卡顿的程度:
目前为止,我们已经知道了什么是卡顿、卡顿的发生原因、如何在 Chrome 中查看卡顿,接下来我们要想办法用 JS 获取页面的卡顿程度。
利用上述的原理:浏览器是单线程的,如果卡顿发生了那么后面队列堆积的方法就得不到执行。
假如我们配置一个定时器,每隔一段时间 t 就向浏览器的线程队列中丢一个方法进去:
如果线程队列是空闲的,那么我们理论上可以检查到我们的方式每次都是准时的间隔 t 被调用一次;如果线程队列是繁忙的,那么这个间隔时间将是大于 t 的;
试验方案有了。
var t = new Date();
setInterval(function(){
console.log(new Date() - t);
t = new Date();
}, 100);
接下来的事情是把这些数据收集起来,形成一个指标。这事情就好办多了:
统计页面一段时间的这些 t 值的和,可以计算出页面的拥堵程度,这个值理论上是和 CPU 的时间消耗成正比的,所以我们定义这个值为 CPU 消耗;
统计这些 t 值在什么时候开始归于平静,这个值也就是浏览器线程开始闲下来的时间,我们定义这个值为页面可操作时间;
统计一段时间这些 t 值超过某个阈值的次数,比如设置的间隔是 100ms,t 值过了 200 的次数和总次数的比。我们定义这个值为页面渲染的 CPU 占比;