@dropbox/ttvc

中文文档
3.0.1发布于 2024/09/14Apache-2.0TypeScriptESM + CJS零依赖近 30 天下载 9410

实时完成测量

中文使用文档
文档目录17 节
  1. 概览
  2. 开始吧
  3. 使用量
  4. 基本用途
  5. 向收集端点报告衡量标准
  6. 记录一个性能时间线条目
  7. 使用 React 路由器的客户端导航
  8. 将 TTVC 测量的取消归为归属
  9. API 密码
  10. 类型
  11. 职能
  12. 浏览器支持
  13. 怎么会这样?
  14. 发展中国家
  15. 大楼
  16. 测试
  17. 释放

ttvc

version minzip size

lint unit playwright

概览

ttvc 提供适合实地数据收集(实时用户监测)的可视性完成度量表的内浏览器执行.

可视完整度测量用户认为一个页面的所有可视元素已完全加载的时刻. 页面一到可视化完成,若无用户输入,便不得在取景口中作其他更改.

开始吧

此库可从 npm 获取 。 在您的项目中添加 npm 或者说 yarn 软件包管理器.

$ npm install @dropbox/ttvc
$ yarn add @dropbox/ttvc

使用量

基本用途

import {init, onTTVC} from '@dropbox/ttvc';

// Call this as early in pageload as possible to setup instrumentation.
init({
  debug: false,
  idleTimeout: 2000,
  networkTimeout: 0,
});

// Reports the last visible change for each navigation that
// occurs during the life of this document.
const unsubscribe = onTTVC((measurement) => {
  console.log('TTVC:', measurement.duration);
});

向收集端点报告衡量标准

import {init, onTTVC} from '@dropbox/ttvc';

init();

let measurements = [];

// capture measurements in client
onTTVC((measurement) => {
  measurements.append(measurement);
});

// flush data to server when page is hidden
document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    navigator.sendBeacon('/log', JSON.stringify(measurements));
    measurements = [];
  }
});

记录一个性能时间线条目

使用 时间线 API (英语).

注:设置任意起始和结束时间 performance.measure 依赖 用户时间等级 3 规格。 这尚未被所有主要浏览器采用.

import {init, onTTVC} from '@dropbox/ttvc';

init();

onTTVC(({start, end, duration, detail}: Metric) => {
  window.performance.measure('TTVC', {
    start,
    end,
    duration,
    detail,
  });
});

使用 React 路由器的客户端导航

@ dropbox/ttvc 支持测量客户端的导航!

在每个应用程序中,什么算作导航可能不同,但只要你发出导航已经开始的信号,这个库就可以找出其余部分.

要启动新的导航测量,呼叫 start() 或发出窗口对象上的“位置更改”事件.

// analytics.js
import {init, onTTVC} from '@dropbox/ttvc';

init();

onTTVC((measurement) => {
  console.log('TTVC:', measurement.duration);
});
// app.js
import {start} from '@dropbox/ttvc';
import React, {useEffect} from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, useLocation} from 'react-router-dom';

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

const App = () => {
  const location = useLocation();

  useEffect(() => {
    // Option 1: If you have access to the ttvc library, import it and
    // call start().
    start();

    // Option 2: Dispatch a custom 'locationchange' event. TTVC subscribes to
    // this and will call start() for you.
    window.dispatchEvent(new Event('locationchange'));
  }, [location]);

  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/" element={<Home />} />
        {/* ... more routes */}
      </Routes>
    </div>
  );
};

将 TTVC 测量的取消归为归属

在某些情况下,@dropbox/ttvc可能会在被捕获之前放弃测量.

如果用户与页面互动或导航远离页面,或者在页面到达状态 ot 视觉完整性之前将页面放入后台,则会发生这种情况.

这样做是为了对测量的准确性获得更高的信心,因为与一页的相互作用会使其变化的方式使测量无效.

然而,@dropbox/ttvc提供了一个监视这些取消并把它们归结到特定原因的方法. 向 onTTVC 当测量被取消时,将调用.

import {init, onTTVC} from '@dropbox/ttvc';

init();

onTTVC(
  (measurement) => {
    console.log('TTVC measurement captured:', measurement.duration);
  },
  (error) => {
    console.log('TTVC measurement cancelled:', error.cancellationReason);
  }
);

API 密码

类型

Metric

