raw-view モジュールルックアップのキャッシュによる FCP/LCP の最適化

これらの2つのPRで、First Contentful Paint (FCP) と Largest Contentful Paint (LCP) の改善を試みています。

これらの変更による実際の効果について、ぜひ試してフィードバックをいただけると幸いです。

もちろん、テスト、リファクタリング、テストカバレッジに関するご協力も大歓迎です。

「いいね!」 11

最初の最適化は簡単なもので、理にかなっていると思います。@david@eviltrout がこの領域の最適化に時間を費やしたので、彼らがどう思うか非常に興味があります。

2番目の最適化は、長期的に見て少し壊れやすいように感じます。最適化したい気持ちは完全に理解できますが、メンテナンスが必要な領域になるため、少し心配です。

「いいね!」 5

@rritさん、PRありがとうございます。最初のものは良い改善のように思えます。パフォーマンスへの影響を測定できましたか?どれくらい時間を節約できますか?

@samが言ったように、2番目の保守性は少し懸念されます。Emberのソースコードからコピー&ペーストしたように見えますか?パフォーマンスを改善するために何か変更しましたか?

「いいね!」 4

lookupView-patch

Array の代わりに Map を使用するように実装しました。

lookupView でのアプリケーション起動時間(開発インスタンスの場合):

  • パッチなし:124 ms
    Firefox ProfilerlookupView にフィルタリングされたコールスタック)

  • パッチあり:9 ms
    Firefox ProfilerlookupView にフィルタリングされたコールスタック)

節約時間:約 115 ms

これにより、appendOutletView での時間が開発インスタンスで 1.083 ms から 946 ms に減少します。


raw handlebar helpers へのパッチ

はい、実際にはコピー&ペーストで、変更点は 1 つだけです。isPath のための安価なチェックを使用します。

      // @ember/-internals/utils isPath を置き換えます
      // @see: https://github.com/emberjs/ember.js/blob/3537670c14883346e11e841fcb71333384fcbc87/packages/%40ember/-internals/metal/lib/path_cache.ts#L5-L7
      // @see: https://github.com/emberjs/ember.js/blob/255a0dd3c7de1187f4a2f61a97cf78bfff8f66a8/packages/%40ember/-internals/glimmer/lib/utils/bindings.ts#L70
      let isPath = context.indexOf('.') > -1;

例:renderTopicListItem は最終的に _getPath の多くの呼び出しをトリガーします(さらに 50〜100 ms 節約可能):
Firefox ProfilerrenderTopicListItem 内の _getPath にフィルタリングされたコールスタック)

高コストな _getPath の呼び出しは、Discourse ではなく Ember.js で最適化されるべきことかもしれません。


また、Firefox Profiler をチェックして、JavaScript の実行に関する洞察を得てください。

「いいね!」 4

パッチありがとうございます。2番目のものは少し壊れやすいようです。

ベンチマークは開発モードで実行されていますか、それとも本番モードで実行されていますか?Emberはどちらでもかなり異なるプロファイルを持っています。

「いいね!」 2

@david がこの問題を解決する優れた方法を見つけました。彼の GitHub のコメント を参照してください。

Web ページの「latest」で renderTopicListItem を呼び出す時間が、Ember の「production」ビルドで 348 ms から 201 ms に減少します。

以前のベンチマークはまだ開発モードで実行されていました。


Ember.js の本番モードでベンチマークを実行するにはどうすればよいですか?

# Ember を本番モードで起動する
d/ember-cli server --environment="production"
「いいね!」 2

残念ながら、この大幅な速度向上を再現できませんでした。FirefoxとChrome(macOS)では、測定可能な改善は見られません。ChromeではrenderTopicListItemに約23ミリ秒かかります。Firefoxでは30ミリ秒です。古いAndroidデバイス(Pixel 3)では、約108ミリ秒かかります。変更前と変更後で数値に変化は見られません。

ちなみに、これらの数値はperformance APIを使用して測定しました。renderTopicListItemの開始時にperformance.mark("rtli-start")を追加し、終了時にperformance.measure("rtli", "rtli-start")を追加しました。

その後、ブラウザを再読み込みします(開発者ツールを閉じ、ブラウザプラグインを無効にした状態で。開発者ツールやブラウザプラグインはレンダリングパフォーマンスに大きく影響する可能性があります)。読み込みが完了したら、開発者ツールを開き、次のコードを実行して測定値を合計します。

