このページは機械翻訳のため、誤りを含む場合があります。 英語の原文を読む

ドキュメント

パフォーマンスレポート

NSH アプリのコストを実測した結果です。NSH がアプリを高速に保つ仕組みと、自分のアプリを計測する方法については Performance を参照してください。

#ベースライン

NSH 自身のベースラインです(特記がない限り Apple silicon)。

シナリオ数値
カウンターアプリ、ヘッドレス(デバッグ)最初のフレーム約 0.5〜0.65 ms(58 ops / 49 mount items)、タップ 1 回あたり約 0.15 ms
カウンターアプリ、Mac Catalyst(リリース)最初のフレーム約 1.05〜1.15 ms(うち約 0.7 ms は CoreText による 10 個のテキストの初回レイアウト)、タップ 1 回あたり約 0.12 ms
Gallery の写真リスト、ヘッドレス(デバッグ)最初のフレーム 653 ops / 224 nodes、約 2.7 ms
写真リストのスクロール、Catalyst(リリース)ゆっくりスクロール中の 1 行の再バインド 約 0.4 ms、速いフリングでの約 32 行ぶんの 1 画面 0.9〜1.6 ms
写真リストのスクロール、Android エミュレーター(arm64、リリース)1 行の再バインド 約 0.3〜0.4 ms(JS は約 60 µs)
エンジンの起動(リリース)約 75〜155 µs。グローバル API(fetch、URL など)は初めて使われるまでコストがかからず、使用時に約 90 µs
ホットリロードファイルの保存から新バージョンの実行まで約 120 ms、更新の適用は 0.2〜0.5 ms

#Linux (GTK 4)

Linux デスクトップ(x86_64、24 スレッド、NVIDIA GPU)でリリースビルドを使い、120 Hz ディスプレイ上の 1896 × 1030 ウィンドウで gallery を動かして計測しました。すべての値は examples/gallery/tools/perf.py(nsh test --target linux --fps)が自動的に取得したもので、1 秒に 1 行出力されます。CPU はプロセス全体の値で、コア 1 つぶんを 100% とした割合です。Frame p95 は、描画された 1 フレームあたりのメインスレッドの所要時間の 95 パーセンタイルです。8.3 ms 未満であれば、1 フレームが 120 Hz のリフレッシュに収まります。

#アニメーションのデモ

デモFPSFrame p95CPU
Stocks: 22 本のライブスパークライン、日中チャート、板情報、ティッカーテープ117–1205–6 ms25–29%(1200 × 800)、28–32%(1896 × 1030)
Stocks、ウィンドウが 4K 144 Hz ディスプレイ全体を 1.6 倍で占める場合143–1454.1–4.4 ms26–29%
Canvas: ゲージ、時計、ドットマトリクス1202.6–4.4 ms5–10%
Animations: 3 つのネイティブループ、スプリング、シーケンス1202.0 ms12–13%

#全ページ

gallery の全ページについて、ページを開いたときと、テストがスクロールしている間の値です。同じマシンの 144 Hz ディスプレイ上、1200 × 800 のウィンドウで計測しました。NSH は画面上で何かが変化したときだけフレームを描画するため、ここでの FPS は何かが動いている間のレートで、描画されたフレーム間隔の中央値 1 つぶんを 1 フレームとして算出しています(perf.pyの moving)。ディスプレイの 144 では、アニメーションやスクロールのすべてのフレームが直前のフレームの 1 リフレッシュ後に届きます。リフレッシュ超過率 は、1 リフレッシュ(6.9 ms)より長くかかったフレームの割合です。Images の GIF と WebP は、動画と同様、それぞれ固有のフレームレート(ここでは約 50 FPS)で再生されます。Physics、Overlays、Menus は内容が短く、1200 × 800 ではスクロールが数フレームで末尾に達してしまうため、スクロールの余地がある 900 × 500 のウィンドウで計測しています。

