当前位置:首页 > 编程语言 > 正文内容

Performance API简介

a811625534年前 (2022-08-12)编程语言20

测量实时Web应用程序在真实用户设备和 *** 连接上的响应能力。它可以通过以下方式帮助识别客户端和服务器端代码中的瓶颈:

  • 用户计时:客户端JavaScript函数性能的自定义测量
  • 绘制时间:浏览器渲染指标
  • 资源计时:资产和Ajax调用的加载性能
  • 导航时间:页面加载指标,包括重定向、DNS查找、DOM准备情况等

API解决了与典型性能评估相关的几个问题:

  1. 开发人员经常在连接到快速 *** 的高端PC上测试应用程序。DevTools可以模拟速度较慢的设备,但当大多数客户运行连接到机场WiFi的两年前的移动设备时,它并不总是突出现实世界的问题。
  2. 谷歌分析等第三方选项经常被阻止,导致结果和假设出现偏差。在某些国家/地区,您可能还会遇到隐私问题。
  3. Performance API可以比等 *** 更准确地衡量各种指标。

以下部分描述了您可以使用Performance API的方式。建议您了解一些和的知识。

Performance API可用性

大多数现代浏览器都支持Performance API——包括IE10和IE11(甚至IE9也有有限的支持)。您可以使用以下 *** 检测API的存在:

if ('performance' in window) {
// use Performance API
}

百分比的Polyfill API是不可能的,所以要小心缺少浏览器。如果您的90%的用户都乐于使用Internet Explorer 8进行浏览,那么您只能衡量10%的客户端具有更强大的应用程序。

该API可以在中使用,它提供了一种在后台线程中执行复杂计算而无需停止浏览器操作的 *** 。

大多数API *** 都可以通过标准在服务器端Node.js中使用:

// Node.js performance
import { performance } from 'node:perf_hooks';
// or in Common  *** : const { performance } = require('node:perf_hooks');
console.log( performance.now() );

Deno提供了标准的:

// Deno performance
console.log( performance.now() );

您需要使用--allow-hrtime权限运行脚本以启用高分辨率时间测量:

deno run --allow-hrtime index.js

服务器端性能通常更容易评估和管理,因为它取决于负载、CPU、RAM、硬盘和云服务限制。硬件升级或流程管理选项(例如、和)可能比重构代码更有效。

出于这个原因,以下部分将重点介绍客户端性能。

自定义性能测量

Performance API可用于确定应用程序函数的执行速度。您可能使用过或遇到过使用的计时函数:

const timeStart = new Date();
runMyCode();
const timetaken = new Date() - timeStart;
console.log(`runMyCode() executed in ${ timeTaken }ms`);

Performance API提供了两个主要好处:

  1. 更好的准确性: Date()测量到最接近的毫秒,但Performance API可以测量毫秒的分数(取决于浏览器)。
  2. 更好的可靠性:用户或操作系统可以更改系统时间,因此Date()基于度量的指标并不总是准确的。这意味着当时钟向前移动时,您的函数可能会显得特别慢!

Date()等效的 *** 是返回一个高分辨率时间戳,当负责创建文档的进程启动时(页面已加载),该时间戳设置为零:

const timeStart = performance.now();
runMyCode();
const timeTaken = performance.now() - timeStart;
console.log(`runMyCode() executed in ${ timeTaken }ms`);

非标准属性也可以返回从1970年1月1日开始的时间戳,尽管这在IE和Deno中不可用。

performance.now()在进行多次测量时变得不切实际。Performance API提供了一个缓冲区,您可以在其中记录事件以供以后分析, *** 是将标签名称传递给:

performance.mark('start:app');
performance.mark('start:init');
init(); // run initialization functions
performance.mark('end:init');
performance.mark('start:funcX');
funcX(); // run another function
performance.mark('end:funcX');
performance.mark('end:app');

可以使用以下 *** 提取性能缓冲区中所有标记对象的数组:

const mark = performance.getEntriesByType('mark');

示例结果:

[
{
detail: null
duration: 0
entryType: "mark"
name: "start:app"
startTime: 1000
},
{
detail: null
duration: 0
entryType: "mark"
name: "start:init"
startTime: 1001
},
{
detail: null
duration: 0
entryType: "mark"
name: "end:init"
startTime: 1100
},
...
]

