性能优化-网页加载耗时数据的搜集

时间:2021-08-20 21:14:22

最近需要针对现有的一些线上产品,进行优化工作。首先得对这些产品的性能做一个统计,找出目前问题最严重的,优先进行改进。前面我都是通过在自己本地电脑上测试,利用诸如YSLOW、PageSpeed之类的工具来检测性能。但是通过这些方法,得到的结果都是比较理想的,没有并发因素,网络也因为是内网环境,非常给力,每个产品体现出来都还挺快。因此最终还是决定搜集用户端真实的页面加载耗时来作为参考标准。

在考虑如何搜集用户端数据的过程中,一开始,是准备在页面上通过JS进行埋点,类似这种方式:

<script>
T = T || {};
T.beforeHead = new Date().getTime();
</script>

在页面的不同点记录时间戳,最终在load完成后,统计发送到服务端进行分析。但是搜索了网上的资料,发现这种形式存在一些弊端:

1.这会驱使JS引擎比平时更早的加载
2.让HTML和JS的解析器频繁更换上下文
3.嵌入的JS代码片段会阻塞剩余资源的加载
4.不能捕获到网络延迟的时间消耗(服务器到客户端的这一个时间消耗)
5.new Date().getTime()在各个浏览器中,平均耗时为7.5ms,你的应用越简单,那么这个时间消耗对你性能测试结果的影响就会越大
6.这种埋点方式也增加了性能测试的工作量,因为你需要花费额外的时间来维护这些JS片段
 
由于需要测试的产品有多个,理想的情况是自己写一个脚本,然后每个产品页面引入一下,自动完成这部分工作。有鉴于上述几个因素,又经过网上的一些搜索,发现了雅虎前端编写的一个性能统计工具:BOOMERANG,利用这个工具可以自动的完成页面加载时间的统计。它提供的统计项比较多,由于我们需要用到的功能只有前端整个页面的加载耗时,因此我从其源码中把该功能摘录了出来,实现的原理是利用W3C提供的Navigation Timing API来获取打开页面时的时间戳,然后当页面load完成后,通过new Date().getTime()获取时间戳,两者相减极为页面加载的完整时间。注意目前仅IE9、Chrome6+浏览器实现了该API。下面是获取页面打开时间戳的代码:
var _initStartTime = function () {
	var performance, startTime = false;
	performance = window.performance || window.msPerformance || window.webkitPerformance || window.mozPerformance;

	if (performance && performance.timing && performance.timing.navigationStart) {
		startTime = performance.timing.navigationStart;
	// Chrome Browser	
	} else if(window.chrome && window.chrome.csi && window.chrome.csi().startE) {
		startTime = w.chrome.csi().startE;
	// The Google Toolbar exposes navigation start time similar to old versions of chrome	
	// This would work for any browser that has the google toolbar installed	
	} else if(window.gtbExternal && window.gtbExternal.startE()) {
		startTime = window.gtbExternal.startE();
	}
	// 解决火狐7.8的bug
	if (navigator.userAgent.match(/Firefox\/[78]\./)) {
		this.navigationStart = performance.timing.unloadEventStart || performance.timing.fetchStart || undefined;
	}
	
	return startTime;
};

通过这种方式,就可以得到较为准确的耗时数据了。

在内网环境我自己电脑上,测试产品C的页面耗时均值约为1秒;而通过上面的方法,统计线上用户端的时间消耗均值,约为4秒。两者差异相当大,可见我们的产品优化潜力还是非常大的。