VS Codeのエージェントモードを拡張するには、を試してください!

統合ターミナルのパフォーマンス改善

2017年10月3日 Daniel Imms, @Tyriar

統合ターミナルのレンダリングエンジンは、Visual Studio Codeの次期バージョン1.17に向けて、パフォーマンスを念頭に置いて完全に書き換えられました。このバージョンでは、DOMベースのレンダリングシステムから、HTMLのキャンバス要素を使用するシステムに移行します。

DOMレンダリング

驚くべきことですが、静的なドキュメント表示用に設計されたシステムで、インタラクティブなターミナルをレンダリングすることが可能でした。しかし、時間が経つにつれて、いくつかの問題を解決するために、DOMが提供する特定の機能をオーバーライドする必要があることがわかりました

選択: ターミナルのユースケースをカバーするために、DOMの選択システムに逆らって多くの作業が行われました。DOMに表示されるものだけを常にレンダリングしていたため、選択を再実装せずに複数ページのコンテンツを選択することはできませんでした。スクロールすると選択が解除されることもありました。これらの問題を解決するために、カスタムの選択ロジックが追加されました。

文字のずれ: 多くの等幅フォントが一部のUnicode文字に対して厳密に等幅ではないため、下の画像の右側のような状況が発生することがありました。

Characters to the right of the terminal could become misaligned when Unicode was used

この問題を回避する方法として、すべてのUnicode文字を固定幅のスパンで囲むというものがありましたが、これではフレームのレンダリングにかかる時間が増加します。

過剰なガベージコレクション: ターミナルをレンダリングするために必要な要素の数が多いため、ガベージコレクタは頻繁にメモリをクリーンアップする必要があり、レンダリング時間を著しく遅らせることがよくありました。この問題を回避するためにオブジェクトプールが導入され、DOM要素を再利用できるようになりました。

パフォーマンス: これらの問題を解決するためにどれだけ努力しても、レイアウトエンジンによって課されるハードキャップによってパフォーマンスは常に制限されます。

レイアウトエンジンの迂回

場合によっては、要素を構成してレイアウトを行うだけで1フレーム(16.6ms)よりも時間がかかることがあり、ターミナルでスムーズな60フレーム/秒(FPS)を維持したい場合、これは許容できません。この解決策は、新しいキャンバスベースのレンダリングエンジンでした。

<canvas> HTML要素を使用すると、JavaScript APIを使用してグラフィックとテキストを描画できます。

レンダリングレイヤー

「レンダリングレイヤー」と呼ばれる複数のキャンバス要素を使用して、ターミナルの異なる部分のレンダリングを簡素化します。

現在のレイヤーは、以下の順序です。

  1. テキスト: 背景色と前景テキスト。このレイヤーは不透明です。
  2. 選択: マウスによる選択。
  3. リンク: リンクにカーソルを合わせたときのアンダーライン。
  4. カーソル: ターミナルのカーソル。

これらの部分を独自の小さなコンポーネントに分離することで、描画方法が大幅に簡素化されました。

変更された部分のみを描画

新しいレンダラーの重要な部分は、**変更された**ものだけを描画することです。そのため、セルの描画状態に関する最小限の情報を含むスリムな内部モデルが保持されています。この状態は、高価な描画アクションが実行される前に、セルが変更する必要があるかどうかをすばやく確認するために使用されます。**テキスト**レイヤーの場合、このモデルには文字、テキストスタイル、前景の色、背景の色への参照が含まれています。

これは、何も変更されていない場合でも、行全体がDOMから削除され、再構築され、再追加されていた以前のレンダリングエンジンとは対照的です。

Only individual character changes are now drawn to the screen

上の画像の緑色の長方形は、再描画された領域を示しています。

テクスチャアトラス

テクスチャアトラスは、レンダリング時間をさらに高速化するために使用されます。舞台裏には、デフォルトの背景色で最も一般的なスタイルで、すべてのASCII文字を含むImageBitmapがあります。

これらのスタイルのテキストを描画する場合、CanvasRenderingContext2D.fillTextへの通常の呼び出しの代わりに、テクスチャアトラスが使用されます。ImageBitmapはGPU上に配置されているため、描画速度が大幅に向上します。

Behind the scenes an image is maintained containing the most common characters

強制フレームスキップ

DOMでのレンダリング速度のため、パーサーが十分なCPU時間を確保できるよう、余分なフレームをスキップする必要がありました。これによりコマンドは以前よりも高速に実行できましたが、ターミナルを通じて大量のデータがストリームされると、フレームレートが10 FPSを下回る原因となりました。

新しいレンダラーでは、この制限が解除され、ターミナルで最大60 FPSを楽しむことができるようになりました。

60 frames per second is now possible in the terminal

結果

当社のベンチマークでは、統合ターミナルが状況に応じて**以前よりも約5〜45倍高速にレンダリングされる**ことが測定されました。応答性とフレームレートの向上に気づかなくても、レンダリングが高速化することでバッテリーの使用量も減ります!皆様がパフォーマンスの向上を享受されることを願っています。これらは数日中にVS Codeバージョン1.17に搭載され、現在Insidersビルドでテスト可能です。

さらに詳しく知りたい場合は、この機能を追加したオリジナルのxterm.jsプルリクエストもご覧ください。

ハッピーコーディング!

Daniel Imms、VS Codeチームメンバー @Tyriar