ページフレームの発生源FPSFrame p95リフレッシュ超過率CPU
Stocksライブデータ、ネイティブループ1444.1 ms0%26%
Stocks、スクロールライブデータ、スクロール1444.1 ms0%25%
Photos、スクロールスクロール1442.8 ms2%9%
Lists、スクロールスクロール1431.7 ms0%7%
Scrolling、スクロールスクロール1441.6 ms1%4%
Navigation、スクロールスクロール1431.7 ms0%2%
Form、スクロールスクロール1441.3 ms0%4%
Resizable、スクロールスクロール1430.6 ms0%1%
Dock、スクロールスクロール1420.5 ms1%1%
Gesturesスプリング、脈動するリング1441.6 ms0%1–5%
Physics、スクロールスクロール(900 × 500 のウィンドウ)1441.6 ms1%1%
Animationsネイティブループ1442.6 ms0–1%5%
Canvas、スクロールスクロール、ネイティブループ1444.2 ms0%1–4%
Styles、スクロールスクロール1442.3 ms2%3%
Tailwindanimate-* ユーティリティ1441.7 ms0%3–8%
Text、スクロールスクロール1441.9 ms0%4%
Text View、スクロールスクロール1411.8 ms2%7%
Images、スクロールスクロール、GIF と WebP のフレーム1432.9 ms2%8%
Components、スクロールスクロール1441.4 ms0%3%
Overlays、スクロールスクロール(900 × 500 のウィンドウ)1441.7 ms0%2%
Menus、スクロールスクロール(900 × 500 のウィンドウ)1441.9 ms0%2%
Controlsトランジション1440.9 ms0%1–4%
Web and video動画フレーム、ページ135–1421.0 ms0%7–8%

#メモリ

起動 3 秒後の安止状態の値です(リリースのランナー、480 × 640 のウィンドウ)。Private はそのプロセスだけが所有するメモリ(USS)です。Resident にはこれに加えて共有ライブラリ(GTK、GPU ドライバー)のページが含まれ、これらはマシン上のすべての GTK アプリで共有されます。

アプリレンダラーPrivate (USS)Resident (RSS)
Rust アプリ(nsh init --template rust)GL(ngl)約 49 MB約 142 MB
Rust アプリCairo(GSK_RENDERER=cairo)約 28 MB約 95 MB
TSX カウンター(examples/counter)GL約 79 MB約 166 MB
参考: ラベル 1 つだけの GTK 4 ウィンドウVulkan / Cairo約 62 / 約 40 MB約 132 / 約 109 MB

すでに開いたページに戻ってもメモリは増えません。ページを初めて開くと、意図的にキャッシュするもの(デコード済み画像。上限 128 MB)と、初回使用時に読み込まれるライブラリ(Web ビュー用の WebKitGTK)のぶんだけプロセスが大きくなります。

#アプリのサイズ

nsh init で各テンプレートから作成した Hello world アプリと、実際に使われている 2 つのアプリを、nsh package --target linux が x86_64 向けにビルドした場合のサイズです。ランナーはアプリの唯一の実行ファイルで、アーカイブはそれを配布する形式の .tar.gz です。Hello world はリンク時最適化を有効にし、strip してビルドしています(CARGO_PROFILE_RELEASE_LTO=fat、CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1、CARGO_PROFILE_RELEASE_STRIP=true)。

アプリ記述言語ランナーアーカイブ
Hello world(--template rust)Rust16.5 MB7.5 MB
Hello world(--template ts)TSX、QuickJS 上25.7 MB11.6 MB
Hello world(--template mixed)TSX と Rust クレート25.8 MB11.7 MB
sysmon 0.1.3Rust20.9 MB(strip 済み)9.7 MB
Omasend 0.2.0Rust22.3 MB9.8 MB

TSX のランナーには QuickJS ランタイム、ネイティブモジュール、レンダラーが含まれます。アプリ自身のコードはランナーの隣に置かれるバンドルで、Hello world では 1 KB 未満です。

これらの数値を支えているもの:

  • レンダラー: NVIDIA のドライバー環境では、NSH は GSK の GL レンダラーで描画します。この環境では、Vulkan レンダラーよりフレームのコストがはるかに小さくなります(Animations デモ: 1 フレームあたりの描画が約 9.5 ms ではなく約 1 ms)。それでも最終的な選択は GSK_RENDERER が行います。
  • Canvas のラスタライズ: 各 canvas は一度だけ 256 px のタイルにラスタライズされ、GPU 上に保持されます。アニメーションする値は、その値を読む操作がカバーする領域だけを、描画の静的な部分の保持済みピクセルの上に再描画します。画面外にある canvas は、スクロールで表示されるまで待機します。
  • パスを一度だけ確保: 長いパスのあとの fillRect と fillText は、そのパスが再び使われるまでそのまま残します(400 点の折れ線のあとに 240 本の棒: 0.63 ms)。

#macOS (AppKit)

