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

欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码):

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://www.cnblogs.com/homehtml/p/12629612.html

时间: 2024-08-26 04:42:50

[聊一聊系列]聊一聊前端速度统计(性能统计)那些事儿的相关文章

[聊一聊系列]聊一聊前端功能统计那些事儿

欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码):https://segmentfault.com/blog... 1. 什么是功能统计 作为一名开发,我们的产品发布出去之后,无论是产品还是运营,其实都是想及时了解产品对用户产生的影响的.用户到底喜欢什么不喜欢什么.但是如果拉住用户去一个个问的话,也无法得到最真实的大众的想法.于是,运用大数据进行分析,就变成了产品们的利器. 那么这些反映了用户真实行为的数据,就得靠前端工程师们来打印了. 比如,你想看

[聊一聊系列]聊一聊前端存储那些事儿

https://segmentfault.com/a/1190000005927232 欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码):https://segmentfault.com/blog/frontenddriver 在web开发越来越复杂的今天,前端拥有的能力也越来越多.其中最重要的一项莫过于web存储.开发者们如果使用得当,这些存储可以帮助我们提升网页的性能与灵活度.本文不讲个中的细节,只讲各种前端存储的利弊,与各类存储的应用场景.毕竟

atitit.提升备份文件复制速度(1) -----分析统计问题and解决方案

atitit.提升备份文件复制速度(1) -----分析统计问题and解决方案 1. 现在的情形 1 2. 硬盘信息 大概50mb/s, 50iops 1 3. 统计小的文件比率 2 4. 复制速度估计.. 2 5. 小文件类型比率按照扩展名 2 6. 速度慢的原因:::iops太低的... 4 7. 解决之道::: 4 7.1. 提升到ssd 硬盘. 4 7.2. 清理垃圾 4 7.3. 清理重复文件 5 7.4. 移动pic/isho文件.. 5 7.5. 打包文件.. . 5 8. 清理后

Windows系统CPU内存网络性能统计第一篇 内存

最近翻出以前做过的Windows系统性能统计程序,这个程序可以统计系统中的CPU使用情况,内存使用情况以及网络流量.现在将其整理一下(共有三篇),希望对大家有所帮助. 目录如下: 1.<Windows系统CPU内存网络性能统计第一篇 内存> 2.<Windows系统CPU内存网络性能统计第二篇 CPU> 3.<Windows系统CPU内存网络性能统计第三篇网络流量> 本篇将介绍统计系统内存使用情况,包括内存使用率.总物理内存大小.可用物理内存大小.总虚拟内存大小,可用虚

Windows系统CPU内存网络性能统计第二篇 CPU CPU整体使用率

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 本文配套程序下载地址为:http://download.csdn.net/detail/morewindows/5160810 转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/8678359 欢迎关注微博:http://weibo.com/MoreWindo

Windows系统CPU内存网络性能统计第四篇 CPU 多核CPU各核使用率C++

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/8678396 欢迎关注微博:http://weibo.com/MoreWindows Windows系统CPU内存网络性能统计第四篇 CPU多核CPU各核使用率 C++ http://blog.csdn.ne

前端工程与性能优化

每个参与过开发企业级 web 应用的前端工程师或许都曾思考过前端性能优化方面的问题.我们有雅虎 14 条性能优化原则,还有两本很经典的性能优化指导书:<高性能网站建设指南>.<高性能网站建设进阶指南>.经验丰富的工程师对于前端性能优化方法耳濡目染,基本都能一一列举出来.这些性能优化原则大概是在 7 年前提出的,对于 web 性能优化至今都有非常重要的指导意义. 然而,对于构建大型 web 应用的团队来说,要坚持贯彻这些优化原则并不是一件十分容易的事.因为优化原则中很多要求与工程管理

论前端设计中性能的重要性

前端性能的重要性 在我的web开发生涯里,大部分时候我都是作为一个后台工程师.这样一来,我投入了非常多的精力去研究.练习如何通过后台优化来提升项目产品的性能,诸如编译器选项,数据库索引,内存管理等.很多书都花大量篇幅来讲述如何在这些方面提高性能,很多人也进而在这方面的优化花了大量时间.说实话,很多WEB网页,真正花费在web服务器到终端用户的时间其实往往不超过整个响应时间的一两成.如果你真的想极大幅度地减少web页面的响应时间,你应该把注意力放在真正影响终端用户体验的另外八九成的内容上.那这80

web前端开发教程系列-2 - 前端开发书籍分享(转)

目录: 前言 一. CSS 二. JavaScript 三. jQuery 四. 后记 前言 前端书籍在每个商城或书架上面都是琳琅满目,很多初学者又不能很好的判断书的质量或层次.因为今天给同学们分享一下,看书主要是两个方面,一个是层次性,一个是持续性.阅读是一件快乐的事情,要持续的浇灌,希望之田才会长青不衰. 一. CSS css的书大多是停留在基础普及,就是介绍Css基础概念的居多. 下面列举几个,有的可能已经绝版了,只能看到电子版了. CSS网站布局实录  这本是出现比较早的css书籍,现在