rrit
(Ayke)
2022 年 1 月 30 日午前 2:02
1
JavaScript の遅延読み込みについて
可能な限り、すべての JavaScript に defer 属性を追加します。JavaScript の読み込みと実行を遅延させることで、ブラウザは HTML の解析、レンダリング、ペイントを開始できます。
これにより、Discourse の起動プロセス中またはその前に、静的な一時コンテンツが表示される可能性があります。これは、初回読み込み時のユーザー体感速度を向上させるはずです。
静的な一時コンテンツのアイデア:
ロゴとローディングスピナー付きのスプラッシュスクリーン
バックエンドからの投稿を含むトピックビュー
POC と PR
最新の概念実証と PR については、こちらの投稿を参照してください 。
現在、ベンダー JavaScript およびそれ以前のすべての JavaScript は遅延読み込みされていません。
@参照 : https://github.com/rr-it/discourse/commit/328efd5c055f5f2a4d93b5e52268cfe92913faf7
この問題の解決策に関するアイデアを歓迎します。
JavaScript の async、defer、none
defer を含む JavaScript の読み込みオプションの詳細については、Efficiently load JavaScript with defer and async を参照してください。
(これは、実際の Discourse ブートの高速化に関するものではありません。)
Fastboot/再水和
Background Google have recently announced it will be rolling out an update to search ranking based on “Core Web Vitals” starting May 2021. It will use 3 signals for this new ranking bump: LCP: Largest Contentful Paint This metric is used to...
Reading time: 5 mins 🕑
Likes: 25 ❤
この記事を読みました:
結論として、Fastboot/再水和の実装のようです。
これにはいつ頃の予定がありますか?
「いいね!」 4
Falco
(Falco)
2022 年 1 月 30 日午前 2:13
2
それはEmberJSが起動して再レンダリングされた後もLCPを引き起こすことになり、Googleの新しいランキングに関する主な問題に対処することにはなりません。
それがDiscourseにおけるLCPに対処するための現在の中期計画です。
「いいね!」 2
rrit
(Ayke)
2022 年 2 月 3 日午後 11:06
3
Chrome 88以降では、幸いなことにこれはもはや真実ではありません!
私もついさっきまで知りませんでした。:))
「この変更の前は、要素が削除されると、LCPの候補として考慮されなくなっていました。[…] この変更の後、削除された要素はLCPの候補として引き続き考慮されます。」
「後でDOMから削除されるコンテンツを最大のコンテンツ描画要素として含めるように変更することで、同じサイズの画像([*Discourseの場合:テキスト要素 ])が複数回挿入されるサイトで、最大のコンテンツ描画要素の時間が改善されます。これは、カルーセルでよく見られるパターンですが、サーバーサイドレンダリングを行う一部のJavaScriptフレームワークでも同様です。」
LCP変更履歴
将来的にはさらに良い変更があるかもしれません:
「いいね!」 1
rrit
(Ayke)
2022 年 2 月 4 日午前 12:37
4
POCが実装されたトピックページのシミュレーション 統計を以下に示します。
Lighthouse: 「値は推定値であり、変動する可能性があります。」
WebPageTest
webpagetest.org
Moto4Gシミュレーション
注:私たちは一番上の黒い矢印です。
注:
0秒~2秒 - 白画面:
WebPageTestはJavaScriptのdeferを無視し、最初のペイントを行う前にすべてのJavaScriptをダウンロードします。これは実際のデバイスでは正しく機能します。
2.5秒 - LCP:サーバーレンダリングからの静的コンテンツ
3.5秒 - ビジュアル変更:ロゴが読み込まれました
6.5秒 - ビジュアル変更:EmberJsレンダリングからのコンテンツ
7秒 - ビジュアル完了
PageSpeed Insights
Largest Contentful Paint要素
PageSpeedは、サーバーレンダリングからの静的テキストノードをFCP LCP要素として正しく識別します:
div.row > div.topic-body > div.post > p
EmberJsによってレンダリングされたテキストノード:
div.row > div.topic-body > div.regular.contents > div.cooked > p
しかし、PageSpeedはシミュレーション 結果に正しく識別された静的テキストノードを使用していないようです。シミュレーション されたFCPとLCPが大きすぎます。
実世界のユーザーデータ
POCが実装された「実際の」データを取得するために、さらに14~28日間待ちましょう。Chrome UX Report からのデータです。
テストされたトピックページでPOCが実装されていない場合の統計:
(データは単一のトピックURLのものであり、オリジン全体のものではありません。)
「いいね!」 4
Falco
(Falco)
2022 年 2 月 4 日午前 1:49
5
「いいね!」 3
rrit
(Ayke)
2022 年 2 月 4 日午前 10:40
6
Web Vitals Chrome 拡張機能経由
デスクトップで
Chromium バージョン 90.0.4430.212
新しいシークレットウィンドウでの初回読み込み
初回入力遅延に関する注記: ページが完全に読み込まれるまで待ってから、背景をクリックしました。EmberJs のレンダリングが完了した後です。
初回入力遅延に関する注記: ここでは、静的コンテンツが最初に表示されたときにすぐに背景をクリックしました。この FID に私の反応時間を追加してください
。
これらのグラフのバーの下にある パーセンタイル に関する追加注記:
パーセンタイルは、測定された値と元の値を比較するだけなので、それほど重要ではありません。元は、サブフォルダに Discourse がインストールされている TYPO3 のウェブページです。
「いいね!」 2
素晴らしいアイデアです!@rrit
Discourseが非常に遅く、JavaScriptが多いWebアプリケーションであることに完全に同意します。CSS/JSファイルを遅延させることができれば、LCP、FCP、FID、CLSの速度が大幅に向上します。
これが実現するのを見るのは本当に助かります。私たちや他の多くの人々がこの問題に直面しています。すべてのDiscourseサイトがCore Web Vitalsで失敗しています。最初にユーザーに高速な静的HTMLページを提供したり、最初の初期ロードでJS/CSSロジックをすべて遅延させたりすれば、すべてのページの速度が上がり、CWVスコアを通過できます!コアDiscourseアップデートでこれがライブになるのを見るのが楽しみです。
すべてのDiscourseサイトは、サイトがCore Web Vitalsを通過しないためにGoogleのランキングが低下しています。
「いいね!」 2
david
(David Taylor)
2022 年 2 月 7 日午後 7:37
11
コアでの実験も検討しています。「フラッシュ」で異なるスタイルのコンテンツが表示されるのは少し落ち着かないので、まずはデフォルトで無効になっている「実験的」サイト設定の背後に配置したいと思います。そうすれば、サイト管理者が希望する場合に有効にすることができます。
rritさん、PRにサイト設定を追加していただけますか?設定が有効/無効の場合の動作を確認するために、RSpecテストを追加することも良いでしょう。
「いいね!」 5
Falco
(Falco)
2022 年 2 月 7 日午後 8:03
12
これは、サーバーによってレンダリングされたページにフルスクリーンスピナー(幅100%、高さ100%)を配置し、Emberアプリが最終的に起動したときにそれを置き換えることで、非常に低いLCPを取得できることを意味しませんか?
このスピナーをDiscourse UIを模倣したSVGにすることで、トランジションをよりスムーズにし、FOUC(Flash of Unstyled Content)のような現象を軽減できる可能性があります。
「いいね!」 2
david
(David Taylor)
2022 年 2 月 7 日午後 8:04
13
LCPの「候補 」という部分が重要だと思います。
実際にレンダリングされるものと同じくらい大きい(少なくとも同じサイズ)場合にのみ、最大のコンテンツペイントと見なされるのでしょうか?
したがって、クローラービューを使用すると、コンテンツ(つまりテキスト)がほぼ同じであるため、うまく機能するということでしょうか?
(上記のスクリーンショットに基づいた推測がほとんどです。フルスクリーンスピナーは試していません)
「いいね!」 1
rrit
(Ayke)
2022 年 2 月 7 日午後 8:33
14
フィーチャーフラグは実装されました。
私はまったくRuby開発者ではありません。この件については、間違いなく助けが必要です。
POCをmainのPRの前に、discourse/discourseリポジトリの新しいブランチにプッシュしますか?
このフィーチャーに関する私のPRはこちらです:
main ← rr-it:dev/javascript-defer
opened 03:49AM - 08 Feb 22 UTC
Implement experimental feature flags for "static topic content" and " javascript… defer"
### static topic content
`SiteSetting.enable_experimental_static_topic_content`
Can be set via settings dashboard.
Show static content in topic view for a faster Largest Contentful Paint (LCP).
Warning: visitors might see disconcerting jumping of content!"
### javascript defer
`SiteSetting.enable_experimental_javascript_defer`
Can be set via settings dashboard.
Defer loading of JavaScripts to show static content even faster in combination with 'enable_experimental_javascript_defer'. Warning: the discourse frontend, themes, components and/or plugins might fail!
---
The vendor-javascript and all preceding javascripts are not deferred right now.
@see: https://github.com/rr-it/discourse/commit/49405c353a31180933aed9dca7697dce05227707
Ideas on how to solve this are very welcome.
---
For more information see also:
https://meta.discourse.org/t/defer-javascript-and-show-interim-content-on-initial-page-load/216458
@david これらの変更に対するRspecテストの開発について、少し頭を貸していただけますか?
app/helpers/application_helper.rb : spec/helpers/application_helper_spec.rb
ここでは実現可能な単体テストが見当たりません。統合テストでのみテスト可能と思われます。
app/models/theme.rb
app/models/theme_field.rb
QUnitテストランナーのためにdeferタグを無効にする必要がありました:app/views/qunit/index.html.erb
以前はフィーチャーフラグ "javascript defer" = false でもQUnitテストは実行されていました。そして今、テストは "javascript defer" = true でも実行されます。
「いいね!」 2
rrit
(Ayke)
2022 年 2 月 7 日午後 8:54
15
これはおそらく、Chrome Speed - Largest Contentful Paint Bug Fixes in M88 で既にブロックされているでしょう。
ビューポート全体を占める画像は、背景画像と視覚的に同等ですが、最大のコンテンツ描画(LCP)とはみなされなくなりました。
良い点です。Largest Contentful Paint (LCP) | Articles | web.dev を参照してください。
テキスト要素の場合、テキストノードのサイズのみが考慮されます(すべてのテキストノードを囲む最小の長方形)。
すべての要素について、CSSで適用されたマージン、パディング、またはボーダーは考慮されません。
そのため、静的なテキストノードはEmberJsのテキストノードとまったく同じサイズでレンダリングされる必要があります。
line-height を増やすことで、さらにわずかに大きくすることもできます。
たとえば、テキストノードの幅が一致しない場合、さまざまな改行によって導入される多くの幾何学的なケースがあり、静的なテキストノードがEmberJsのものより小さくなる可能性があります。
参照:LCPの例
実際には、トピックページの投稿を noscript でレンダリングしました。CSSクラスは実際のクラスとわずかに一致しているため、見た目は同じです。
参照:app/views/layouts/application.html.erb の変更点
編集:私の間違いです。これは実際にはクローラービューです:app/views/topics/show.html.erb
「いいね!」 2
rrit
(Ayke)
2022 年 2 月 7 日午後 9:08
16
POCでは2つの機能が組み合わされていますが、これらを2つの実験的フィーチャーフラグに分割しますか?
deferタグ付きJavaScript(設定ダッシュボードのフィーチャーフラグ)
(コンテナの再構築またはテーマキャッシュのフラッシュが必要なため、非表示のフィーチャーフラグ) ← 修正:キャッシュによるホットスイッチ
トピックビューでの静的コンテンツの表示(設定ダッシュボードのフィーチャーフラグ)
こちらです:フィーチャーフラグ
もちろん、LCPへの完全な影響は両方を使用することで達成されます:「FCP:静的コンテンツ」
プラグインまたはテーマコンポーネントがJavaScriptの遅延で失敗するDiscourseインスタンスがあるかもしれません。これらの機能を分割することで、JavaScriptを遅延させることなく静的コンテンツでわずかな改善を得ることができます:「FCP:JS遅延なしの静的コンテンツ」
「いいね!」 2
rrit
(Ayke)
2022 年 2 月 11 日午後 6:32
17
Google Search Console からの最初の印象(2022-01-30 より POC を適用後):
デスクトップ
デスクトップでは、結果が表示されるまでに時間がかかりました。
注:古い緑色のベースラインは、同じドメイン上の Discourse 以外のウェブページを表します。
モバイル
注:古い緑色のベースラインは、同じドメイン上の Discourse 以外のウェブページを表します。
モバイルページでさらなる改善が見られることを期待して、さらに 7 ~ 14 日間待ちましょう。値は過去 28 日間の平均であるため、現在 POC が適用されているのは 12 日間のみです。
「いいね!」 5
rrit
(Ayke)
2022 年 3 月 3 日午後 3:22
18
PoC に関する LCP の概要
POC は 2022 年 1 月 30 日から適用されており、Google Search Console の「Core Web Vitals」レポート(CrUX データに基づく)の全ページに影響を与えるまでに 4 週間以上かかりました。
すべてのトピック ページは LCP のグリーン ゾーン(CrUX による測定)にあります。
デスクトップ: LCP 1.7 秒
モバイル: LCP 2.0 秒
LCP データ: Google Search Console/CrUX
2022 年 1 月 30 日から POC を適用した Google Search Console からのインプレッション:
デスクトップ
注: 古い緑のベースラインは、同じドメイン上の Discourse 以外のウェブページを表します。
良好な URL
モバイル
注: 古い緑のベースラインは、同じドメイン上の Discourse 以外のウェブページを表します。
良好な URL
LCP 問題: 2.5 秒以上(モバイル)
注: トピック ページのみが EmberJS コンテンツの前に静的コンテンツを表示します。
機能フラグ付き PR の承認が必要
main ← rr-it:dev/javascript-defer
opened 03:49AM - 08 Feb 22 UTC
Implement experimental feature flags for "static topic content" and " javascript… defer"
### static topic content
`SiteSetting.enable_experimental_static_topic_content`
Can be set via settings dashboard.
Show static content in topic view for a faster Largest Contentful Paint (LCP).
Warning: visitors might see disconcerting jumping of content!"
### javascript defer
`SiteSetting.enable_experimental_javascript_defer`
Can be set via settings dashboard.
Defer loading of JavaScripts to show static content even faster in combination with 'enable_experimental_javascript_defer'. Warning: the discourse frontend, themes, components and/or plugins might fail!
---
The vendor-javascript and all preceding javascripts are not deferred right now.
@see: https://github.com/rr-it/discourse/commit/49405c353a31180933aed9dca7697dce05227707
Ideas on how to solve this are very welcome.
---
For more information see also:
https://meta.discourse.org/t/defer-javascript-and-show-interim-content-on-initial-page-load/216458
@sam 承認のために、この PR を誰かに委任していただけますでしょうか。
「いいね!」 3
sam
(Sam Saffron)
2022 年 3 月 8 日午前 3:09
19
確かに慎重にレビューいたします。非常に大きな変更ですので、対応に少々お時間をいただく場合がございます。
「いいね!」 5
david
(David Taylor)
2022 年 3 月 9 日午後 12:48
29
@rrit サイトのデータ共有ありがとうございます!社内で検討した結果、現時点ではこの機能性をDiscourseコアに追加しないことになりました。
共有いただいたWeb Vitalメトリクスは非常に印象的ですが、「クローラービュー」コンテンツのフラッシュは、ユーザーエクスペリエンスとしてあまり良くありません。行ったスタイリングの変更は確かに役立ちますが、カスタムスタイリングを持つすべてのDiscourseサイトで微調整が必要になります。
長期的な目標は、Ember FastBoot のようなものを使用した真のサーバーサイドレンダリングを実装することです。理論的には、測定された統計的改善と同じものを提供し、シームレスなユーザーエクスペリエンスも提供します。私たちはその目標に努力を集中させたいと考えています。
とはいえ、Discourseは非常に拡張性が高いため、Discourseプラグインでアイデアを実装し、ここで#pluginで共有することは完全に可能だと思います。
コアPRで最も大きな変更は、スクリプトタグにdefer属性を追加したことです。プラグインからそれらのすべての場所をオーバーライドするのは非常に困難です。しかし、ミドルウェアベースのアプローチで同じ結果が得られると思います。このブログ記事は同様の問題を説明しています。
Table of Contents1 Nokogiri is the answer2 Small corner cases that we need to cover3 Hooking it up to Rack middleware4 Usage example5 Performance6 TL;DR - Whole middleware Few years ago I wrote a post about adding rel=”nofollow” to all the links in...
Est. reading time: 5 minutes
このテクニックを使用して、text/htmlレスポンスをチェックし、それらを解析して、必要に応じてdefer属性を追加するミドルウェアを作成できます。
プラグインからミドルウェアを追加するには、次のようなことができます。
# name: my-plugin
# about: My plugin description
# version: 1.0
# url: https://example.org
require_relative "lib/script_defer_middleware"
on(:after_initializers) do
Rails.configuration.middleware.use(ScriptDeferMiddleware)
end
プラグインベースのアプローチで問題が発生した場合は、ここに投稿してください。喜んで方向性を示します。
「いいね!」 10
rrit
(Ayke)
2022 年 3 月 9 日午後 3:58
30
もしこれに時間を割くことができれば、おそらくプラグインを実装するでしょう。
しかし、今のところ web_only.yml でパッチアプローチで対応しようとしています。
# テストされていない擬似コードです!
hooks:
after_code:
- exec:
cd: $home
cmd:
- curl https://patch-diff.githubusercontent.com/raw/discourse/discourse/pull/15858.diff | git apply
「いいね!」 4
rrit
(Ayke)
2022 年 3 月 9 日午後 4:09
31
Ember FastBootは長期的なアプローチとして完璧に見えます。一方、LCPのトピックは引き続き注目されています。
「いいね!」 2
Johani
(Joe)
2022 年 7 月 5 日午後 5:45
38
@rrit さん、ありがとうございます
良いニュースがあります。Discourse に新しい機能が実装され、この問題がかなり改善されるはずです。
Discourse is a single-page Javascript application.
This means that navigation within the app is blazingly fast. The compromise with modern web applications is that they must be loaded and parsed on the initial page view. While we’ve been doing a lot of work over the years to optimize how we serve site assets, this can sometimes be a little bit slow based on device/network conditions.
Over the last few weeks, we’ve been actively working and testing potential improvements for the initial wait th…
「いいね!」 5