*** 计算两个标记之间的时间并将其存储在性能缓冲区中。您传递一个新的度量名称、起始标记名称(或null以从页面加载测量)和结束标记名称(或null以测量当前时间):

performance.measure('init', 'start:init', 'end:init');

一个被附加到具有计算持续时间的缓冲区中。要获取此值,您可以请求所有度量的数组:

const measure = performance.getEntriesByType('measure');

或按其名称请求度量:

performance.getEntriesByName('init');

示例结果:

[
{
detail: null
duration: 99
entryType: "measure"
name: "init"
startTime: 1001
}
]

使用性能缓冲器

除了标记和测量,性能缓冲区还用于自动记录导航时间、资源时间和绘制时间(我们将在后面讨论)。您可以获得缓冲区中所有条目的数组:

performance.getEntries();

默认情况下,大多数浏览器提供一个缓冲区,最多可存储150个资源指标。这对于大多数评估来说应该足够了,但是如果需要,您可以增加或减少缓冲区限制:

// record 500 metrics
performance.setResourceTimingBufferSize(500);

可以按名称清除标记,也可以指定一个空值来清除所有标记:

performance.clearMarks('start:init');

同样,可以按名称或空值清除所有度量值:

performance.clearMeasures();

监控性能缓冲区更新

可以监视性能缓冲区的更改并在发生特定事件时运行函数。如果您使用来响应DOM更新或使用来检测元素何时滚动到视口中,那么语法将会很熟悉。

您必须使用两个参数定义观察者函数:

  1. 已检测到的观察者条目数组,以及
  2. 观察者对象。如有必要,可以调用它的 *** 来停止观察者。
function performanceCallback(list, observer) {
list.getEntries().forEach(entry => {
console.log(`name    : ${ entry.name }`);
console.log(`type    : ${ entry.type }`);
console.log(`start   : ${ entry.startTime }`);
console.log(`duration: ${ entry.duration }`);
});
}

该函数被传递给一个新的 PerformanceObserver 对象。它的 *** 被传递一个 Performance buffer entryTypes 数组来观察:

let observer = new PerformanceObserver( performanceCallback );
observer.observe({ entryTypes: ['mark', 'measure'] });

在此示例中,添加新标记或度量会运行该performanceCallback()函数。虽然它只在此处记录消息,但它可用于触发数据上传或进行进一步计算。

测量绘制性能

Paint Timing API仅在客户端JavaScript中可用,并自动记录对很重要的两个指标:

  1. first-paint:浏览器已经开始绘制页面。
  2. first-contentful-paint:浏览器绘制了DOM内容的之一个重要项,例如标题或图像。

这些可以从性能缓冲区中提取到一个数组中:

const paintTimes = performance.getEntriesByType('paint');

在页面完全加载之前,请小心运行此命令;值将不会准备好。要么等事件或使用监视paint入口类型。

示例结果:

[
{
"name": "first-paint",
"entryType": "paint",
"startTime": 812,
"duration": 0
},
{
"name": "first-contentful-paint",
"entryType": "paint",
"startTime": 856,
"duration": 0
}
]

缓慢的首次绘制通常是由阻止渲染的CSS或JavaScript引起的。如果浏览器必须下载大图像或,则与first-contentful-paint的差距可能会很大。

资源性能测量

图像、样式表和JavaScript文件等资源的 *** 计时会自动记录到性能缓冲区。虽然您几乎无法解决 *** 速度问题(除了减小文件大小),但它可以帮助突出资产较大、Ajax响应缓慢或第三方脚本性能不佳的问题。

可以使用以下 *** 从缓冲区中提取一组:

const resources = performance.getEntriesByType('resource');

或者,您可以通过传递其完整URL来获取资产的指标:

const resource = performance.getEntriesByName('https://test.com/script.js');

示例结果:

