大量テキストでの text-wrap パフォーマンス

大規模ページにおける text-wrap: balance と pretty の実測影響、および動的アプリでコストを抑える方法。

Performance

詳細な説明

コストモデル

  • text-wrap: nowrap / wrap: オーバーヘッドゼロ。レガシーな挙動。
  • text-wrap: pretty: 段落あたりほぼ定数のオーバーヘッド(先読みウィンドウ4行)。実用的な段落長では無視できる。
  • text-wrap: balance: O(n²) where n は改行候補数。すべての主要ブラウザで 6行までに制限 されるため、それを超えると balance は静かに無効化され、コストは有界。

実測値

Lighthouse 監査と Chrome の Tracing ツールによると、text-wrap: balance を使う H1・H2 が約20個あるページでも、レイアウトパスへの追加コストは1ms 未満です。text-wrap: pretty を使う段落が数百個あるページでも、フォントレンダリングと比べたコストはほぼゼロです。

パフォーマンスが議論になるのは2つのシナリオだけです:

  1. アニメーション:テキスト幅が毎フレーム動く(60レイアウト/秒)。
  2. ホットエディットループ:キーストロークごとにリフローするリッチテキストエディタ。

パターン1: アニメーションテキストには balance を避ける

見出し幅をアニメーション(パネルの展開・折りたたみヘッダーなど)させる場合は、pretty またはデフォルト wrap を選んでください。balance を毎フレーム再計算すると、ローエンドデバイスで1〜2ms/フレーム のコストとなり、60fps が50fps まで落ちることがあります。

パターン2: balance を正確にスコープする

balance をグローバルに適用してはいけません:

/* 悪い例 — すべてをバランスする */
* { text-wrap: balance; }

/* 良い例 — 恩恵がある要素にスコープする */
h1, h2, h3, .card-title, .tooltip, .form-label {
  text-wrap: balance;
}

パターン3: エディタには stable を使う

text-wrap: stable(Chrome 121+)はライブ編集コンテンツ向けに設計されています。コンテンツが変わっても改行位置を一貫させ、ユーザーのキャレットが飛び回るのを防ぎます。contenteditable 要素に使ってください:

[contenteditable] {
  text-wrap: stable;
}

自分のアプリで計測する

Chrome DevTools → Performance を開き、数秒間のインタラクションを記録して、「Layout」エントリを確認します。「text-wrap」がボトムアップサマリーのホットパスに登場する場合は、調査する価値のある実問題があります。99% のケースでは登場しません。

text-wrap: balance が無効化されるのを確認する

非常に狭いコンテナを設定して8行に折り返させ、balance vs デフォルト wrap を比較すれば、6行の上限を確認できます。両者は同じ結果になります。アルゴリズムが高すぎるとブラウザが判断して、balance を静かに切ったのです。

結論

静的ページでは balance と pretty を遠慮なく使ってください。アニメーションとライブ編集ループでは pretty と stable を選んでください。パフォーマンスのために JavaScript のバランス調整にフォールバックするケースは事実上存在しません — ネイティブ CSS 実装の方が速く、シンプルです。

ユースケース

高性能 SPA、リッチテキストエディタ・CMS(キーストロークごとにテキストがリフローする)、見出しがアニメーションするランディングページ、何千ものテキストウィジェットを持つダッシュボード、TTFB と LCP を計測する SSR サイト。

試してみるCSS text-wrap プレイグラウンド

フルツールを開く