如何使用 Performance API 让您的网站更快

news/2024/5/14 2:04:30/文章来源:https://blog.csdn.net/weixin_40906515/article/details/118214818

本教程介绍了如何使用 Performance API 记录来自访问您的应用程序的真实用户的类似 DevTool 的统计信息。

使用浏览器 DevTools 评估 Web 应用程序性能很有用,但复制实际使用情况并不容易。使用不同设备、浏览器和网络的不同地点的人都会有不同的体验。

性能 API 简介

在性能API使用缓冲记录DevTool般在你的网页的生命周期的特定点对象属性指标。这些要点包括:

  1. 页面导航:记录页面加载重定向、连接、握手、DOM 事件等。

  2. 资源加载:记录图片、CSS、脚本、Ajax 调用等资源加载。

  3. Paint metrics:记录浏览器渲染信息。

  4. 自定义性能:记录任意应用程序处理时间以查找慢功能。

所有 API 都在客户端 JavaScript 中可用,包括Web Workers。您可以使用以下方法检测 API 支持:

if ('performance' in window) {// call Performance APIs}

注意:请注意,尽管实现了大部分 API,但 Safari 并不支持所有方法。

自定义(用户)性能 API 也复制到:

  • Node.js 内置performance_hook模块,以及

  • Deno性能 API(使用它的脚本必须在--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 namedescriptiondurationmetrics由服务器响应写入 HTTPServer-Timing标头

该对象包括相对于页面加载开始的以毫秒为单位的资源计时属性。通常按以下顺序预计时间:

财产描述
开始时间获取开始时的时间戳 -0用于页面
工人开始启动 Service Worker 之前的时间戳
重定向开始第一次重定向的时间戳
重定向结束收到上次重定向的最后一个字节后的时间戳
获取开始获取资源之前的时间戳
域查找开始DNS 查找前的时间戳
域查找结束DNS 查找后的时间戳
连接开始建立服务器连接前的时间戳
连接结束建立服务器连接后的时间戳
安全连接启动SSL 握手前的时间戳
请求开始浏览器请求前的时间戳
响应开始浏览器收到第一个字节数据时的时间戳
响应结束收到最后一个字节数据后的时间戳
期间startTime和responseEnd之间经过的时间

该对象包括以字节为单位的下载大小属性:

财产描述
传输大小资源大小,包括标题和正文
编码体尺寸解压前的资源体大小
解码体尺寸解压后的资源体大小

最后,该对象包括进一步的导航和 DOM 事件属性(在 Safari 中不可用):

财产描述
类型要么"navigate""reload""back_forward"或者"prerender"
重定向计数重定向次数
卸载事件开始unload上一个文档事件之前的时间戳
卸载事件结束unload上一个文档事件之后的时间戳
domInteractiveHTML 解析和 DOM 构建完成时的时间戳
domContentLoadedEventStart

运行DOMContentLoaded事件处理程序之前的时间戳

domContentLoadedEventEnd

运行DOMContentLoaded事件处理程序后的时间戳

domCompleteDOM 构建和DOMContentLoaded事件完成时的时间戳
加载事件开始页面load事件触发前的时间戳
加载事件结束页面load事件后的时间戳。下载所有资产

在页面完全加载后记录页面加载指标的示例:

'performance' in window && window.addEventListener('load', () => {constpagePerf        = 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对象推送到性能缓冲区:

  • first-paint发生:浏览器绘制第一个像素,并且

  • first-contentful-paint发生:浏览器绘制 DOM 内容的第一项

运行时,两个对象都以数组形式返回:

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) 模块

CommonJSrequire语法:

const { performance } = require('perf_hooks');

或者 ES 模块import语法:

import { performance } from 'perf_hooks';

最简单的选项是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' );

entryTypenamestartTime属性:

[{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可以观看更改到缓冲区,并运行一个函数,当特定对象出现。观察者函数定义有两个参数:

  1. list: 观察者条目

  2. 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是关系到性能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 一书会有所帮助。它提供了一系列快餐、简单的食谱和改变生活的饮食,让您的网站更快、响应更快。

往期推荐

Vite 太快了,烦死了,是时候该小睡一会了。


如何实现比 setTimeout 快 80 倍的定时器?


万字长文!总结Vue 性能优化方式及原理


90 行代码的 webpack,你确定不学吗?

最后

如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:

  1. 点个「在看」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)

  2. 欢迎加我微信「huab119」拉你进技术群,长期交流学习...

    关注公众号「前端劝退师」,持续为你推送精选好文,也可以加我为好友,随时聊骚。

点个在看支持我吧,转发就更好了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_745226.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何为 Drupal 7 网站添加悬浮的反馈按钮?

最近有客户咨询我们要怎么为 Drupal 网站添加悬浮按钮,方便访客能够链接到反馈表单页面。很幸运,使用 Feedback Simple 模块可以很容易实现。在这篇短教程中,我将和大家分享如何添加链接到“反馈”页面的悬浮按钮。创建反馈页面使用 Webform …

但凡早知道这28个网站,都不至于学得那么不扎实

大家好,我是零一,经常有读者问我:自学怎么学,要学的知识那么多,根本记不住怎么办?读者咨询我一般刚开始回答的时候都是说要多做笔记总结,更重要的就是要上手敲代码实践,如果抛开任何…

网站就必须用响应式布局吗?MVC视图展现模式之移动布局

本文先引入给读者一个自己研究的机会,下次深入说明一下: 废话不多说,直接上图 新建一个mvc的项目 在视图里面添加一个移动端视图 正常访问一下 Bootstrap自带的响应式的方式(页面代码并没有改变) 我们来模拟一下移动端…

基于django的视频点播网站开发-step13-后台反馈功能

用户反馈管理功能,是对前端用户反馈的问题进行展示,并可实现删除功能。是一个很实用的功能,也算是当代网站的标配。它可以实时的跟踪到用户对网站的各种意见和吐槽,开发者能及时修缮网站功能或者修改网站bug。 Demo地址 反馈管理包…

国外SEO分析工具应用心得

第一部分:常用分析术语理解(一) PC端1.Title Tag,这个标签会显示在搜索结果页的网站链接部分(比如百度,通过标签中的某几个关键词去搜索,可能会在百度结果中得到较为靠前的排名),同时该标签会显示在浏览器的标题栏&…

南美一黑客公开哥伦比亚政府网站数据

据外媒报道,一名叫做Hanom1960的黑客于日前攻击了哥伦比亚信息技术与通信部网站和国家教育部网站,并将从上面窃取来的数据泄露出去。这名自称隶属于LulsZec黑客组织的黑客于上周首次亮相,当时,他盗窃了来自哥斯达黎加外交部的数据…

让浏览器自动在指定网站地址前加https

由于在公司只能上内网,但是有些网站在最前面加上https://就可以登录,因此有了这个需求: Chrome浏览器: 1.新建网页:chrome://net-internals/#hsts 2.以cnblogs为例,按如下设置 点击add即可~ 转载于:https:/…

大学网站首页代码html_网站代码优化购物网站优化排名首页旅游排名网站优化新网站快速优化排名商务网站流量优化手机端优化网站排名网站搜索排名优化...

网站代码优化购物网站优化排名首页旅游排名网站优化新网站快速优化排名商务网站流量优化手机端优化网站排名网站搜索排名优化网站代码优化购物网站优化排名首页旅游排名网站优化新网站快速优化排名商务网站流量优化手机端优化网站排名网站搜索排名优化网站代码优化购物网站优化…

Eclipse 发布到网站的附加产品的形式 Update Site

Eclipse 发布到网站的附加产品的形式 Update Site 通过Update Site Project项目将自己做的插件产品公布到公网上,给客户或其它測试人员下载和应用,这样自己的插件就以网站的形式暴露给公众了,谁都能够下载下来试用它。 1. 创建Plug-inProject…

网易云音乐网站项目问题整理

排版有些麻烦&#xff0c;简单的方法是设div,而我却用了直接添加图片的方法 以下是代码说明&#xff1a; 1 <div class"xiazaiquyu">2 <!--第一列-->3 <div class"first">4 <im…

云服务器有必要做cdn吗,网站云服务器使用CDN加速的必要性

最近一直有小伙伴咨询小编&#xff1a;网站云服务器在网站运营过程中有没有必要使用CDN加速&#xff1f; 小网站需要用CDN吗&#xff1f;对于这个问题小编的建议是&#xff1a;有必要&#xff0c;非常必要&#xff01;为什么这么说&#xff0c;今天小编给大家详细介绍使用CDN的…

使用Windows Server 2003搭建一个asp+access网站

鼠标右键->新建->网站->下一步->描述(随便给一个&#xff0c;这里我以test为例) ->下一步->下一步->输入主目录的路径&#xff0c;默认路径下是C:\Inetpub\wwwroot->下一步->下一步->完成 当前已创建好网站&#xff0c;默认是停止状态的(因为默认…

如何优化SEO的网站结构

如何优化SEO的网站结构 明确定义的站点结构使搜索引擎爬虫的工作更容易&#xff0c;这意味着更好的索引编制和更多机会获得更高的排名。 随着百度排名算法&#xff0c;语音搜索和移动优先索引中人工智能的引入&#xff0c;网站的结构变得比以往任何时候都更加重要。 在网站上抛…

成立仅8个月的个人网站,月收入几十万美金,很难做到吗?

http://new.iheima.com/detail/2014/0205/58390.html viralnova.com 是一个2013年5月才成立的个人网站&#xff0c;这个网站最近在美国一些科技博客曝光量非常高&#xff0c;大家都觉得这个网站是个小奇迹。 原因是这个个人网站成立仅仅只有8个多月&#xff0c;但是每天的独立用…

【面试精选】关于大型网站系统架构你不得不懂的10个问题

该文已加入笔主的开源项目——JavaGuide&#xff08;一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目),地址:https://github.com/Snailclimb/JavaGuide 。觉得不错的话&#xff0c;记得点个Star。下面这些问题都是一线大厂的真实面试问题&#xff0c;不论是对你面试…

网站验证码的生成原理、难度控制,及python实现

图片验证码已经广泛的使用在各种反爬虫的场景中&#xff0c;验证码的的生成验证过程对于开发者来说是零成本的&#xff0c;对于用户体验来说可能稍差、但是对于爬虫来说是致命的和高成本的。 下面将介绍使用python实现网站验证码的产生及验证的全过程&#xff0c;然我们对验证码…

网站跨站点单点登录

昨天和几位朋友探讨到了这个话题&#xff0c;发现虽然单点登录&#xff0c;或者叫做独立的passport登录虽然已经有了很多实现方法&#xff0c;但是能真正了解并实现的人却并不太多&#xff0c;所以些下此文&#xff0c;希望从原理到实现&#xff0c;能让大家了解的多一些 至于…

谈谈网站静态化

写在前头 静态化是解决减轻网站压力,提高网站访问速度的常用方案,但在强调交互的We2.0 时代,对静态化提出了更高的要求,静态不仅要能静,还要能动,下面我通过一个项目,谈谈网站静态化后的架构设计方案,同时和大家探讨一下,在开源产品大行其道,言架构必称MemberCache, Nginx,的时…

大型网站技术架构(四)网站的高性能架构

2019独角兽企业重金招聘Python工程师标准>>> 网站性能是客观的指标&#xff0c;可以具体体现到响应时间、吞吐量、并发数、性能计数器等技术指标。 1、性能测试指标 1.1 响应时间 指应用执行一个操作需要的时间&#xff0c;指从发出请求到最后收到响应数据所需要的时…

建立网站 --- 了解常用的服务端

电脑的使用方式主要分为两大类 &#xff1a; 客户机 和 服务器 客户机&#xff1a; 访问其他主机的机器&#xff0c;通过ISP &#xff08;因特网业务提供者&#xff09;上网时&#xff0c;客户机被分配了一个临时的IP地址&#xff0c;利用这个临时IP地址&#xff0c;客户机…