要約
インライン PDF プレビューは、長いトピックをスクロールすると、一貫してスクロール位置がリセットされます(1 ページ目に戻る)。これは、Discourse の投稿ストリームのリサイクル/仮想化により、PDF 埋め込みがビューポートからスクロールアウトしたときに破棄され、再挿入されるために発生しているようです。
これはすべてのブラウザ、すべての PDF に影響し、すべてのプラグインとテーマを無効にした場合でも発生します。
再現手順
- PDF 添付ファイルを含むトピックを作成します。
- インライン PDF プレビューコンポーネントがアクティブであることを確認します。
- トピックを下にスクロールし、PDF を含む投稿がビューポートから外れるまで移動します。
- 同じ PDF プレビューにスクロールして戻ります。
- 結果:
- PDF が最初から再読み込みされます。
- プレビューのスクロール位置が失われます。
- PDF は新しく読み込まれたかのように再レンダリングされます。
PDF のネットワークリクエストが発生しないことから、DOM ノードがローカルで削除され、再作成されたことを示しています。
期待される動作
- PDF プレビューはスクロール位置を維持し、トピックをスクロールしただけで再読み込みされるべきではありません。
- 他の埋め込みコンテンツ(画像、動画、Onebox)はスクロール時に状態がリセットされないため、PDF プレビューも一貫して動作するはずです。
実際の動作
- 投稿が可視範囲外になるとすぐに、Discourse は DOM ノードをアンロードします。
- 投稿がビューポートに戻ってくると、埋め込みが再構築されます。
- これにより、ブラウザのネイティブ PDF レンダラーが 1 ページ目から再開されます。
- これは、投稿がビューポートを離れるたびに(上方向または下方向)発生します。
環境
- テストされたすべてのブラウザで発生:Chrome、Firefox、Safari、Edge
- すべてのプラグインを無効にした場合(セーフモード)に発生
- すべてのテーマコンポーネントを無効にした場合に発生
- サイズと形式の異なる複数の PDF ファイルで発生
- 投稿日時点の Discourse (tests-passed) 最新ブランチで発生
技術的な注意点
Discourse は、ストリーム仮想化の一部として、画面外の投稿コンポーネントをアンマウントしているようです。
PDF プレビューは単純な <iframe> / <embed> を使用しているため、永続化のメカニズムがなく、次のような場合に完全にリセットされます。
willDestroyElement()がトリガーされたとき- 投稿のコンテナが再レンダリングされたとき
- ビューポートへの再エントリー時に DOM ノードが再作成されたとき
これは、ブラウザネイティブの PDF ビューアが DOM の再構築をまたいでスクロール状態を保持しないため、PDF に特有の現象です。
これにより、特に複数ページの添付ファイルがある場合、PDF を含む長いトピックを読むのが困難になります。
求められる解決策
- 投稿のリサイクル中にインライン PDF プレビューコンポーネントが破棄されないようにする、または
- プラグイン/テーマコンポーネントが「永続的な状態」を宣言し、Discourse がそれらをアンマウントしないようにする方法を提供する
- または、インライン PDF ビューアを含む投稿に対して投稿ストリームのリサイクルを無効にするサイト設定を公開する
部分的な修正、例えば PDF 埋め込みを含む投稿のリサイクルをスキップするだけでも、問題を解決できます。
追加のコンテキスト
これは、クリーンなテストビルド、複数のブラウザ、および複数の PDF で確実に再現されているため、単なる環境の問題ではありません。
この動作について説明している Meta トピックはないため、これは未報告の回帰、またはストリーム仮想化の改善によって意図せず発生した結果である可能性があります。