export type Metric = {
  // time since timeOrigin that the navigation was triggered
  // (this will be 0 for the initial pageload)
  start: number;

  // time since timeOrigin that ttvc was marked for the current navigation
  end: number;

  // the difference between start and end; this is the value of "TTVC"
  duration: number;

  // additional metadata related to the current navigation
  detail: {
    // if ttvc ignored a stalled network request, this value will be true
    didNetworkTimeOut: boolean;

    // the most recent visible update
    // (this can be either a mutation or a load event target, whichever
    // occurred last)
    lastVisibleChange?: HTMLElement | TimestampedMutationRecord;

    // describes how the navigation being measured was initiated
    // NOTE: this extends the navigation type values defined in the W3 spec;
    // "script" is usually reported as "navigation" by the browser, but we
    // report that distinctly
    // @see https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type
    navigationType: // Navigation started by clicking a link, by entering the
    // URL in the browser's address bar, or by form submission.
    | 'navigate'
      // Navigation is through the browser's reload operation.
      | 'reload'
      // Navigation is through the browser's history traversal operation.
      | 'back_forward'
      // Navigation is initiated by a prerender hint.
      | 'prerender'
      // Navigation is triggered with a script operation, e.g. in a single page application.
      | 'script';
  };
};

CancellationError

export type CancellationError = {
  // time since timeOrigin that the navigation was triggered
  start: number;

  // time since timeOrigin that cancellation occurred
  end: number;

  // the difference between start and end
  duration: number;

  // reason for cancellation
  cancellationReason: CancellationReason;

  // Optional type of event that triggered cancellation
  eventType?: string;

  // Optional target of event that triggered cancellation
  eventTarget?: EventTarget;

  // the most recent visual update; this can be either a mutation or a load event target
  lastVisibleChange?: HTMLElement | TimestampedMutationRecord;

  navigationType: NavigationType;
};

export enum CancellationReason {
  // navigation has occurred
  NEW_NAVIGATION = 'NEW_NAVIGATION',

  // page was put in background
  VISIBILITY_CHANGE = 'VISIBILITY_CHANGE',

  // user interaction occurred
  USER_INTERACTION = 'USER_INTERACTION',

  // measurement was cancelled because a new one was started
  NEW_MEASUREMENT = 'NEW_MEASUREMENT',

  // manual cancellation via API happened
  MANUAL_CANCELLATION = 'MANUAL_CANCELLATION',
}

TtvcOptions

export type TtvcOptions = {
  // decide whether to log debug messages
  debug?: boolean;

  // the duration in ms to wait before declaring the page completely idle
  idleTimeout?: number;

  // a duration in ms to wait before assuming that a single network request
  // was not instrumented correctly
  networkTimeout?: number;
};

职能

init()

type init = (options?: TtvcOptions) -> void;

为当前页面设置了仪器并开始监视. 对于最准确的结果,请在页面装入时尽早调用.

接受选项参数(见上文).

start()

type start = () -> void;

开始新的TTVC测量.

你个 别 初始页面负荷需要调用 。 使用此选项通知 @dropbox/ttvc 新的客户端导航即将进行.

onTTVC()

type onTTVC = (subscriber: (metric: Metric) -> void) -> () => void;

将召回功能注册为新的 TTVC 度量衡的用户 。 返回“ 取消订阅” 函数, 该函数可以调用以取消对已订阅的回调函数的登记 .

如果发生页内导航,调用函数可能不止一次被调用.

onTTVC 可不止一次进行注册.

cancel()

type cancel = (eventType?: string) => void;

中止当前 TTVC 测量 .

这种方法作为出逃舱门提供. 考虑使用 cancel 以通知 @ dropbox/ttvc 已发生用户交互,继续测量可能会产生无效结果.

可以通过一个可选参数来指定触发取消的事件. 该事件的类型将同时被登录到错误回调中.

incrementAjaxCount() & decrementAjaxCount()

type incrementAjaxCount = () -> void;
type decrementAjaxCount = () -> void;

使用这些函数在您的应用程序中为 AJAX 请求提供工具 。 试着保证 incrementAjaxCount 财务报告和审定财务报表 decrementAjaxCount 无论成功还是失败,每项请求都要求一次.

譬如说.

// patch window.fetch
const nativeFetch = window.fetch;