performance.getEntriesByName("rtli").reduce((v, m) => v + m.duration, 0);

この変更は明らかに優れた実装なので、必ずマージします。しかし、レンダリングパフォーマンスで目に見える違いが出るかどうかはわかりません :thinking:

「いいね!」 7

Firefox のプライベートブラウジングモード (Linux) で、Performance API を使用してパフォーマンスの利点を再現できます。

http://localhost:4200/latest をテスト中
renderTopicListItem に費やされた時間は、約 290 ms から約 190 ms に減少しました。

私の Discourse テストインスタンスには、多くのトピック、多くの回答、多くの異なる作成者がいます。これは、本番インスタンスから取得されたデータです。これにより、レンダリングされる要素が多くなります。
これが、私たちのベンチマークの違いでしょうか?


折りたたみ部分以下のコンテンツの事前レンダリング

Discourse は、「latest」ページで 30 のトピックを事前レンダリングします。その後、コンテンツが初めて表示されます (FCP)。折りたたみ部分の上には、約 12 のトピックしか表示されません。

トピックページでも同様です。20 の投稿が事前レンダリングされますが、折りたたみ部分の上には最大 6 つの 1 行の投稿しか表示されません。

これは、FCP の最適化のもう 1 つのポイントになる可能性があります。

「いいね!」 1

FirefoxとOSのバージョンを教えていただけますか? 290msという数字は、2018年のAndroidデバイスの3倍近く遅いので、少し驚いています。

確かに、それが差の一部を説明しているかもしれません。私の場合は、Metaからのライブデータを使用して実行しました。

bin/ember-cli --environment production --proxy https://meta.discourse.org

はい、これは可能な改善策です。ただし、レイアウトやスクロールがジャンプしないように(たとえば、ユーザーがページを半分スクロールした状態でページを更新した場合など)、細心の注意を払う必要があります。「画面外」の定義も、デバイス/ブラウザ/テーマによって異なります。

「いいね!」 3

meta.discourse.orgへのプロキシ

残念ながら、プロキシを使用してEmberを実行するとエラーが発生します。

d/ember-cli --environment production --proxy https://meta.discourse.org

http://localhost:4200/

Discourse Build Error

Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames:
Host: localhost. is not in the cert's altnames: DNS:*.cdck-prod-meta.discourse.cloud

http://127.0.0.1:4200/

Discourse Build Error

Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames:
Host: meta.discourse.org. is not in the cert's altnames: DNS:*.cdck-prod-meta.discourse.cloud

ベンチマークに使用したシステム

Firefoxのabout:supportから抽出

名前 Firefox
バージョン 95.0.2
ビルドID 20211219102529
ディストリビューションID canonical-002
ユーザーエージェント Mozilla/5.0 (X11; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0
オペレーティングシステム Linux 5.10.0-0.bpo.9-amd64 #1 SMP Debian 5.10.70-1~bpo10+1 (2021-10-10)
オペレーティングシステムテーマ Adwaita-dark / Adwaita
アプリケーションプログラムファイル /snap/firefox/777/usr/lib/firefox/firefox
名前 Firefox Developer Edition
バージョン 96.0b10
ビルドID 20211228195952
アップデートディレクトリ /opt/firefox-dev-autoinstall
アップデートチャンネル aurora
ユーザーエージェント Mozilla/5.0 (X11; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
オペレーティングシステム Linux 5.10.0-0.bpo.9-amd64 #1 SMP Debian 5.10.70-1~bpo10+1 (2021-10-10)
オペレーティングシステムテーマ Adwaita-dark / Adwaita
アプリケーションプログラムファイル /opt/firefox-dev-autoinstall/firefox-bin

Chromiumのchrome://system/から抽出

CHROME VERSION 90.0.4430.212 built on Debian 10.9, running on Debian 10.11
OS VERSION Linux: 5.10.0-0.bpo.9-amd64

OSバージョン:

# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
「いいね!」 2

リファクタリングのプルリクエストがマージされました。

@rrit さん、この件を提起してくれてありがとう。素晴らしい改善です!

「いいね!」 5

このトピックは9時間後に自動的に閉じられました。返信はもう許可されていません。