MacBook Pro(Apple M3、24 GB)の内蔵 120 Hz ProMotion ディスプレイ上で、リリースビルドを使い、1200 × 800 のウィンドウで gallery を動かして計測しました。すべての値は examples/gallery/tools/perf.py(nsh test --target macos --fps、1 秒に 1 行出力)が自動的に取得したものです。CPU はプロセス全体の値でコア 1 つぶんを 100% とした割合、GPU は GPU に占める割合です。フェーズはフレームごとのメインスレッドの処理で、tick(ディスプレイリンクのネイティブアニメーション)と canvas(描画のリプレイ)があります。

#アニメーションのデモ

デモFPSFrame p95CPUGPU
Stocks: 22 本のライブスパークライン、日中チャート、板情報、ティッカーテープ1202.7–3.7 ms33–36%18–22%
Canvas: ゲージ、時計、ドットマトリクス119–1200.6–0.7 ms4–7%0%
Animations: 3 つのネイティブループ、スプリング、シーケンス119–1200.3–1.6 ms5–8%0%

Stocks では、1 フレームあたりのメインスレッド時間は tick が約 1.6 ms で、そのうち約 0.45 ms は canvas のアニメーション部分のリプレイです。各 canvas の残りの部分は、Core Animation が専用のスレッドで描画します。

#全ページ

gallery の全ページについて、ページを開いたときと、テストがスクロールしている間の値を、同じ 1200 × 800 のウィンドウで計測しました。Linux と同様に、FPS は何かが動いている間のレート(描画されたフレーム間隔の中央値 1 つぶんを 1 フレームとして算出)です。ディスプレイの 120 では、アニメーションやスクロールのすべてのフレームが直前のフレームの 1 リフレッシュ後に届きます。リフレッシュ超過率 は、1 リフレッシュ(8.3 ms)より長くかかったフレームの割合です。静止しているページはフレームを描画せず、CPU 使用率は 2〜5% です。Images の GIF と WebP は Core Animation で、動画は AVFoundation で、それぞれ固有のフレームレートで再生されます。

ページフレームの発生源FPSFrame p95リフレッシュ超過率CPU
Stocksライブデータ、ネイティブループ1203.2 ms0%35%
Stocks、スクロールライブデータ、スクロール1203.5 ms0%36%
AI Chat、スクロールスクロール1202.4 ms1%5%
Photos、スクロールスクロール1201.4 ms0%10%
Lists、スクロールスクロール1201.6 ms0%8%
Scrolling、スクロールスクロール1202.7 ms0%6%
Navigation、スクロールスクロール1200.2 ms0%4%
Form、スクロールスクロール1200.6 ms0%5%
Resizable、スクロールスクロール1200.3 ms0%4%
Dock、スクロールスクロール1200.3 ms1%5%
Gesturesスプリング、脈動するリング1200.4 ms0%4%
Physics、スクロールスクロール1200.3 ms0%4%
Animationsネイティブループ1200.3 ms0%5%
Canvas、スクロールスクロール、ネイティブループ1201.2 ms0%7%
Styles、スクロールスクロール、揺れる transform1201.0 ms0%6%
Tailwindanimate-* ユーティリティ1200.5 ms0%4%
Text、スクロールスクロール1200.3 ms0%5%
Text View、スクロールスクロール1200.7 ms0%5%
Images、スクロールスクロール1200.4 ms0%5%
Components、スクロールスクロール1200.3 ms0%5%
Overlays、スクロールスクロール1200.3 ms0%4%
Menus、スクロールスクロール1200.3 ms0%5%
Controlsトランジション1200.3 ms0%4%
Web and video、スクロールスクロール1200.2 ms0%6%
SystemrequestAnimationFrame、タイマー1200.2 ms0%3%
Standard APIs、スクロールスクロール1200.3 ms0%5%
Storage、スクロールスクロール1200.3 ms0%5%

#メモリ

起動 3 秒後の安止状態の値です(リリースのランナー)。Footprint は macOS がそのプロセスに計上するメモリ(アクティビティモニタに表示される値)です。Resident にはこれに加えて、システムの共有ライブラリのページが含まれます。

アプリウィンドウFootprintResident (RSS)
Rust アプリ(nsh init --template rust)1200 × 800約 19 MB約 86 MB
TSX カウンター(examples/counter)1200 × 800約 20 MB約 89 MB
参考: ラベル 1 つだけの AppKit ウィンドウ480 × 640約 17 MB約 80 MB