[
{
connectEnd: 195,
connectStart: 195,
decodedBodySize: 0,
domainLookupEnd: 195,
domainLookupStart: 195,
duration: 2,
encodedBodySize: 0,
entryType: "resource",
fetchStart: 195,
initiatorType: "script",
name: "https://test.com/script.js",
nextHopProtocol: "h3",
redirectEnd: 0,
redirectStart: 0,
requestStart: 195,
responseEnd: 197,
responseStart: 197,
secureConnectionStart: 195,
serverTiming: [],
startTime: 195,
transferSize: 0,
workerStart: 195
}
]

可以检查以下属性:

  • name:资源网址
  • entryType:“资源”
  • initiatorType: 资源是如何被启动的,例如“脚本”或“链接”
  • serverTiming:服务器在中传递的对象数组(您的服务器端应用程序可以将指标发送到客户端以进行进一步分析)
  • startTime:获取开始时的时间戳
  • nextHopProtocol : 使用的 *** 协议
  • workerStart:启动Progressive Web App Service Worker之前的时间戳(如果请求未被Service Worker拦截,则为 0)
  • redirectStart:重定向开始时的时间戳
  • redirectEnd : 最后一个重定向响应的最后一个字节之后的时间戳
  • fetchStart:资源获取之前的时间戳
  • domainLookupStart : DNS查询前的时间戳
  • domainLookupEnd : DNS查询后的时间戳
  • connectStart:建立服务器连接之前的时间戳
  • connectEnd : 建立服务器连接后的时间戳
  • secureConnectionStart : SSL握手之前的时间戳
  • requestStart : 浏览器请求资源之前的时间戳
  • responseStart : 浏览器接收到之一个字节数据的时间戳
  • responseEnd : 收到最后一个字节或关闭连接后的时间戳
  • duration : startTime和responseEnd之间的差异
  • transferSize:以字节为单位的资源大小,包括标头和压缩主体
  • encodeBodySize : 解压缩前的资源体(以字节为单位)
  • decodedBodySize : 解压后的资源体,以字节为单位

此示例脚本检索由发起的所有Ajax请求并返回总传输大小和持续时间:

const fetchAll = performance.getEntriesByType('resource')
.filter( r => r.initiatorType === 'fetch')
.reduce( (sum, current) => {
return {
transferSize: sum.transferSize += current.transferSize,
duration: sum.duration += current.duration
}
},
{ transferSize: 0, duration: 0 }
);

导航性能测量

卸载前一页和加载当前页的 *** 时间会作为单个对象自动记录到性能缓冲区。

使用以下 *** 将其提取到数组中:

const pageTime = performance.getEntriesByType('navigation');

…或者通过将页面URL传递给.getEntriesByName()

const pageTiming = performance.getEntriesByName(window.location);

这些指标与的指标相同,但还包括特定于页面的值:

  • entryType : 例如“导航”
  • type:“navigate”、“reload”、“back_forward”或“prerender”
  • redirectCount : 重定向次数
  • unloadEventStart : 上一个文档的卸载事件之前的时间戳
  • unloadEventEnd : 上一个文档的卸载事件之后的时间戳
  • domInteractive : 浏览器解析HTML并构建DOM的时间戳
  • domContentloadedEventStart:文档的DOMContentLoaded事件触发之前的时间戳
  • domContentLoadedEventEnd : 文档的DOMContentLoaded事件完成后的时间戳
  • domComplete : DOM构建和DOMContentLoaded事件完成后的时间戳
  • loadEventStart:页面加载事件触发之前的时间戳
  • loadEventEnd : 页面加载事件和所有资产可用后的时间戳

典型问题包括:

  • unloadEventEnddomInteractive之间有很长的延迟。这可能表明服务器响应缓慢。
  • domContentLoadedEventStartdomComplete之间有很长的延迟。这可能表明页面启动脚本太慢了。
  • domCompleteloadEventEnd之间有很长的延迟。这可能表明该页面有太多资源,或者有几个资源加载时间过长。

性能记录与分析

Performance API允许您整理真实世界的使用数据并将其上传到服务器以进行进一步分析。您可以使用)来存储数据,但第三方脚本可能会被阻止或引入新的性能问题。您可以根据自己的要求定制您自己的解决方案,以确保监控不会影响其他功能。

