[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿

迎接人人收看聊一聊系列,这一套系列文章,能够协助前端工程师们相识前端的各个方面(不仅仅是代码):

https://segmentfault.com/blog/frontenddriver

上一篇文章我们议论了,怎样举行前端日记办理统计:

https://segmentfault.com/a/1190000005861012

这一篇我们来看看怎样举行速率统计

网站的速率影响了用户接见网站最初的体验。试想,假如一个用户,在等待了多少秒后,照样停留在白屏的状态,那末他的挑选将是脱离这个网站。机能统计有助于帮我们检测网站的用户体验。

这里援用百度百科中的一句话 —- 平常一个网站,假如首屏时候在2秒之内是比较优异的,5秒之内是能够吸收的,5秒以上就不可容忍了。用户会挑选革新页面或马上脱离。

这里,有些数据须要与人人分享一下(来自FEX的统计):

产物机能收益
Google耽误 400ms搜刮量下落 0.59%
Bing耽误 2s收入下落 4.3%
Yahoo耽误 400ms流量下落 5-9%
Mozilla页面翻开削减 2.2s下载量提拔 15.4%
Netflix开启 Gzip机能提拔 13.25%带宽削减50%

能够看到,速率,关于一个网站来说,主要性可见一斑。

1、网站都有哪些目标?

1.1 首屏时候

这个目标关于大多数网站来说,异常主要。那末何为首屏时候呢?援用百度百科里的一句话,就是:

网站用户体验的一个主要目标。 指一个网站被浏览器如IE窗口上部800*600的地区被充溢所需时候。

实在就是你的网页刚进入时,衬着完全部浏览器屏幕的时候。

关于是不是包含首屏一切的图片下载完成。这个网上有些争议,有的同砚说不包含图片,只需DOM+款式 都衬着完了,就算完成了。

笔者以为,既然是首屏,那末首屏上一切的东西都加载完成,让用户感觉不到另有没完成的部份,就算完成了。

所以,综合一下,我们的首屏时候,包含首屏的DOM元素的衬着,展如今用户第一屏幕的一切图片都完成。

实在Chrome供应开发着搜检网站全部衬着历程的小公举,哦不,是小东西(如图1.1.1所示)在F12开发者东西的Network面板内里:

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图1.1.1

这个是屏幕捕捉的东西,能够看到全部网页的衬着历程。我们接着来穷究一下上述哪一个时候点是首屏时候点。

我们来一同看看百度首页的首屏状态,因为百度首页加载比较快,所以这里我们模仿一下3G网的耽误(如图1.1.2):
《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图1.1.2

我们看到,虽然在240ms的时候,网页算是被衬着出来了,然则照样有许多空缺的处所。

279MS的时候,虽然框架都被衬着完成了,DOM与款式也都衬着完成了,然则我们看到图片还不完全,所以,固然也不算首屏完成了。

有的同砚会说,318ms的时候,总算完成了吧,nonono,我们向后视察,就会发明另有一些元素会再被衬着出来。也就是说晓得稳固之前,我们都不能算首屏完成了。

晓得487 ms的时候,页面才算加载完成了。而且以后不会再发作页面的抖动了。

看完这些,置信智慧的你内心已有数了,什么是首屏时候。

1.2 白屏时候

    这个实在不多说,读者也邃晓,就是页面处于空缺的时候。页面空缺,用户就会烦躁,而且变得不耐心。影响白屏时候的多数是:DNS剖析耗时+效劳端耗时+收集传输耗时。

1.3 用户可操作时候

    望文生义,这项目标值得是,我们的网页用户能够运用的时候。平常来说 domready时候,就是我们的用户可操作时候了。

1.4 总下载时候

    平常指,页面整体的下载时候,一切的页面资本都下载完成。

1.5 自定义目标

    因为营业差别,站长们所体贴的时候必定也差别了。比方你多是一个电商网站的站长,你体贴你的第一屏商品究竟展现的有多快( 平常这会带来更多的收入),所以,你须要监控你的商品展现的时候。

2 怎样统计本身网站的这些目标

假如并不想要花费精神在这些统计上,只是要小小的关注一下的话,固然能够本身翻开控制台,在页面的各个阶段,将时候打印出来,亦或许是运用html5新增的接口:performance来评价一下本身的网站究竟差在那里(如图2.0.1)。
《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.0.1

然则,你的测试并不能代表一切的用户的状态。而且,你须要一个监控顺序,去时候提醒着你,如今你的网站的速率处于什么状态。

    所以,关于有寻求一些的站长而言,笔者在这里更发起采纳用户日记,即,在本身网站的代码中,增添统计,并把统计效果发送到效劳器。在效劳器收集这些日记,并发生一个监控的网站。实在大可不必运用一些付费的效劳,我们本身就可以够轻轻松松的做一个简答的速率监控效劳。

    在本文的第三节,我们将会一同做一个小的速率监控效劳的例子。许多站长以至能够拿过来直接运用。接下来,我们照样针对之前我们提到过的几个目标,注重解说统计要领:

2.1 怎样统计首屏时候

    实在,关于网页高度小于屏幕的网站来说,统计首屏时候异常的简朴,只需在页面底部加上剧本打印当前时候即可,或许关于网页高度大于一屏的网页来说,只需在预算接近于一屏幕的元素的位置后,打印一下当前时候即可。

    比方,如今你有一个简朴的网页(如图2.1.1所示):

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
    </head>
    <body>
        <div>这是第一屏,这是第一屏</div>
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <div>第一屏末端,第一屏末端</div>
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
    </body>
</html>

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.1.1

我们须要统计首屏时候的话,则须要定义一个基准,就是–什么时候用户点开的当前网页,HTML5的performance接口供应了这个时候:performance.timing.navigationStart,这个就是用户接见我们网页最最先的跳转时候了。

<head>
    <script type="text/javascript">
        window.logInfo = {};
        window.logInfo.openTime = performance.timing.navigationStart;
    </script>
</head>

我们在页面开首处,将基准记下。

接下来,在约莫的首屏处加上我们的统计:

<div>第一屏末端,第一屏末端</div>
<script type="text/javascript">
    window.logInfo.firstScreen = +new Date() - window.logInfo.openTime;
    console.log('首屏时候:', window.logInfo.firstScreen + 'ms');
</script>

我们再来看看我们的页面(如图2.1.2所示):
《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.1.2

便有了首屏时候。

霸特,霸特。同砚们不要冲动的太早。我们这个首屏时候,并不没有算上图片。所以,我们得把首屏中一切图片的加载时候也算上。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
        <script type="text/javascript">
            window.logInfo = {};
            window.logInfo.openTime = performance.timing.navigationStart;
        </script>
    </head>
    <body>
        <div>这是第一屏,这是第一屏</div>
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <div>第一屏末端,第一屏末端</div>
        <script type="text/javascript">
            (function logFirstScreen() {
                var images = document.getElementsByTagName('img');
                var iLen = images.length;
                var curMax = 0;
                var inScreenLen = 0;
                // 图片的加载回调
                function imageBack() {
                    this.removeEventListener
                    && this.removeEventListener('load', imageBack, !1);
                    if (++curMax === inScreenLen) {
                        // 假如一切在首屏的图片均已加载完成了的话,发送日记
                        log();
                    }   
                }   
                // 关于一切的位于指定地区的图片,绑定回调事宜
                for (var s = 0; s < iLen; s++) {
                    var img = images[s];
                    var offset = {
                        top: 0
                    };
                    var curImg = img;
                    while (curImg.offsetParent) {
                        offset.top += curImg.offsetTop;
                        curImg = curImg.offsetParent;
                    }
                    // 推断图片在不在首屏
                    if (document.documentElement.clientHeight < offset.top) {
                        continue;
                    }
                    // 图片还没有加载完成的话
                    if (!img.complete) {
                        inScreenLen++;
                        img.addEventListener('load', imageBack, !1);
                    }
                }
                // 假如首屏没有图片的话,直接发送日记
                if (inScreenLen === 0) {
                    log();
                }
                // 发送日记举行统计
                function log () {
                    window.logInfo.firstScreen = +new Date() - window.logInfo.openTime;
                    console.log('首屏时候:', window.logInfo.firstScreen + 'ms');
                }
            })();
        </script>
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
    </body>
</html>

以上封装的首屏时候函数,无依靠比较玲珑,同砚们能够直接运用于本身的项目中。如许,我们就轻轻松松的统计到了首屏时候。

2.2 怎样统计白屏时候

    能够在页面的head底部增加的JS代码来统计白屏时候,虽然如许做能够并不非常精准,然则也能够基础代表了首屏时候,如图2.2.1所示。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
        <script type="text/javascript">
            window.logInfo = {};
            window.logInfo.openTime = performance.timing.navigationStart;
            window.logInfo.whiteScreenTime = +new Date() - window.logInfo.openTime;
            console.log('白屏时候:', window.logInfo.whiteScreenTime + 'ms');
        </script>
    </head>

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.2.1

2.3 怎样统计用户可操作时候

    前面提到过document.ready实在就可以够算作我们的用户可操作时候啦。我们无妨直接尝尝,如图2.3.1所示:

document
.addEventListener(
    'DOMContentLoaded',
    function (event) {
        window.logInfo.readyTime = +new Date() - window.logInfo.openTime;
        console.log('用户可操作时候:', window.logInfo.readyTime);
    }
);

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.3.1

2.4 怎样打印总下载时候

    页面整体下载时候,运用window.onload即可,这能够协助我们看看我们一切的资本是不是拖慢网页,如图2.4.1所示:

window.onload = function () {
    window.logInfo.allloadTime = +new Date() - window.logInfo.openTime;
    console.log('总下载时候:', window.logInfo.allloadTime + 'ms');
};

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.4.1

2.5 一致打印时候,更轻易

    我们将上述的统计兼并,一个完全的统计就出来了,如图2.5.1所示:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0">
        <script type="text/javascript">
            window.logInfo = {};
            window.logInfo.openTime = performance.timing.navigationStart;
            window.logInfo.whiteScreenTime = +new Date() - window.logInfo.openTime;
        </script>
    </head>
    <body>
        <div>这是第一屏,这是第一屏</div>
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <div>第一屏末端,第一屏末端</div>
        <script type="text/javascript">
            (function logFirstScreen() {
                var images = document.getElementsByTagName('img');
                var iLen = images.length;
                var curMax = 0;
                var inScreenLen = 0;
                // 图片的加载回调
                function imageBack() {
                    this.removeEventListener
                    && this.removeEventListener('load', imageBack, !1);
                    if (++curMax === inScreenLen) {
                        // 假如一切在首屏的图片均已加载完成了的话,发送日记
                        log();
                    }
                }   
                // 关于一切的位于指定地区的图片,绑定回调事宜
                for (var s = 0; s < iLen; s++) {
                    var img = images[s];
                    var offset = {
                        top: 0
                    };
                    var curImg = img;
                    while (curImg.offsetParent) {
                        offset.top += curImg.offsetTop;
                        curImg = curImg.offsetParent;
                    }
                    // 推断图片在不在首屏
                    if (document.documentElement.clientHeight < offset.top) {
                        continue;
                    }
                    // 图片还没有加载完成的话
                    if (!img.complete) {
                        inScreenLen++;
                        img.addEventListener('load', imageBack, !1);
                    }
                }
                // 假如首屏没有图片的话,直接发送日记
                if (inScreenLen === 0) {
                    log();
                }
                // 发送日记举行统计
                function log () {
                    window.logInfo.firstScreen = +new Date() - window.logInfo.openTime;
                }
            })();
            document
            .addEventListener(
                'DOMContentLoaded',
                function (event) {
                    window.logInfo.readyTime = +new Date() - window.logInfo.openTime;
                }
            );
            window.onload = function () {
                window.logInfo.allloadTime = +new Date() - window.logInfo.openTime;
                var timname = {
                    whiteScreenTime: '白屏时候',
                    firstScreen: '首屏时候',
                    readyTime: '用户可操作时候',
                    allloadTime: '总下载时候'
                };
                for (var i in timname) {
                    console.log(timname[i] + ':' + window.logInfo[i] + 'ms');
                }
            };
        </script>
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
        <img src="http://static.oschina.net/uploads/space/2016/0623/152644_6UUC_1177792.png">
    </body>
</html>

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.5.1

按照上一节( https://segmentfault.com/a/1190000005861012 )所说,我们将这个日记发送到效劳端去。

var logStr = '';
for (var i in timname) {
    logStr += '&' + i + '=' + window.logInfo[i];
}
(new Image()).src = 'http://localhost:8091/?action=speedlog' + logStr;

开启我们的nginx监听,并在效劳端吸收这条日记如图2.5.2,图2.5.3所示:

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.5.2

《[聊一聊系列]聊一聊前端速率统计(机能统计)那些事儿》
图2.5.3

我们看看日记内里是不是是已多了一条了呢?

如果再加以定时使命,日记收集等功能的辅佐,我们就可以及时控制本身网站的机能啦。

不要走开,请关注我。下一章,我们将继承聊聊百度挪动版首页那些事。

https://segmentfault.com/a/1190000005882953

后续,我们也会一同来聊聊,怎样优化我们的这些速率,以进步我们的网站机能。

原创文章,版权一切,转载请说明出处

    原文作者:侯医生
    原文地址: https://segmentfault.com/a/1190000005869953
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