gallery のツアー中、プロセスのメモリ使用量は Canvas ページまでは 84〜230 MB、Text View ページ以降は約 350〜360 MB です。これは、意図的にキャッシュするもの(デコード済み画像は上限 128 MB、Text View ページのドキュメント)と、初回使用時に読み込まれるフレームワーク(Web ビュー用の WebKit)によるものです。Canvas ページのラスタは、3 つの canvas がすべて画面に表示されているときで最大約 310 MB になり、ページを閉じると解放されます。

#アプリのサイズ

nsh init が各テンプレートで作成した hello world アプリを、nsh package --target macos が Apple silicon (arm64) 向けにビルドしたもの(Linux と同様にリンク時最適化とストリップを適用)と、上記の 2 つのアプリを Apple silicon 向けの配布形態のまま計測しました。実行ファイルは .app 内のランナーです。zip は .app を圧縮したものです(ditto -c -k):

アプリ記述言語実行ファイルzip 圧縮後 .app
Hello world (--template rust)Rust12.4 MB6.0 MB
Hello world (--template ts)TSX(QuickJS 上)19.8 MB9.5 MB
Hello world (--template mixed)TSX と Rust クレート19.8 MB9.5 MB
sysmon 0.1.3Rust21.6 MB8.4 MB(リリースの .tar.gz)
Omasend 0.2.0Rust18.4 MB9.7 MB(リリースの .tar.gz)

これらの数値を支えている仕組み:

  • 変更があるときだけフレームを生成: ディスプレイリンクはネイティブアニメーションの実行中のみティックし、アニメーションの終了とともに停止します。アニメーションはそのページとともに停止します(ビューが削除されるとそのキーフレームは終了し、ループはコンポーネントの cleanup で停止します)。
  • キャンバスはコストが最も低い場所で描画: 頻繁に描画されるキャンバス(アニメーションやライブデータ)は Core Animation のスレッド(drawsAsynchronously)で描画され、メインスレッドを空けておけます。たまにしか再描画されないキャンバスは即座に描画され、非同期描画が保持するグラフィックスメモリを使いません。アニメーションする値が変わると、その値を読み取る操作がカバーする領域だけが再描画されます。
  • 静的なキャンバス部分を保持: 描画内容が変わらなくなると、最初のアニメーション操作より前にある長い部分がレイヤーとして保持されます。各フレームではそのレイヤーを描画し、アニメーションする残りの部分だけをメインスレッド上で即座に再生します(Canvas ページのゲージ、時計、ドットマトリクスでは、GPU 処理が不要になりメモリは半分になります)。
  • 内容が変わったときだけ描画: テキストとキャンバスはそれぞれ専用のレイヤーに描画され、内容やサイズが変わったときに再描画されます。移動やスクロールでは再描画されません。

#Windows (Win32, Direct2D)

Windows 11 デスクトップ(Intel Core i7-13700KF、32 GB、NVIDIA GeForce RTX 3060 Ti)の 4K 144 Hz ディスプレイ(150%)で、リリースビルド、ギャラリーは 1200 × 800 のウィンドウ(1800 × 1200 ピクセル)として計測しました。すべての値は examples/gallery/tools/perf.py(nsh test --target windows --fps、1 秒に 1 行)によって自動的に取得しています。CPU はプロセス全体で、1 コアに対するパーセントです。各フェーズはメインスレッドの 1 フレームあたりの値で、paint(Direct2D によるウィンドウの描画)と、その内数の canvas(描画の記録と再生)があります。

#アニメーションのデモ

デモFPSフレーム p95フレームあたりの paint / canvasCPU
Stocks: ライブのスパークライン 22 本、日中チャート、板、歩み値1443.7–4.3 ms1.4 / 0.13 ms36–43%
Canvas: ゲージ、時計、ドットマトリクス1441.0–2.0 ms0.8–1.4 / 0.05 ms21–35%
Animations: 3 つのネイティブループ、スプリング、シーケンス1441.0–3.6 ms0.9–1.9 ms20–41%

Stocks は毎秒 16~17 回コミットし、各コミットはエンジンスレッド上で最大 2.1 ms の JS と 1.7 ms のコアで処理されます(p95)。

#すべてのページ

ギャラリーのすべてのページについて、同じ 1200 × 800 のウィンドウで、ページを開いたときとテストがスクロールしている間を計測しました。Linux や macOS と同様に、FPS は何かが動いている間のレートです(描画されたフレーム間隔の中央値あたり 1 フレーム)。ディスプレイの 144 Hz では、アニメーションやスクロールのフレームはすべて直前のフレームの 1 リフレッシュ後に届きます。1 リフレッシュ超過は、フレームが 1 リフレッシュ(6.9 ms)より長くかかった割合です。静止しているページはフレームを描画せず、CPU 使用率は 0–2% です。Images の GIF と WebP はそれぞれ固有のフレームレート(ここでは約 40 FPS)で再生されます。Physics、Overlays、Menus、Storage は、スクロールの余地がある 900 × 500 のウィンドウで計測しています。

