前端页面加载速度的优化是一个系统性的工程,包括常见资源合并压缩、静态资源请求多域名化、CDN等。用户请求显示一个网页的详细过程也是十分复杂,包括DNS解析、建立TCP连接、加载HTML以及静态资源、渲染页面dom结构等多个阶段,任何一个阶段出现瓶颈都会影响用户体验,我们如何在真实的用户环境中准确的统计各个阶段的耗时呢?本文给出一个可行的方案。
借助于W3C的Navigation Timing API(目前大多数浏览器都已经支持,包括IE9以上版本),该API通过window.performance提供页面加载相关的信息,我们这里只需要关注window.performance.timing。打开chrome开发工具的console标签,输入window.performance.timing,典型的输出如下:
connectEnd: 1450349863256 connectStart: 1450349863216 domComplete: 1450349864919 domContentLoadedEventEnd: 1450349864091 domContentLoadedEventStart: 1450349864066 domInteractive: 1450349864066 domLoading: 1450349863308 domainLookupEnd: 1450349863216 domainLookupStart: 1450349863169 fetchStart: 1450349863167 loadEventEnd: 1450349864920 loadEventStart: 1450349864919 navigationStart: 1450349863167 redirectEnd: 0 redirectStart: 0 requestStart: 1450349863256 responseEnd: 1450349863299 responseStart: 1450349863298 secureConnectionStart: 0 unloadEventEnd: 0 unloadEventStart: 0
其中有各种浏览器事件的开始时间和结束时间,具体各个事件的涵义,可以参考W3C标准,这张图描述的非常清晰。
比如我们要获取dns的时间:
domainLookupEnd-domainLookupStart
连接建立耗时:
connectEnd-connectStart
目前这些数据都可以在浏览器中读到,将他们发布到服务端机器上,就可以统计分析用户真实网络环境先的各项指标了。 发布到服务端机器的一种最简单的方法就是:将这些数据作为参数请求一个后端文件,然后我们就可以在access日志中得到这些数据。一段伪代码如下:
if(!window.performace){ var timing = window.performance.timing.toJSON(); var params = []; for(var ntItem in timing){ params.push(ntItem+'='+timing[ntItem]); } var targetUrl = 'www.baidu.com?'+params.join('&'); ajaxGet(targetUrl); }
在服务端我们就可以从access日志中得到Navigation Timing API提供的时间信息了。
本文参考W3C文档: http://w3c.github.io/navigation-timing/