12k
All articles

Pretext とウェブテキストレイアウトの未来

Pretextは、DOM外でテキストを測定してreflowを避け、仮想化リスト、チャットフィード、masonryレイアウトを高速化するTypeScriptライブラリです。

OpenReplay Team
OpenReplay Team
Pretext とウェブテキストレイアウトの未来

ブラウザのレイアウトエンジンは、ほとんどの処理を驚くほど上手くこなします。しかし、数千のテキストブロックの高さを素早く連続して計測する必要が生じると、その限界が見え始めます。まさにこの課題に対処するために開発されたのが Pretext です。

重要なポイント

  • getBoundingClientRect()offsetHeight によって引き起こされる DOM リフローは、ブラウザレンダリングにおける最もコストの高い処理の一つであり、多数のテキストブロックを計測する UI では急速に累積します。
  • Pretext は、prepare()layout() という二段階のアーキテクチャを用いて、DOM の外部でテキストの計測とレイアウトを完全に行う TypeScript ライブラリです。
  • 仮想化リスト、マソンリーグリッド、AI チャットフィード、キャンバスベースの UI など、特定のボトルネックを対象としており、汎用的なページレンダリングを目的としたものではありません。
  • Pretext は、レイアウトと計測をブラウザに委ねるブラックボックス的な処理としてではなく、アプリケーションレベルでプログラマブルに扱うという、より広範なトレンドの転換を示しています。

DOM リフローの真のコスト

DOM 要素に対して getBoundingClientRect() を呼び出したり offsetHeight を読み取ったりすると、ブラウザは応答を返す前にページのジオメトリを再計算するために処理を一時停止しなければなりません。これが レイアウトリフロー であり、複雑な構造を持つページでは、ブラウザレンダリングにおける最もコストの高い処理の一つです。

多くのインターフェースでは、このコストは目に見えません。しかし、仮想化リスト、マソンリーグリッド、AI チャットフィード、あるいは数百のテキストブロックを動的に計測する必要がある UI では、リフローのコストが急速に累積します。その結果、フレームドロップやジャンクが発生し、インターフェースが実際よりも重く感じられるようになります。

これこそが Pretext が対象とする具体的な問題です。CSS でも、一般的なレンダリングでもありません。繰り返しのテキスト計測が繰り返しの DOM リフローを引き起こすという、限定的かつ深刻なケースだけを対象としています。

Pretext のテキスト計測アプローチ

Pretext は、React での業績で知られ、現在は Midjourney のエンジニアである Cheng Lou が開発したオープンソースの TypeScript ライブラリです。二段階のアーキテクチャを使用して、DOM の外部でテキストの計測とレイアウトを完全に行います。

第一フェーズ: prepare()

import { prepare, layout } from '@chenglou/pretext'

const prepared = prepare('Hello, world 🌍', '16px Inter')

これはコストのかかるステップですが、一度だけ実行されます。Pretext は Canvas APImeasureText() メソッドを使用してテキストをセグメント化し、Unicode の改行規則を適用し、すべてのセグメントのピクセル幅をキャッシュします。DOM の読み取りもリフローも発生しません。モダンブラウザのサポートは Intl.Segmenter などの API に依存しており、これらは現在広く利用可能です。

第二フェーズ: layout()

const { height, lineCount } = layout(prepared, 320, 24)
// 純粋な算術処理。DOM なし。リフローなし。

これがホットパスです。コンテナの幅と行の高さを指定すると、キャッシュされたセグメント幅のみを使用して、折り返し後の最終的な高さを計算します。リサイズイベントのたびにこれを呼び出しても、リフローは一切発生しません。

ライブラリのリリース時に共有されたベンチマークによると、500 個のテキストブロックに対する単一のレイアウト操作は、Pretext では約 0.09ms で完了するのに対し、DOM ベースの計測では大幅に時間がかかります。また、このライブラリは、ブラウザ自身のレンダリングを検証のオラクルとして使用した AI 支援の反復プロセスを通じて、混在言語テキスト、双方向スクリプト、絵文字の処理にも対応するよう設計されています。

実際に適した用途

Pretext は CSS の代替品ではありません。視覚的なレンダリング、アクセシビリティツリー、ブラウザのインラインフォーマットモデルの全複雑性を処理するものではありません。特定のボトルネックに特化した専用ツールです。