ページフレームの発生源FPSフレーム p951 リフレッシュ超過CPU
Stocksライブデータ、ネイティブループ1443.9 ms0%36%
Stocks, scrollingライブデータ、スクロール1444.3 ms0%43%
Photos, scrollingスクロール1432.1 ms0%9%
Lists, scrollingスクロール1442.0 ms1%19%
Scrolling, scrollingスクロール1432.1 ms0%7%
Navigation, scrollingスクロール1440.8 ms0%9%
Form, scrollingスクロール1440.8 ms0%12%
Resizable, scrollingスクロール1430.4 ms0%4%
Dock, scrollingスクロール1440.5 ms1%5%
Gesturesスプリング、脈動するリング1441.8 ms0%36%
Physics, scrollingスクロール(900 × 500 のウィンドウ)1440.8 ms0%4%
Animationsネイティブループ1441.0 ms0%28%
Canvas, scrollingスクロール、ネイティブループ1442.0 ms0%35%
Styles, scrollingスクロール、揺れる transform1442.1 ms0%39%
Tailwindanimate-* ユーティリティ1440.6 ms0%19%
Text, scrollingスクロール1441.6 ms0%8%
Text View, scrollingスクロール1441.1 ms0%10%
Images, scrollingスクロール、GIF と WebP のフレーム1434.8 ms2%23%
Components, scrollingスクロール1441.0 ms1%11%
Overlays, scrollingスクロール(900 × 500 のウィンドウ)1440.6 ms0%1%
Menus, scrollingスクロール(900 × 500 のウィンドウ)1440.6 ms0%2%
Controlsトランジション117–1441.5 ms0%22%
Web and video, scrollingスクロール1441.6 ms0%15%
SystemrequestAnimationFrame、タイマー144< 0.1 ms0%1%
Storage, scrollingスクロール(900 × 500 のウィンドウ)1440.5 ms0%1%

#メモリ

起動 3 秒後の静止時の値です(リリースランナー、1200 × 800 のウィンドウ)。プライベートワーキングセットはプロセスだけが使用するメモリ(タスクマネージャーの「メモリ」列)、プライベートバイトはプロセスがコミットしたメモリ、ワーキングセットはそれに加えて、他のプロセスと共有するシステムライブラリ(Direct3D、Direct2D、DirectWrite、GPU ドライバー)のページを含みます:

アプリプライベートワーキングセットプライベートバイトワーキングセット
Rust アプリ (nsh init --template rust)約 14 MB約 60 MB約 53–71 MB
TSX カウンター (examples/counter)約 15 MB約 61 MB約 56–71 MB

ギャラリーのツアー中のワーキングセットは、Stocks で約 108–115 MB、Canvas ページから約 230 MB、Text View ページから約 320–340 MB、Web and video が WebView2 を開いた後で約 390–405 MB になります(WebView2 のページは WebView2 自身のプロセスで動作します)。これには意図的にキャッシュしているもの(デコード済み画像は 128 MB が上限、Text View ページのドキュメント)が含まれます。

#アプリのサイズ

nsh init が各テンプレートで作成した hello world アプリを、nsh package --target windows が x86_64 向けにビルドしたもの(Rust ランナーは Linux と同様にリンク時最適化とストリップを適用)です。実行ファイルはアプリの <Name>.exe です。zip はそのディレクトリの隣に書き出される .zip です:

アプリ記述言語実行ファイルzip
Hello world (--template rust)Rust15.0 MB6.7 MB
Hello world (--template ts)TSX(QuickJS 上)28.6 MB12.4 MB
Hello world (--template mixed)TSX と Rust クレート26.3 MB11.5 MB

