# @dropbox/ttvc 中文文档

规范地址：https://npmcn.com/package/%40dropbox/ttvc/

版本：3\.0\.1
npm 元数据更新时间：2026-05-18T22:23:48.284Z
中文译文更新时间：2026-11-12T20:27:42.579Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40dropbox/ttvc
原文对照：https://npmcn.com/package/%40dropbox/ttvc/?lang=original
源码仓库：https://github.com/dropbox/ttvc

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：119 kB，32 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=16\.0\.0
- 运行依赖：0 个
- 首次发布：2022-05-19T00:12:48.223Z
- 最新版本发布：2024-09-13T20:05:45.058Z
- 近 30 天下载量：9410（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：16（近 12 个月 0 个）

## 中文简介

实时完成测量

## 安装

```sh
npm install @dropbox/ttvc
```

也可以使用：`pnpm add @dropbox/ttvc`、`yarn add @dropbox/ttvc`、`bun add @dropbox/ttvc`

## README

# `ttvc`

![version](https://img.shields.io/npm/v/@dropbox/ttvc) ![minzip size](https://img.shields.io/bundlephobia/minzip/@dropbox/ttvc)

![lint](https://img.shields.io/github/actions/workflow/status/dropbox/ttvc/lint.yml?branch=main&label=lint) ![unit](https://img.shields.io/github/actions/workflow/status/dropbox/ttvc/unit.yml?branch=main&label=unit) ![playwright](https://img.shields.io/github/actions/workflow/status/dropbox/ttvc/playwright.yml?branch=main&label=playwright)

-   [概览](https://npmcn.com/package/%40dropbox/ttvc/#readme-overview)
-   [开始吧](https://npmcn.com/package/%40dropbox/ttvc/#readme-get-started)
-   [使用量](https://npmcn.com/package/%40dropbox/ttvc/#readme-usage)
    -   [基本用途](https://npmcn.com/package/%40dropbox/ttvc/#readme-basic-usage)
    -   [向收集端点报告衡量标准](https://npmcn.com/package/%40dropbox/ttvc/#readme-report-metrics-to-a-collection-endpoint)
    -   [记录一个性能时间线条目](https://npmcn.com/package/%40dropbox/ttvc/#readme-record-a-performancetimeline-entry)
    -   [使用 React 路由器的客户端导航](https://npmcn.com/package/%40dropbox/ttvc/#readme-client-side-navigation-with-react-router)
    -   [将 TTVC 测量的取消归为归属](https://npmcn.com/package/%40dropbox/ttvc/#readme-attributing-ttvc-measurement-cancellations)
-   [API 密码](https://npmcn.com/package/%40dropbox/ttvc/#readme-api)
    -   [类型](https://npmcn.com/package/%40dropbox/ttvc/#readme-types)
    -   [职能](https://npmcn.com/package/%40dropbox/ttvc/#readme-functions)
-   [浏览器支持](https://npmcn.com/package/%40dropbox/ttvc/#readme-browser-support)
-   [怎么会这样?](https://npmcn.com/package/%40dropbox/ttvc/#readme-how-does-it-work)
-   [发展中国家](https://npmcn.com/package/%40dropbox/ttvc/#readme-developing)
    -   [大楼](https://npmcn.com/package/%40dropbox/ttvc/#readme-building)
    -   [测试](https://npmcn.com/package/%40dropbox/ttvc/#readme-testing)
    -   [释放](https://npmcn.com/package/%40dropbox/ttvc/#readme-releasing)

## 概览

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

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

## 开始吧

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

```
$ npm install @dropbox/ttvc
```

```
$ yarn add @dropbox/ttvc
```

## 使用量

### 基本用途

```js
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);
});
```

### 向收集端点报告衡量标准

```js
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 = [];
  }
});
```

### 记录一个性能时间线条目

使用 [时间线](https://developer.mozilla.org/en-US/docs/Web/API/Performance_Timeline) API (英语).

注:设置任意起始和结束时间 `performance.measure` 依赖 [用户时间等级 3](https://w3c.github.io/user-timing/) 规格。 这尚未被所有主要浏览器采用.

```js
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()` 或发出窗口对象上的“位置更改”事件.

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

init();

onTTVC((measurement) => {
  console.log('TTVC:', measurement.duration);
});
```

```js
// 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` 当测量被取消时,将调用.

```js
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`

```typescript
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`

```typescript
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`

```typescript
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()`

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

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

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

#### `start()`

```typescript
type start = () -> void;
```

开始新的TTVC测量.

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

#### `onTTVC()`

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

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

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

`onTTVC` 可不止一次进行注册.

#### `cancel()`

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

中止当前 TTVC 测量 .

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

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

#### `incrementAjaxCount() & decrementAjaxCount()`

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

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

譬如说.

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

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

## 浏览器支持

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

-   [ES6 语法](https://262.ecma-international.org/6.0/)
-   [语法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
-   [窗口。 变异观察员](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
-   [窗口。 交叉观察员](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
-   [性能。 现在( )](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now)

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

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

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

## 怎么会这样?

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

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

![The TTVC Algorithm](https://user-images.githubusercontent.com/11449340/217963862-617c379c-2efd-4cc3-9c74-aa58afe7b1da.png)

更详尽的建筑内容!

[https://dropbox.tech/frontend/measuring-ttvc-web-性能-度量-开源-图书馆](https://dropbox.tech/frontend/measuring-ttvc-web-performance-metric-open-source-library)

## 发展中国家

要开发此软件包, 您需要节点版本 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`](https://github.com/sindresorhus/np#readme)。 。 。 .

要切换新版本,请切换到 `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`

见 [完整文档](https://github.com/sindresorhus/np#readme) 向所有人开放 `np` CLI选项.

## 常见问题

### @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 和提交记录判断。

