编程技术文章分享与教程

网站首页 > 技术文章 正文

地表最强网页性能工具 Perfume.js 发布!

hmc789 2024-11-12 11:33:19 技术文章 2 ℃

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

1.什么是 Perfume.js

Perfume 是一个小型的 Web 性能监控库,可将现场数据报告回您最喜欢的分析工具。Perfume.js 具有以下突出特点:

  • ? 支持最新的性能 API 以实现精确指标
  • 设备数据丰富
  • 跨浏览器测试
  • 过滤掉假阳性/阴性结果
  • gzip 压缩后体积仅 5.1Kb
  • 支持 Web Vitals Score 核心指标
  • 灵活的分析工具
  • ?? 内置 requestIdleCallback 策略,零浪费毫秒
  • 能够跟踪有关用户操作的数据

requestIdleCallback:通过安排在空闲期间执行函数,requestIdleCallback 可以帮助确保浏览器保持响应能力和高性能,即使在执行复杂操作或渲染大量数据时也是如此。

Perfume 利用最新的性能 API 来收集现场数据,使开发者能够了解现实世界用户的实际体验。性能涵盖以下核心指标:

  • Navigation Timing:DNS 查找、标头大小、获取时间(缓存查找加上响应时间)、worker时间(worker时间加上响应时间)、时间(请求加上响应时间)、下载时间、Time to First Byte等等
  • Navigator Interface:用户代理的状态和标识,允许脚本查询和注册自己进行一些活动
  • Resource Timing资源计时收集文档相关资源的性能指标,比如:样式表、脚本、图像等等。
  • Element Timing使用 Element Timing API 跟踪图像元素和文本节点何时显示在屏幕
  • Service Worker Status:Service Worker是否支持等
  • StorageManager interface提供用于管理数据本地存储权限和估算可用存储空间接口
  • Time to First Byte (TTFB)
  • First Contentful Paint (FCP)
  • Largest Contentful Paint (LCP):最大有意义的绘制
  • First Input Delay (FID):用户输入延迟
  • Cumulative Layout Shift (CLS):最大累计偏移
  • Interaction to Next Paint (INP)测量用户交互(例如单击或触摸输入)和以视觉方式更新网站的“下一次绘制”之间经过的时间
  • Total Blocking Time (TBT)内容绘制 (FCP) 之后主线程被阻塞足够长的时间以阻止输入响应的总时间。
  • Navigation Total Blocking Time (NTBT)

目前 Perfume.js 在 Github 通过 MIT 协议开源,有超过 3k 的 star、是一个值得关注的前端开源项目。

2.Perfume.js 与 Web Vitals 的关系

Perfume 利用 Web Vitals 库来收集所有标准化性能指标。 它探索新的指标(如导航总阻塞时间)和维度(如低端设备、服务工作人员状态),以更好地了解站点性能数据。

所以不用担心,Perfume.js 是 Web Vitals 的超集,有点像 Typescript 是 Javascript 的超集。

Perfume 默认报告导航计时、网络信息、TTFB、FCP、FID、LCP、CLS、INP 和 TBT 等指标; 所有结果都将报告给 analyticsTracker 回调,下面的代码是开发者组织跟踪的一种方法,支持随意调整。

import { initPerfume } from 'perfume.js';

initPerfume({
  analyticsTracker: (options) => {
    const {
      attribution,
      metricName,
      data,
      navigatorInformation,
      rating,
      navigationType,
    } = options;
    switch (metricName) {
      case 'navigationTiming':
        if (data && data.timeToFirstByte) {
          myAnalyticsTool.track('navigationTiming', data);
        }
        break;
      case 'networkInformation':
        if (data && data.effectiveType) {
          myAnalyticsTool.track('networkInformation', data);
        }
        break;
      case 'storageEstimate':
        myAnalyticsTool.track('storageEstimate', data);
        break;
      case 'TTFB':
        myAnalyticsTool.track('timeToFirstByte', { duration: data });
        break;
      case 'RT':
        myAnalyticsTool.track('redirectTime', { duration: data });
        break;
      case 'FCP':
        myAnalyticsTool.track('firstContentfulPaint', { duration: data });
        break;
      case 'FID':
        myAnalyticsTool.track('firstInputDelay', { duration: data });
        break;
      case 'LCP':
        myAnalyticsTool.track('largestContentfulPaint', { duration: data });
        break;
      case 'CLS':
        myAnalyticsTool.track('cumulativeLayoutShift', { value: data });
        break;
      case 'INP':
        myAnalyticsTool.track('interactionToNextPaint', { value: data });
        break;
      case 'TBT':
        myAnalyticsTool.track('totalBlockingTime', { duration: data });
        break;
      case 'elPageTitle':
        myAnalyticsTool.track('elementTimingPageTitle', { duration: data });
        break;
      case 'userJourneyStep':
        myAnalyticsTool.track('userJourneyStep', {
          duration: data,
          stepName: attribution.step_name,
          vitals_score: rating,
        });
        break;
      default:
        myAnalyticsTool.track(metricName, { duration: data });
        break;
    }
  },
});

Perfume 为所有事件添加了数据丰富功能,以便可以更好地了解现实世界的体验:

  • deviceMemory:用户的设备内存(RAM)。
  • hardwareConcurrency:用户设备上逻辑 CPU 处理器核心的数量。
  • serviceWorkerStatus:Service Worker 的状态,介于受控、支持和不支持之间。

基于 Navigator API,该库可以帮助开发者区分低端和高端设备/体验:

  • isLowEndDevice:RAM 和 CPU 分数的组合。
  • isLowEndExperience:RAM、CPU、NetworkStatus 和 SaveData 得分的组合。

3.Perfume.js 基础用法

Resource Timing

Resource Timing 收集文档相关资源的性能指标,比如:样式表、脚本、图像等等。 Perfume 有助于公开所有 PerformanceResourceTiming 条目,并按所使用的 Kb 对数据数据消耗进行分组。

initPerfume({
  resourceTiming: true,
  // 标记资源请求
  analyticsTracker: ({ metricName, data }) => {
    myAnalyticsTool.track(metricName, data);
  })
});
// Perfume.js 输出: dataConsumption { "css": 185.95, "fetch": 0, "img": 377.93, ... , "script": 8344.95 }

Element Timing

使用新兴的 Element Timing API 规范跟踪图像元素和文本节点何时显示在屏幕上,只需将具有选择的描述性值的 elementtiming 属性添加到想要测量的 HTML 元素即可:

// dom上通过elementtiming属性标记要测量的元素
<h1 elementtiming="elPageTitle" class="title">Perfume.js</h1>
<img
  elementtiming="elHeroLogo"
  alt="Perfume.js logo"
  src="https://zizzamia.github.io/perfume/assets/perfume-logo-v5-0-0.png"
/>
initPerfume({
  elementTiming: true,
  // 元素时间
  analyticsTracker: ({ metricName, data }) => {
    myAnalyticsTool.track(metricName, data);
  })
});

// Perfume.js: elPageTitle 256.00 ms
// Perfume.js: elHeroLogo 1234.00 ms

注意:以上数据本质上是基于 PerformanceObserver API来完成测量:

const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    console.log(entry);
  });
});
observer.observe({ type: "element", buffered: true });

关于 Perfume.js 更多指标用法可以参考文末资料,这里不再过多展开。

参考资料

https://github.com/Zizzamia/perfume.js

https://betterprogramming.pub/web-vitals-guide-b56e28798e7f

https://developer.mozilla.org/en-US/docs/Web/API/PerformanceElementTiming

https://developer.mozilla.org/zh-CN/docs/Web/API/StorageManager

标签列表
最新留言