
测量实时Web应用程序在真实用户设备和 *** 连接上的响应能力。它可以通过以下方式帮助识别客户端和服务器端代码中的瓶颈:
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提供了两个主要好处:
Date()测量到最接近的毫秒,但Performance API可以测量毫秒的分数(取决于浏览器)。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更新或使用来检测元素何时滚动到视口中,那么语法将会很熟悉。
您必须使用两个参数定义观察者函数:
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中可用,并自动记录对很重要的两个指标:
这些可以从性能缓冲区中提取到一个数组中:
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
}
]
可以检查以下属性:
此示例脚本检索由发起的所有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);
这些指标与的指标相同,但还包括特定于页面的值:
典型问题包括:
Performance API允许您整理真实世界的使用数据并将其上传到服务器以进行进一步分析。您可以使用)来存储数据,但第三方脚本可能会被阻止或引入新的性能问题。您可以根据自己的要求定制您自己的解决方案,以确保监控不会影响其他功能。
警惕无法确定统计数据的情况——可能是因为用户使用旧浏览器、拦截JavaScript或在公司 *** 后面。了解缺少哪些数据可能比基于不完整信息做出假设更有成效。
理想情况下,您的分析脚本不会因运行复杂计算或上传大量数据而对性能产生负面影响。考虑利用 *** 工作者并尽量减少同步localStorage调用的使用。以后总是可以批量处理原始数据。
最后,要警惕异常值,例如对统计数据产生不利影响的非常快或非常慢的设备和连接。例如,如果9个用户在2秒内加载了一个页面,但第10个用户的下载时间为60秒,则平均延迟接近8秒。更现实的指标是中位数(2秒)或第90个百分位(每10个用户中有9个用户的加载时间为2秒或更短)。
Web性能仍然是开发人员的一个关键因素。用户希望网站和应用程序能够在大多数设备上做出响应。搜索引擎优化也会受到影响,因为。
有很多性能监控工具,但大多数评估服务器端执行速度或使用有限数量的有能力的客户端来判断浏览器渲染。Performance API提供了一种整理真实用户指标的 *** ,这是任何其他方式都无法计算的。
每台连接到Internet的计算机都有一个Internet协议 (IP) 地址。但是,并非所有IP地址的外观或行为都相同。 如果您使用计算机网络或服务器,了解动态IP和静态IP之间的区别至关重要。通过详细了解每个协议,您可以选择最适合您需求的解决方案。 在本文中,我们将讨论静态和动态IP之间...
宝塔的数据库管理,是基于phpmyadmin管理和新建数据库。其最大的便利性就是类似,通过面板可以快速访问进行管理操作,无需单独访问phpmyadmin的主页。 此外,在宝塔面板进行数据库管理,你也对数据库名、用户名及密码等信息一目了然,及可以对数据库执行快速备份或者导入。 添加数据...
想成为一名网络开发人员或好奇工作的哪些子类型的薪水最高?Web开发是一个竞争激烈、多样化的行业,随着新语言和框架的出现而不断发展。 询问Web开发人员的薪水是一个难以解决的问题(尽管我们尝试)。有太多的因素需要考虑。 无论您是自由开发者还是有兴趣从事更传统的工作、喜欢前端或后端工作,或者想知...
无服务器计算是一种基于云的执行模型,可以将应用程序作为服务托管,而无需维护服务器。 服务提供商维护服务器上的资源分配,并根据实际使用情况向用户收费。焦点转移到一个人正在创建的核心应用程序上,基础设施完全由服务提供商处理。无服务器计算也称为功能即服务 (FaaS)。 换句话说,Serverle...
市场上有各种各样的数据库可供选择,用户通常可以仔细考虑PostgreSQL与SQL Server,以便为他们的用例找出更好的选择。使用PostgreSQL进行运营的组织可能希望切换到像Microsoft SQL Server这样的数据库,因为它主要迎合不同的数据仓库解决方案、电子商务和其他业务线...
您可能听说过SaaS,您可能听说过PaaS和IaaS,但您听说过函数即服务 (FaaS) 吗? FaaS市场正在快速增长。根据Allied Market Research的数据,2018年市场价值 。预计到2026年,这一数字将增长到240亿美元——这意味着该行业将从2020年到2026年以2...