適した用途は以下の通りです:

  • 仮想化テキストリスト — レンダリング前に正確なアイテムの高さが必要な場合
  • マソンリーレイアウト — カラム配置のためにブロックの高さを事前計算する必要がある場合
  • AI チャットインターフェース — ストリーミングで可変長のメッセージを扱う場合
  • キャンバスまたは WebGL UI — テキストを DOM の外部で完全にフローさせる必要がある場合
  • エディタやフィード — コンテンツの変更に応じてレイアウトが常に再計算される場合

一般的なコンテンツページ、ブログ、マーケティングサイトには Pretext は必要ありません。ブラウザのネイティブレイアウトがそれらのケースを十分に処理できます。

注目すべき広範なトレンドの転換

Pretext は、フロントエンド開発においてより一般的になりつつあるパターンを体現しています。それは、レイアウト、計測、レンダリングをブラウザに委ねるのではなく、アプリケーションレベルでプログラマブルに扱うというアプローチです。react-window や react-virtualized などのライブラリは、リスト仮想化においてすでにこのアプローチを採用しています。Pretext はそれをテキスト計測レイヤー自体にまで拡張するものです。

興味深い問いは、Pretext が何かを置き換えるかどうかではありません。そうではありません。本当の問いは、テキストレイアウトがブラックボックスでなくなったとき、何が可能になるかということです。可変幅のテキストフロー、コンテンツに合わせて縮小するコンテナ、サーバーサイドのレイアウト予測、印刷品質のジャスティフィケーションアルゴリズム、これらすべてが取り組み可能な問題になります。

テキスト計測が実際のボトルネックとなっているインターフェースを構築しているフロントエンド開発者にとって、Pretext は詳しく調べる価値があります。それ以外の方にとっても、ブラウザレンダリングのフロンティアがどこへ向かっているかを示す有益なシグナルとなるでしょう。

まとめ

Pretext はブラウザのレイアウトエンジンを置き換えようとしているわけではありません。繰り返しのテキスト計測という、限定的かつコストの高い一つの問題を切り出し、DOM の外部に出ることでクリーンに解決しています。ほとんどのウェブサイトにとって、この区別は重要ではありません。しかし、仮想化フィード、マソンリーレイアウト、キャンバスベースのインターフェースを構築しているチームにとっては、パフォーマンスの上限を大きく引き上げる手段となります。さらに重要なのは、テキストレイアウトがブラウザの封じ込められた動作ではなく、プログラマブルなプリミティブとなる未来を指し示している点です。

よくある質問

Pretext は CSS やブラウザのレイアウトエンジンを置き換えるものですか?

いいえ。Pretext は DOM の外部でのテキスト計測と折り返し計算のみを処理します。視覚的なレンダリング、アクセシビリティツリーの管理、完全なインラインフォーマットモデルの処理は行いません。実際のレンダリングには引き続き CSS とブラウザに依存します。Pretext はパフォーマンスが重要な計測処理を補完するものであり、ブラウザのレイアウトシステムの代替品ではありません。

Pretext を使用すべきでない場合はどのような場合ですか?

一般的なコンテンツサイト、ブログ、マーケティングページ、あるいは数百のテキストブロックを動的に計測しないインターフェースであれば、Pretext は意味のある効果をもたらさないまま複雑さを増すだけです。そのようなケースではブラウザのネイティブレイアウトで十分に高速です。Pretext を使用するのは、プロファイリングデータで繰り返しのテキスト計測による DOM リフローが確認されたボトルネックである場合に限るべきです。

Pretext は絵文字、混在スクリプト、双方向テキストをどのように処理しますか?

Pretext は Canvas API の measureText メソッドと Unicode の改行規則を組み合わせてテキストのセグメント化を行います。絵文字、双方向スクリプト、混在言語コンテンツをサポートするよう設計されており、その動作はブラウザ自身のレンダリングを正確性の検証オラクルとして比較する AI 支援の反復プロセスを通じて精緻化されています。

Pretext は SSR や事前レンダリングのシナリオでサーバー上で実行できますか?

現時点では完全には対応していません。Pretext は現在ブラウザ環境に焦点を当てていますが、サーバーサイドのサポートはプロジェクトで議論されており、互換性のある canvas 実装が利用可能な環境では実用的になる可能性があります。サーバーサイドのレイアウト予測や事前計算された高さは興味深い将来のユースケースですが、現時点では実験的なものとして扱うべきです。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.