これらの数値を支えている仕組み:

  • 変更があるときだけフレームを生成し、変更された場所だけを描画: コンポジターに同期したティッカーは、ネイティブアニメーション、トランジション、またはフレームコールバックの実行中に動作します。1 フレームでは、変更されたビューの領域(以前の位置と現在の位置)を、ウィンドウが保持しているピクセルの上に描画し、その部分だけをコンポジターに提示します(Stocks: 1 フレームあたり約 34 ビュー)。
  • キャンバスはアニメーションする部分を記録: 描画は Direct2D のコマンドリストとして記録され、どの倍率でもベクターのままシャープに表示されます。アニメーションする値が変わると、アニメーションする値を最初に読み取る操作以降だけが再記録され、それより前の部分は保持されます(Stocks: 脈動するスパークライン 22 本とチャートで、1 秒あたり約 26 ms の記録)。
  • 見えているものだけを描画: スクロールビューやクリッピングビューの子のうち、視界の外にあるものはフレームから除外されます。自身のコンテンツを持たないビューは、背景と枠線以外を描画しません。

#iOS (UIKit)

iOS シミュレーター(iPhone 18 Pro Max、前述の MacBook Pro 上)で、リリースビルド、同じツアー(perf.py --target ios: nsh test --target ios --fps、UIKit が受け取る指のタッチ)を使って計測しました。シミュレーターは 60 Hz で表示します。ProMotion 搭載の iPhone では、NSH のディスプレイリンクは画面の 120 Hz で動作します(nsh package がビルドするアプリと開発ホストは、CADisableMinimumFrameDurationOnPhone でこれを要求します)。各フェーズは tick(ネイティブアニメーション)、drain(エンジンのバッチの適用)、scroll(スクロールビューに追従する処理: リスト、スティッキーセル、バインドされた値)です。

ページフレームの発生源FPSフレーム p95CPU
Home, scrollingスクロール600.1 ms6%
Stocksライブデータ、ネイティブループ600.3 ms22%
Stocks, scrollingライブデータ、スクロール600.3 ms25%
Photos, scrollingスクロール601.2 ms6%
Lists, scrollingスクロール601.1 ms8%
Scrolling, scrollingスクロール600.1 ms7%
Navigation, scrollingスクロール600.2 ms7%
Form, scrollingスクロール600.3 ms7%
Gesturesスプリング、脈動するリング600.3 ms3%
Animationsネイティブループ600.7 ms6%
Canvasネイティブループ600.4 ms16%
Styles揺れる transform600.4 ms4%
Tailwind, scrollingスクロール600.2 ms7%
Text, scrollingスクロール600.1 ms7%
Text View, scrollingスクロール600.1 ms6%
Images, scrollingスクロール600.1 ms5%
Components, scrollingスクロール600.2 ms6%
Overlays, scrollingスクロール600.1 ms6%
Menus, scrollingスクロール600.2 ms7%
Controls, scrollingスクロール、トランジション600.2 ms5%
Web and video, scrollingスクロール600.1 ms8%
SystemrequestAnimationFrame、タイマー600.3 ms4%
Standard APIs, scrollingスクロール600.1 ms7%
Storage, scrollingスクロール600.1 ms8%

FPS は前述と同じく、何かが動いている間のレートです。シミュレーターの 60 Hz では、すべてのフレームが直前のフレームの 1 リフレッシュ後に届きます。何も動いていないページはフレームを描画せず、静止時の CPU 使用率は 1–2% です。プロセスのメモリ使用量は、ギャラリーのホームページで 40 MB、ツアー全体の後で約 180 MB です(意図的にキャッシュしている画像と、Text View ページのドキュメントを含みます)。

iPhone 17 Pro(ProMotion、120 Hz)で、開発ホストと 1 つのデモを画面に表示した状態では、アニメーションするページはリフレッシュのたびに描画します:

ページフレームの発生源FPSフレーム p951 リフレッシュ超過CPUメモリ
Stocksライブデータ、ネイティブループ1200.2–0.3 ms0%46–70%41–43 MB
Canvasネイティブループ1200.1 ms0%25–36%37–38 MB
Animationsネイティブループ1200.2 ms0%3–11%37 MB

Stocks は毎秒 20 回コミットし(50 ms ごとのティック)、各コミットはエンジンスレッド上で 1.5 ms の JS と 1.4 ms のコアで処理されます(p95 はそれぞれ 2.2 ms と 2.0 ms)。エンジンスレッドの稼働率は 4–6% です。

#アプリを計測する

同じ方法でアプリを計測するには、--target linux、macos、windows、ios のいずれかで、--fps と -v を使ってテストまたはステップを実行します:

cargo build --release -p nsh-cli
python3 examples/gallery/tools/perf.py --target macos --only Stocks,Canvas   # the gallery, page by page
echo 'await app.wait(5000)' | nsh -v test App.tsx --target linux --fps        # any app