本教程介绍了如何使用 Performance API 记录来自访问您的应用程序的真实用户的类似 DevTool 的统计信息。
使用浏览器 DevTools 评估 Web 应用程序性能很有用,但复制实际使用情况并不容易。使用不同设备、浏览器和网络的不同地点的人都会有不同的体验。
在性能API使用缓冲记录DevTool般在你的网页的生命周期的特定点对象属性指标。这些要点包括:
所有 API 都在客户端 JavaScript 中可用,包括Web Workers。您可以使用以下方法检测 API 支持:
if ('performance' in window) {
// call Performance APIs
}
注意:请注意,尽管实现了大部分 API,但 Safari 并不支持所有方法。
自定义(用户)性能 API 也复制到:
performance_hook
模块,以及--allow-hrtime
许可下运行)。Date()
不够好?您可能已经看过使用该Date()
函数记录经过时间的示例。例如:
const start = new Date();
// ... run code ...
const elapsed = new Date() - start;
但是,Date()
计算仅限于最接近的毫秒并基于系统时间,操作系统可以随时更新系统时间。
Performance API 使用一个单独的、更高分辨率的计时器,可以在几分之一毫秒内进行记录。它还提供了以其他方式无法记录的指标,例如重定向和 DNS 查找时间。
如果您可以将其记录在某处,则在客户端代码中计算性能指标非常有用。您可以使用 Ajax Fetch / XMLHttpRequest请求或Beacon API将统计信息发送到您的服务器进行分析。
或者,大多数分析系统提供自定义事件类 API 来记录时间。例如,Google Analytics User Timings API可以DOMContentLoaded
通过传递类别 ( 'pageload'
)、变量名称 ( "DOMready"
) 和值来记录时间:
const pageload = performance.getEntriesByType( 'navigation' )[0];
ga('send', 'timing', 'pageload', 'DOMready', pageload.domContentLoadedEventStart);
此示例使用页面导航计时 API。所以让我们从那里开始……
在快速连接上测试您的网站不太可能代表用户体验。浏览器 DevTools网络选项卡允许您调节速度,但它无法模拟较差或断断续续的 3G 信号。
Navigation Timing API 将单个PerformanceNavigationTiming
对象推送到性能缓冲区。它包含真实用户观察到的有关重定向、加载时间、文件大小、DOM 事件等的信息。
通过运行访问对象:
const pagePerf = performance.getEntriesByType( 'navigation' );
或者通过将页面 URL ( window.location
)传递给 来访问它getEntriesByName() method
:
const pagePerf = performance.getEntriesByName( window.location );
两者都返回一个包含具有只读属性的对象的单个元素的数组。例如:
[
{
name: "https://site.com/",
initiatorType: "navigation",
entryType: "navigation",
initiatorType: "navigation",
type: "navigate",
nextHopProtocol: "h2",
startTime: 0
...
}
]
该对象包括资源标识属性:
财产 | 描述 |
---|---|
名称 | 资源网址 |
条目类型 | 性能类型——"navigation" 对于页面,"resource" 对于资产 |
发起者类型 | 启动下载的资源 -"navigation" 用于页面 |
下一跳协议 | 网络协议 |
服务器定时 | PerformanceServerTiming对象数组 |
注意:performanceServerTiming name
、description
和duration
metrics由服务器响应写入 HTTPServer-Timing
标头。
该对象包括相对于页面加载开始的以毫秒为单位的资源计时属性。通常按以下顺序预计时间:
财产 | 描述 |
---|---|
开始时间 | 获取开始时的时间戳 -0 用于页面 |
工人开始 | 启动 Service Worker 之前的时间戳 |
重定向开始 | 第一次重定向的时间戳 |
重定向结束 | 收到上次重定向的最后一个字节后的时间戳 |
获取开始 | 获取资源之前的时间戳 |
域查找开始 | DNS 查找前的时间戳 |
域查找结束 | DNS 查找后的时间戳 |
连接开始 | 建立服务器连接前的时间戳 |
连接结束 | 建立服务器连接后的时间戳 |
安全连接启动 | SSL 握手前的时间戳 |
请求开始 | 浏览器请求前的时间戳 |
响应开始 | 浏览器收到第一个字节数据时的时间戳 |
响应结束 | 收到最后一个字节数据后的时间戳 |
期间 | startTime和responseEnd之间经过的时间 |
该对象包括以字节为单位的下载大小属性:
财产 | 描述 |
---|---|
传输大小 | 资源大小,包括标题和正文 |
编码体尺寸 | 解压前的资源体大小 |
解码体尺寸 | 解压后的资源体大小 |
最后,该对象包括进一步的导航和 DOM 事件属性(在 Safari 中不可用):
财产 | 描述 |
---|---|
类型 | 要么`"navigate" ,"reload" ,"back_forward" 或者"prerender" |
重定向计数 | 重定向次数 |
卸载事件开始 | unload 上一个文档事件之前的时间戳 |
卸载事件结束 | unload 上一个文档事件之后的时间戳 |
domInteractive | HTML 解析和 DOM 构建完成时的时间戳 |
domContentLoadedEventStart | 运行DOMContentLoaded 事件处理程序之前的时间戳 |
domContentLoadedEventEnd | 运行DOMContentLoaded 事件处理程序后的时间戳 |
domComplete | DOM 构建和DOMContentLoaded 事件完成时的时间戳 |
加载事件开始 | 页面load 事件触发前的时间戳 |
加载事件结束 | 页面load 事件后的时间戳。下载所有资产 |
在页面完全加载后记录页面加载指标的示例:
'performance' in window && window.addEventListener('load', () => {
const
pagePerf = performance.getEntriesByName( window.location )[0],
pageDownload = pagePerf.duration,
pageDomComplete = pagePerf.domComplete;
});
PerformanceResourceTiming
每当页面加载图像、字体、CSS 文件、JavaScript 文件或任何其他项目等资产时,Resource Timing API 都会将对象推送到性能缓冲区。跑步:
const resPerf = performance.getEntriesByType( 'resource' );
这将返回一组资源计时对象。这些具有与上面显示的页面计时相同的属性,但没有导航和 DOM 事件信息。
这是一个示例结果:
[
{
name: "https://site.com/style.css",
entryType: "resource",
initiatorType: "link",
fetchStart: 150,
duration: 300
...
},
{
name: "https://site.com/script.js",
entryType: "resource",
initiatorType: "script",
fetchStart: 302,
duration: 112
...
},
...
]
可以通过将其 URL 传递给.getEntriesByName()
方法来检查单个资源:
const resourceTime = performance.getEntriesByName('https://site.com/style.css');
这将返回一个包含单个元素的数组:
[
{
name: "https://site.com/style.css",
entryType: "resource",
initiatorType: "link",
fetchStart: 150,
duration: 300
...
}
]
您可以使用 API 报告每个 CSS 文件的加载时间和解压缩大小:
// array of CSS files, load times, and file sizes
const css = performance.getEntriesByType('resource')
.filter( r => r.initiatorType === 'link' && r.name.includes('.css'))
.map( r => ({
name: r.name,
load: r.duration + 'ms',
size: r.decodedBodySize + ' bytes'
}) );
该css
数组现在包含每个 CSS 文件的对象。例如:
[
{
name: "https://site.com/main.css",
load: "155ms",
size: "14304 bytes"
},
{
name: "https://site.com/grid.css",
load: "203ms",
size: "5696 bytes"
}
]
注意:负载和大小为零表示资产已被缓存。
至少 150 个资源指标对象将被记录到性能缓冲区。您可以使用.setResourceTimingBufferSize(N)
方法定义一个特定的数字。例如:
// record 500 resources
performance.setResourceTimingBufferSize(500);
可以使用 清除现有指标.clearResourceTimings() method
。
First Contentful Paint (FCP)衡量用户导航到您的页面后呈现内容所需的时间。Chrome 的 DevTool Lighthouse 面板的Performance部分显示了该指标。Google 认为 FCP 时间少于 2 秒是好的,并且您的页面将比 Web 的 75% 显示得更快。
在以下情况下,Paint Timing API 将两个记录两个PerformancePaintTiming对象推送到性能缓冲区:
运行时,两个对象都以数组形式返回:
const paintPerf = performance.getEntriesByType( 'paint' );
结果示例:
[
{
"name": "first-paint",
"entryType": "paint",
"startTime": 125
},
{
"name": "first-contentful-paint",
"entryType": "paint",
"startTime": 127
}
]
的开始时间是相对于初始页面加载。
Performance API 可用于为您自己的应用程序功能计时。所有用户计时方法都可以在客户端 JavaScript、Web Workers、Deno 和 Node.js 中使用。
*请注意,Node.js 脚本必须加载Performance hooks( perf_hooks
) 模块。*
*CommonJS*require
语法:
const { performance } = require('perf_hooks');
*或者 ES 模块*import
语法:
import { performance } from 'perf_hooks';
最简单的选项是<span style="font-size: 16px;">performance.now()
,它返回进程生命周期开始时的高分辨率时间戳。
您可以performance.now()
用于简单的计时器。例如:
const start = performance.now();
// ... run code ...
const elapsed = performance.now() - start;
*注意:非标准timeOrigin
属性*返回 Unix 时间的时间戳。它可以在 Node.js 和浏览器 JavaScript 中使用,但不能在 IE 和 Safari 中使用。
performance.now()
在管理多个计时器时很快变得不切实际。该.mark()
方法将一个命名的PerformanceMark 对象对象添加到性能缓冲区。例如:
performance.mark('script:start');
performance.mark('p1:start');
// ... run process 1 ...
performance.mark('p1:end');
performance.mark('p2:start');
// ... run process 2 ...
performance.mark('p2:end');
performance.mark('script:end');
以下代码返回一个标记对象数组:
const marks = performance.getEntriesByType( 'mark' );
用entryType
,name
和startTime
属性:
[
{
entryType: "mark",
name: "script:start",
startTime: 100
},
{
entryType: "mark",
name: "p1:start",
startTime: 200
},
{
entryType: "mark",
name: "p1:end",
startTime: 300
},
...
]
可以使用该.measure()
方法计算两个标记之间经过的时间。它传递了一个度量名称、开始标记名称(或null
使用零)和结束标记名称(或null
使用当前时间):
performance.measure('p1', 'p1:start', 'p1:end');
performance.measure('script', null, 'script:end');
每次调用都会将具有计算持续时间的PerformanceMeasure对象推送到性能缓冲区。可以通过运行来访问一系列度量:
const measures = performance.getEntriesByType( 'measure' );
例子:
[
{
entryType: "measure",
name: "p1",
startTime: 200,
duration: 100
},
{
entryType: "measure",
name: "script",
startTime: 0,
duration: 500
}
]
可以使用以下.getEntriesByName()
方法按名称检索标记或测量对象:
performance.getEntriesByName( 'p1' );
其他方法:
.getEntries()
: 返回所有性能条目的数组。.clearMarks( [name] )
: 清除命名标记(不带名称运行以清除所有标记).clearMeasures( [name] )
: 清除已命名的度量(不带名称运行以清除所有度量)一个PerformanceObserver可以观看更改到缓冲区,并运行一个函数,当特定对象出现。观察者函数定义有两个参数:
list
: 观察者条目observer
(可选):观察者对象function performanceHandler(list, observer) {
list.getEntries().forEach(entry => {
console.log(`name : ${ entry.name }`);
console.log(`type : ${ entry.type }`);
console.log(`duration: ${ entry.duration }`);
// other code, e.g.
// send data via an Ajax request
});
}
这个函数被传递给一个新PerformanceObserver
对象。该.observe()
方法然后将观察到的entryTypes
(通常"mark"
,"measure"
和/或"resource"
):
let observer = new PerformanceObserver( performanceHandler );
observer.observe( { entryTypes: [ 'mark', 'measure' ] } );
performanceHandler()
每当将新标记或度量对象推送到性能缓冲区时,该函数就会运行。
在自我剖析API是关系到性能API和可以帮助找到低效或不必要的后台功能,而无需手动设置标志和措施。
示例代码:
// new profiler, 10ms sample rate
const profile = await performance.profile({ sampleInterval: 10 });
// ... run code ...
// stop profiler, get trace
const trace = await profile.stop();
跟踪返回有关在每个采样间隔执行的脚本、函数和行号的数据。重复引用相同的代码可能表明进一步优化是可能的。
API 目前正在开发中(请参阅Chrome 状态)并且可能会发生变化。
性能 API 提供了一种方法来衡量网站和应用程序在真实设备上的网站和应用程序速度,这些设备由真实的人在不同位置使用一系列连接。它可以轻松地为每个人整理类似 DevTool 的指标并识别潜在的瓶颈。
解决这些性能问题是另一回事,但SitePoint Jump Start Web Performance 一书会有所帮助。它提供了一系列快餐、简单的食谱和改变生活的饮食,让您的网站更快、响应更快。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/eDMV9uG47PzQuZfwccw6qw
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。