1、chrome开发者工具-Performance面板

chrome浏览器右键检查元素即可打开谷歌开发者工具面板,但是常用的可能是Element、Console、Source三个面板的功能,其余面板还有:Network、Performance、Memory、Application、Security、Audits等。

chrome监控点击按钮后调用哪个方法 chrome监控网页_帧率


这些按钮的功能如下:

* Elements: 查找网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能实时在浏览器里面得到反馈。

* Console: 记录开发者开发过程中的日志信息,且可以作为与JS进行交互的命令行shell。

* Sources: 断点调试JS。

* Network: 从发起网页页面请求Request后,分析HTTP请求后得到的各个请求资源信息(包括状态、资源类型、大小、所用时间等),可以根据这个进行网络性能优化。

* Performance: 记录并分析网站的生命周期内所发生的各类事件,以此可以提高网页的运行时间的性能。

* Memory: 可以查看Performance所能提供的更多信息。

* Application: 记录网站加载的所有资源信息,包括存储数据(LocalStorage、SessionStorage、InedxedDB、WebSQL、Cookie),缓存数据,字体,图片,脚本,样式等。

* Security: 判断当前网页是否安全。

* Audits: 对当前网页进行网络利用、网页性能方面的诊断,并给出一些优化建议。比如列出所有没有用到的css文件等。

关于各面板的详细使用情况,可以参考博客:

chrome开发者工具详解

2、如何监控网页卡顿

要监控网页卡顿,必须从FPS说起。

FPS是来自视频或者游戏里的概念,即每秒的帧数,代表视频或游戏的流畅度,俗话说,就是‘不卡’。

那么在前端开发领域,什么是网页的FPS呢?

网页内容在不断变化之中,网页的FPS是浏览器在渲染这些变化时的帧率,帧率越高,用户感觉网页越流畅,反之则会感觉卡顿。

* 1、在chrome中可以通过开发者工具的performance面板查看网页的FPS(具体操作情况可点击1中的链接):

chrome监控点击按钮后调用哪个方法 chrome监控网页_chrome监控点击按钮后调用哪个方法_02


绿色的直方图即代表在页面重新绘制时的帧率,Frames为每一帧渲染所花的时间。

通过render里的FPS paint,可以查看当前网页更新时的FPS具体数值:

chrome监控点击按钮后调用哪个方法 chrome监控网页_网页卡顿与崩溃_03


最优的帧率是60,即16.5ms左右渲染一次。

*2、FPS extension是Chrome的一个扩展,可以显示当前网页的FPS值,即页面是否卡顿。

这种工具获取页面FPS的方式与浏览器自身给出的方式不同,没有采用浏览器原生的API(正在制定),这类工具独辟蹊径,通过浏览器的requestAnimationFrame API(可以使用setInterval polyfill)来实现。

代码类似:

var lastTime = performance.now();
var frame = 0;
var lastFrameTime = performance.now();
var loop = function(time) {
    var now = performance.now();
    var fs = (now - lastFrameTime);
    lastFrameTime = now;
    var fps = Math.round( 1000/fs );
    frame++;
    if(now > 1000 + lastTime){
        var fps = Math.round((frame*1000) / (now-lastTime)); //计算时间达到一秒后的帧数
        frame = 0; //清零
        lastTime = now; //重新计算下一秒的帧数
    };
    window.requestAnimationFrame(loop);
}

(代码摘自淘宝前端团队的《无线性能优化:FPS测试》)
通俗的解释就是,通过requestAnimationFrame API 来定时执行一些JS代码,1s中frame无法达到60帧,即可间接地反映浏览器的渲染帧率。关于requestAnimationFrame API的细节,可以参看文档MDN文档
如何监控网页卡顿
监控目的: 比如在全民直播时,我们必须重视用户的观看体验。所以任何网页或者播放器必须监控起来,以此指导优化,避免卡顿的出现。
方式: 以全民直播为例,使用FPS extension类似的方式(写一段JS循环运行达到监控目的),每秒中计算一次网页的FPS值,获得一列数据:
…6,8,11,23,25,35,44,50,39,34,…
然后通过通用的日志通道,上报到大数据平台进行分析即可。
那如何通过FPS确定网页存在卡顿呢?
观察结论:连续出现3个低于20的FPS 即可认为网页存在卡顿。
通过这种方式,得到了网页卡顿的统计数据,接下来,针对卡顿的问题,在有数据支持的情况下进行网页优化。
内容来源:知乎寸志,感谢作者分享!

3、如何监控网页崩溃