window.fetch = (...args) => {
  TTVC.incrementAjaxCount();
  return nativeFetch(...args).finally(TTVC.decrementAjaxCount);
};

浏览器支持

@dropbox/ttvc 依赖于以下浏览器特性.

请参看在caniuse.com上支持所有以上功能的浏览器:

https://caniuse.com/mutationobserver (中文(中国大陆) ),async-函数,mdn-api 截面观测器,es6,高分辨率时间

如果您想使用此库并支持一个不支持其中之一的浏览器,则您将负责提供多填充和/或重编库去除不支持的语法.

怎么会这样?

浏览器今天不会自动多报告其油漆周期. 如果浏览器开发者决定为我们报告这个值,那肯定是一个改进.

在此期间,我们使用一种基于观测突变和"负载"事件组合的热力学来估计TTVC.

The TTVC Algorithm

更详尽的建筑内容!

https://dropbox.tech/frontend/measuring-ttvc-web-性能-度量-开源-图书馆

发展中国家

要开发此软件包, 您需要节点版本 16 或更多, 以及 yarn 软件包管理器。 一旦您具备了这些先决条件, 便会安装项目依赖性 :

yarn install

大楼

此工程由TypeScript开发. 您可以用 :

$ yarn build

在本地测试时, 您可能会发现在表模式下构建滚动包是有用的 .

$ yarn build:rollup --watch

测试

您可以同时进行所有测试 :

$ yarn test

个人测试

有四个测试脚本

$ yarn test:lint // runs eslint
$ yarn test:typecheck // runs typescript with --noEmit
$ yarn test:unit // runs jest unit tests
$ yarn test:e2e // runs playwright tests (requires yarn build to have been run)

用 Playwright 测试

在运行任何剧作家测试之前,您需要安装默认的一组浏览器:

$ npx playwright install

运行测试套件 :

$ yarn build // build the ttvc package before testing
$ yarn test:e2e

要手动测试页面,请启动测试服务器.

$ yarn express

您可以通过打开 http://localhost:30/test/[test-folder] 在浏览器中启动测试. 例如,http://localhost:30/test/ajax1/

释放

此软件包的配置将使用 np。 。 。 .

要切换新版本,请切换到 main 分支和运行 npm run release。 。 。 .

注:尽管这个软件包是用纱线管理的,但目前 np 预防中有一个错误 yarn np 从运行正确.

这应使释放过程自动化,办法是:

  • 提示您选择新版本
  • 安装所有依赖关系
  • 运行测试
  • 建造新的编译文物
  • 在软件包中切换版本。 json
  • 将新版本推入 npm
  • 在 github.com 上创建新标签并关联"释放"

np 支持一些对您可能有用的 cli 旗帜 :

  • npm run np -- --preview 做个干燥的运行来测试你的释放行为是否如预期
  • npm run np -- patch|minor|major 将版本压缩到下个补丁/ 微分/ 主要增量
  • npm run np -- prerelease --tag=beta 创建“ 预释” 版本, 它将 没有 自动标记为 latest

见 完整文档 向所有人开放 np CLI选项.

版本与发布记录

@dropbox/ttvc 共发布 16 个版本,首次发布于 2022/05/19;过去 12 个月发布了 0 个版本。

版本发布日期距今
3.0.1latest2024/09/142 年前
3.0.02024/04/162 年前
2.3.22024/04/032 年前
2.3.12023/09/213 年前
2.3.02023/09/163 年前
2.2.12023/06/133 年前

其他发布通道:beta → 2.1.1-dash。

关于 @dropbox/ttvc 的常见问题

@dropbox/ttvc 是什么?

实时完成测量

如何安装 @dropbox/ttvc?

在项目目录运行 npm install @dropbox/ttvc,或使用 pnpm add / yarn add / bun add。

@dropbox/ttvc 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dropbox/ttvc 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@dropbox/ttvc 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=16.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@dropbox/ttvc 可以商用吗?

@dropbox/ttvc 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@dropbox/ttvc 的下载量有多少?

根据 npm 官方下载统计,@dropbox/ttvc 在 2026/10/13 – 2026/11/11 这 30 天内被下载 9,410 次,日均约 314 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dropbox/ttvc 还在维护吗?

最新版本 3.0.1 发布于 2024/09/14(2 年前);至今共发布 16 个版本,其中过去 12 个月发布了 0 个;首次发布于 2022/05/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。