前端性能关系到页面的用户体验,页面的用户体验影响了产品的留存率,而产品则直接决定了一个公司的生死存亡。
Global Web Performance Matters for ecommerce的报告中指出:
57%的用户更在乎网页在3秒内是否完成加载。
52%的在线用户认为网页打开速度影响到他们对网站的忠实度。
每慢1秒造成页面 PV 降低11%,用户满意度也随之降低降低16%。
近半数移动用户因为在10秒内仍未打开页面从而放弃。
在我们做前端性能优化的时候,我们必须知道我们所做的优化到底能提升多少性能,这时候就有必要对前端性能进行监控。当然,我们现在这边讨论的前端性能,是关于页面加载和延迟方面的性能,暂时不讨论对错误处理的相关内容。
首先简单介绍一下前端相关的性能指标,我们关注的几个指标如下。
对开发人员而言,我们常用的性能指标API就是Performance。Performance 接口可以获取到当前页面与性能相关的信息。
我们使用window.performance
就可以获得 performance对象。
在控制台我们打印performance,可以看到performance对象包含五个属性。
navigation 提供了在指定的时间段里发生的操作相关信息,包括页面是加载还是刷新、发生了多少次重定向等等。
timing 对象包含延迟相关的性能信息,也是这次我们需要
memory 对象
timeOrigin 返回性能测量开始时的时间的高精度时间戳
我这边先给出上述字段的含义,个人认为比较重要的节点加粗了
(1) DOMContentLoaded 是指页面元素加载完毕,但是一些资源比如图片还无法看到,但是这个时候页面是可以正常交互的,比如滚动,输入字符等。 jQuery 中经常使用的 $(document).ready()
其实监听的就是 DOMContentLoaded 事件。
(2) load 是指页面上所有的资源(图片,音频,视频等)加载完成。jQuery 中 $(document).load()
监听的是 load 事件。
由于上面的一些字段解释源于网上的文档和资料,所以我自己需要做一些代码上的测试。
代码如下,我们计算了DOMContentLoaded的回调执行时间。
javascriptwindow.addEventListener('DOMContentLoaded', () => {
console.time('DOMContentLoaded')
for (let i=0;i<1000000000;i++){
}
console.timeEnd('DOMContentLoaded')
})
在浏览器控制台,我们打印了这两个字段的差值,发现两个字段的差值刚好等于DOMContentLoaded的回调执行时间,网上关于字段的解释正确。并且,真正触发DOMContentLoaded事件应该是domContentLoadedEventStart对应的时间。
在浏览器控制台,我们打印了它和navigationStart的差值。
在浏览器network的下面,我们看到显示的DOMContentLoaded时间是1.34秒
结论:浏览器上的DOMContentLoaded的时间实际代表的是domContentLoadedEventEnd 的时间。
在DOMContentLoaded事件的回调里,我们发现loadEventStart和loadEventEnd都是0。在load事件的回调里,我们发现loadEventStart有值,loadEventEnd是0。
结论:如果需要计算load的时间的话,一定要注意代码在页面load事件触发以后再去计算。
再明确一下白屏时间的定义,用户从打开页面开始到页面开始有东西呈现为止。
如果是chrome高版本,直接可以通过下面代码获得
// 白屏时间 (chrome.loadTimes().firstPaintTime - chrome.loadTimes().startLoadTime)*1000;
如果是没有该API的普通浏览器
我们通常认为浏览器开始渲染 <body>
或者解析完 <head>
的时间是白屏结束的时间点。
所以,白屏时间 = 开始渲染时间 + 头部资源加载时间
javascript//开始渲染时间
startTime = performance.timing.domLoading - performance.timing.navigationStart;
我们在<head>
的前面计时开始,在<head>
最末尾计时结束,中间的差值就是头部资源加载时间。
html<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<script>
var start_time = new Date; //测试时间起点,实际统计起点为 DNS 查询
</script>
<script>
for(let i=0; i<10000000000; i++){
}
</script>
<!-- 页面 CSS 资源 -->
<link rel="stylesheet" href="xx.css">
<script>
var end_time = +new Date; //时间终点
var headTime = end_time - start_time; //头部资源加载时间
</script>
</head>
<body>
</body>
</html>
所以最终,白屏时间 = 开始渲染时间(startTime) + 头部资源加载时间(headTime)
再明确一下首屏时间的定义,用户浏览器首屏内所有内容都呈现出来所花费的时间。
影响首屏的主要因素是图片的加载。基本流程如下
html首屏位置调用 API 开始统计 -> 绑定首屏内所有图片的 load 事件 -> 页面加载完后判断图片是否在首屏内,找出加载最慢的一张 -> 首屏时间
对于网页高度小于屏幕的网站来说,只要在页面底部加上脚本打印当前时间即可;或者对于网页高度大于一屏的网页来说,只要在估算接近于一屏幕的元素的位置后,打印一下当前时间。当然这个时间要得把首屏中所有图片的加载时间也算上。
用户可操作时间影响交互体验,通常我们把所有事件的绑定都放在domReady以后,所以用户可操作的时间可以等于DOM解析完毕的时间。
javascript用户可操作时间 = performance.timing.domInteractive - performance.timing.navigationStart
页面总下载时间可以统计onload时间,load事件必须等到页面内包括图片的所有元素加载完毕后才能触发。
javascript页面总下载时间 = performance.timing.loadEventEnd - performance.timing.navigationStart
javascript// 计算加载时间
function getPerformanceTiming() {
var t = performance.timing
var times = {}
// 页面加载完成的时间,用户等待页面可用的时间
times.loadPage = t.loadEventEnd - t.navigationStart
// 解析 DOM 树结构的时间
times.domReady = t.domComplete - t.responseEnd
// 重定向的时间
times.redirect = t.redirectEnd - t.redirectStart
// DNS 查询时间
times.lookupDomain = t.domainLookupEnd - t.domainLookupStart
// 读取页面第一个字节的时间
times.ttfb = t.responseStart - t.navigationStart
// 资源请求加载完成的时间
times.request = t.responseEnd - t.requestStart
// 执行 onload 回调函数的时间
times.loadEvent = t.loadEventEnd - t.loadEventStart
// DNS 缓存时间
times.appcache = t.domainLookupStart - t.fetchStart
// 卸载页面的时间
times.unloadEvent = t.unloadEventEnd - t.unloadEventStart
// TCP 建立连接完成握手的时间
times.connect = t.connectEnd - t.connectStart
return times
}
页面性能的评估与监控有很多工具,下面简单介绍几个常用的工具:
Page Speed: 谷歌开发的分析和优化网页的工具,可以作为浏览器插件使用
WebPageTest:一款非常优秀的网页前端性能测试工具。使用 WebPagetest,你可以详细掌握网站加载过程中的瀑布流、性能得分、元素分布、视图分析等数据。其中比较直观的视图分析功能可以直接看到页面加载各个阶段的截屏。国内也有利用 WebPagetest 搭建的性能测试平台,推荐使用阿里测。
PhantomJS:自动化监测,模拟Phantom JS 是一个服务器端的 JavaScript API 的 WebKit,基于它可以轻松实现 web 自动化测试。类似的有berserkJS。但是都是服务器模拟测试,不能监控用户真实环境。
本文作者:sora
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!