内部計測モジュールに `span` と `track` APIを追加

tailwindlabs/tailwindcss

Tailwind CSSの内部計測モジュール(Instrumentation)に、spantrack という2つの新しい計測APIが追加されました。既存の start/end マーカー方式を補完し、計測コードの記述漏れを構造的に防ぐ設計です。

背景

既存の I.start(label) / I.end(label) 方式には、計測漏れのリスクがありました。複数の return 文を持つ関数では、すべての出口に I.end(label) を記述しなければならず、追加・削除の際に対応する呼び出しを2か所修正する必要がありました。

PRでは、この問題を解決する2つのユースケースが整理されています。1つ目は、toCss(ast) のような1行で完結する処理を計測したいケース。2つ目は、複数行にまたがるブロックを計測したいケースです。前者は関数全体をコールバックで包む span API、後者はブロックの終了時に自動で end を呼ぶ track APIがそれぞれ対応します。

技術的な変更

instrumentation.tstrack メソッドと span メソッドの2つが追加されました。いずれも既存の start/end の薄いラッパーとして実装されており、内部の計測ロジックは変更されていません。

track メソッド は、using 宣言と組み合わせて使用するDisposableオブジェクトを返します。Symbol.disposeSymbol.asyncDispose の両方を実装しており、ブロックのあらゆる出口(正常終了・例外・非同期)で end が呼ばれることを保証します。done フラグにより二重呼び出しも防止されています。

track(label: string) {
  this.start(label)
  let done = false

  return {
    [Symbol.dispose]: () => {
      if (!done) {
        this.end(label)
        done = true
      }
    },
    [Symbol.asyncDispose]: () => {
      if (!done) {
        this.end(label)
        done = true
      }
    },
  }
}

使用例は以下のとおりです:

{
  using _ = I.track('label')
  // ブロック終了時に自動で I.end('label') が呼ばれる
  …
}

span メソッド は、コールバックの結果をそのまま返すジェネリクス T で型付けされており、計測対象の処理をインラインで記述できます。同期・非同期の両方に対応しており、result.then の存在確認でPromiseを検出した場合は finally フックで end を呼ぶ設計です。

span<T>(label: string, fn: () => T): T {
  this.start(label)
  let isPromise = false
  try {
    let result = fn()

    isPromise = result && typeof (result as any).then === 'function'

    // @ts-expect-error — TS can't infer that result is a Promise here
    return isPromise ? result.finally(() => this.end(label)) : result
  } finally {
    if (!isPromise) this.end(label)
  }
}

1行で計測を完結させる典型的な使い方は次のとおりです:

let css = I.span('toCss(…)', () => toCss(ast))

また、コンストラクタに shouldReport パラメータが追加されました。デフォルト値は既存の env.DEBUG ですが、環境変数を変更せずにコード上で計測の有効・無効を切り替えられるようになっています。

設計判断

trackspan を別々のAPIとして提供した点に、明確なトレードオフの整理が見られます。span はコールバックで包む記述コストと引き換えに、インラインで戻り値を利用できる簡潔さを提供します。一方 trackusing 宣言によるインデントへの影響を最小限に抑えつつ、既存コードをほぼそのままに計測を追加できます。

span のPromise検出に instanceof Promise ではなく .then の有無を確認するduck typingを採用している点も注目です。これにより、ネイティブのPromise以外のthenable(例: ライブラリが返すPromise-like オブジェクト)も正しく扱えます。

using キーワードへの依存については、PRでは「計測モジュールはすでにこれに依存していた」と明示されており、既存の前提を踏まえた一貫した拡張といえます。

まとめ

本PRは、既存の start/end APIをベースに、計測漏れを構造的に排除する2つのAPIを追加した変更です。spantrack の使い分けにより、1行の処理から複数行のブロックまで、コードスタイルを大きく変えることなく計測を挿入できるようになりました。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
d3b18591

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

「リード文(総論)→背景・技術的な変更・設計判断(各論)→まとめ(結論)」という構成が明確で、理想的な記事構成です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライトの形式(```typescript:path/to/file.ts)、PR番号へのリンク形式([#123](URL))ともに正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

「Disposableオブジェクト」「duck typing」「thenable」などの専門用語を適切な文脈で使用しており、専門知識を持つエンジニアという対象読者に適合しています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクション、各パラグラフが総論から各論へと展開されており、トピックセンテンスが段落の冒頭に配置されているため、非常に読みやすい構造になっています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内で引用されている`track`と`span`メソッドのコードブロックは、提供されたDiff情報と完全に一致しています。ファイルパスの指定も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`using`宣言、`Symbol.dispose`、`duck typing`といった技術用語が正確かつ効果的に使われており、変更内容の理解を深めています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

追加された`span`と`track` APIの動作原理、同期・非同期処理のハンドリング、`shouldReport`パラメータの役割について、技術的に正確かつ分かりやすく説明されています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(API追加の背景、各APIの目的、設計上の判断など)は、PRのDescriptionやDiff内のコードで裏付けられており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#20119)が正しく記載され、リンクも正確です。その他の固有名詞(メソッド名、ファイルパスなど)もすべて正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「内部計測モジュールに `span` と `track` APIを追加」は、PRの主たる変更点を具体的かつ正確に表現しており、内容と完全に一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事はPRで提供された情報のみに基づいており、バージョンのサポート状況やリリース予定といった外部知識の追記(捏造)はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「既存の...方式にはリスクがあった」「...という2つの新しい計測APIが追加されました」など、変更の前後関係を示す時間表現はPRの内容と一致しており、正確です。