警惕无法确定统计数据的情况——可能是因为用户使用旧浏览器、拦截JavaScript或在公司 *** 后面。了解缺少哪些数据可能比基于不完整信息做出假设更有成效。

理想情况下,您的分析脚本不会因运行复杂计算或上传大量数据而对性能产生负面影响。考虑利用 *** 工作者并尽量减少同步localStorage调用的使用。以后总是可以批量处理原始数据。

最后,要警惕异常值,例如对统计数据产生不利影响的非常快或非常慢的设备和连接。例如,如果9个用户在2秒内加载了一个页面,但第10个用户的下载时间为60秒,则平均延迟接近8秒。更现实的指标是中位数(2秒)或第90个百分位(每10个用户中有9个用户的加载时间为2秒或更短)。

小结

Web性能仍然是开发人员的一个关键因素。用户希望网站和应用程序能够在大多数设备上做出响应。搜索引擎优化也会受到影响,因为。

有很多性能监控工具,但大多数评估服务器端执行速度或使用有限数量的有能力的客户端来判断浏览器渲染。Performance API提供了一种整理真实用户指标的 *** ,这是任何其他方式都无法计算的。

扫描二维码推送至手机访问。

版权声明:本文由2345好导航站长资讯发布,如需转载请注明出处。

本文链接:http://2345hao.cn/blog/index.php/post/7897.html

分享给朋友:

“Performance API简介” 的相关文章

静态与动态IP地址有何区别?

静态与动态IP地址有何区别?

每台连接到Internet的计算机都有一个Internet协议 (IP) 地址。但是,并非所有IP地址的外观或行为都相同。 如果您使用计算机网络或服务器,了解动态IP和静态IP之间的区别至关重要。通过详细了解每个协议,您可以选择最适合您需求的解决方案。 在本文中,我们将讨论静态和动态IP之间...

宝塔面板教程之数据库管理篇

宝塔面板教程之数据库管理篇

宝塔的数据库管理,是基于phpmyadmin管理和新建数据库。其最大的便利性就是类似,通过面板可以快速访问进行管理操作,无需单独访问phpmyadmin的主页。 此外,在宝塔面板进行数据库管理,你也对数据库名、用户名及密码等信息一目了然,及可以对数据库执行快速备份或者导入。 添加数据...

2022年Web开发人员的平均工资统计报告

2022年Web开发人员的平均工资统计报告

想成为一名网络开发人员或好奇工作的哪些子类型的薪水最高?Web开发是一个竞争激烈、多样化的行业,随着新语言和框架的出现而不断发展。 询问Web开发人员的薪水是一个难以解决的问题(尽管我们尝试)。有太多的因素需要考虑。 无论您是自由开发者还是有兴趣从事更传统的工作、喜欢前端或后端工作,或者想知...

Serverless PHP简介:主要功能、用例以及如何在Lambda上开始使用Bref

Serverless PHP简介:主要功能、用例以及如何在Lambda上开始使用Bref

无服务器计算是一种基于云的执行模型,可以将应用程序作为服务托管,而无需维护服务器。 服务提供商维护服务器上的资源分配,并根据实际使用情况向用户收费。焦点转移到一个人正在创建的核心应用程序上,基础设施完全由服务提供商处理。无服务器计算也称为功能即服务 (FaaS)。 换句话说,Serverle...

PostgreSQL与SQL Server之间的16个关键差异

PostgreSQL与SQL Server之间的16个关键差异

市场上有各种各样的数据库可供选择,用户通常可以仔细考虑PostgreSQL与SQL Server,以便为他们的用例找出更好的选择。使用PostgreSQL进行运营的组织可能希望切换到像Microsoft SQL Server这样的数据库,因为它主要迎合不同的数据仓库解决方案、电子商务和其他业务线...

深入了解什么是函数即服务 (FaaS)

深入了解什么是函数即服务 (FaaS)

您可能听说过SaaS,您可能听说过PaaS和IaaS,但您听说过函数即服务 (FaaS) 吗? FaaS市场正在快速增长。根据Allied Market Research的数据,2018年市场价值 。预计到2026年,这一数字将增长到240亿美元——这意味着该行业将从2020年到2026年以2...