1、崩溃和卡顿的区别
卡顿也就是网页暂时响应比较慢,JS可能无法及时执行,这也是检测网页卡顿所依赖的技术点。
但崩溃就不一样了,网页都崩溃了,页面看不见了,JS无法运行,还有什么办法可以监控网页的崩溃?并将网页的崩溃上报呢?
2、基于Service Worker的崩溃方案统计
随着PWA概念的流行,大家对Service Worker也逐渐熟悉起来。基于以下原因,我们可以使用Service Worker来实现网页崩溃的监控:
*1、Service Worker有自己独立的工作线程,与网页区分开,网页崩溃了,Service Worker一般情况下不会崩溃;
*2、Service Worker生命周期一般比网页还要长,可以用来监控网页的状态;
*3、网页可以通过**navigator.serviceWorker.controller.postMessage**API向掌管自己的SW发送消息。
基于以上几点,我们可以实现一种基于心跳检测 的监控方案:
*P1:网页加载后,通过**postMessage**API每5s给sw发送一个心跳,表示自己在线,sw将在线的网页登记下来,更新登记时间;
*P2:网页在beforeunload时,通过**postMessage**API告知sw自己已经正常关闭,sw将登记的网页清除;
*P3:如果网页在运行的过程中crash了,sw中的running状态将不会被清除,更新时间停留在崩溃前的最后一次心跳;
*P4:Service Worker每10s查看一遍登记中的网页,发现登记时间已经超出了一定时间(比如15s),即可判定该网页crash了。
一些简化后的测试代码,供参考:

if(navigator.serviceWorker.controller !== null){
    let HEARTBEAT_INTERVAL = 5 * 1000;//每5s发一次心跳
    let sessionId = uuid();
    let heartbeat = function () {
        navigator.serviceWorker.controller.postMessage({
            type: 'heartbeat',
            id: sessionId,
            data: {} //附加信息,如果页面crash,上报的附加数据
        });
    }
    window.addEventListener('beforeunload',function() {
        navigator.serviceWorker.controller.postMessage({
            type: 'unload',
            id: sessionId
        });
    });
    setInterval(heartbeat,HEARTBEAT_INTERVAL);
    heartbeat();
}
  • sessionId: 本次页面会话唯一的id;
  • postMessage: 附带一些信息,用于上报crash需要的数据,比如当前页面的地址等。
const CHECK_CRASH_INTERVAL = 10*1000; //每10s检查一次
const CRASH_THRESHOLD = 15 * 1000; //超过15s没有心跳则认为已经crash
const pages = {}
let timer
function checkCrash() {
    const now = Date.now()
    for ( var id in pages){
        let page = pages[id]
        if((now-page.t)>CRASH_THRESHOLD) {
            //上报 crash
            delete pages[id]
        }
    }
    if(Object.keys(pages).length == 0) {
        clearInterval(timer)
        timer = null
    }
}
worker.addEventListener('message', (e)=>{
    const data = e.data;
    if(data.type === 'heartbeat'){
        pages[data.id] = {
            t: Data.now()
        }
        if(!timer){
            timer = setInterval(function(){
                checkCrash()
            },CHECK_CRASH_INTERVAL) 
        }
    }else if(data.type === 'unload'){
        delete pages[data.id]
    }
})

方案的可行性
* **1、兼容性**Service Worker的普及率已经相当高了,鉴于国内各种浏览器都是Chrome内核,而且版本已经在Chrome45以上,已经覆盖了相当一部分用户。作为监控,数据覆盖大部分就好。
* 2、可靠性
相比于利用window对象的load与beforeunload事件实现网页崩溃的监控,利用service Worker更加可靠。
在页面加载时(load事件)在sessionStorage记录good_exit状态为pending,如果用户正常退出(beforeunload事件),good_exit状态改为true,如果页面crash了,good_exit状态依然为pending,在用户第二次访问网页的时候(第2个load事件),查看good_exit的状态,如果仍然是pending,就可以断定上次访问网页崩溃了。
代码:

window.addEventListener('load', function() {
    sessionStorage.setItem('good_exit', 'pending');
    setInterval(function(){
        sessionStorage.setItem('time_before_crash', new Date().toString());
    },1000);
});
window.addEventListener('beforeunload',function() {
    sessionStorage.setItem('good_exit','true');
});
if( sessionStorage.getItem('good_exit') && sessionStorage.getItem('good_exit')!== 'true'){
    /*insert crash logging code here*/
    alert('Hey,welcome back from your crash, looks like you crashed on: ' +sessionStorage.getItem('time_before_crash'));
}

这个方案的问题所在之处:
1、采用sessionStorage存储状态,但通常网页崩溃/卡死后,用户会强制关闭网页或者索性重新打开浏览器,sessionStorage存储的状态将不复存在。
2、如果将存储状态在localStorage甚至Cookie中,如果用户先后打开多个网页,但不关闭,good_exit存储的一直都是pending,那么,每有一次网页打开,就会有一个crash上报。