168iroha / example-component-oriented

コンポーネント指向の実装例
MIT License
0 stars 0 forks source link

SSRで非同期データを扱う仕組みの実装について #16

Closed 168iroha closed 8 months ago

168iroha commented 9 months ago

まずはやりたいことだけ整理しておく

背景

要件の整理

※その他、非同期処理の結果のキャッシュの有効期限等の議論も必要だが、本件は非同期処理を行うことが本題であり、いつサーバで非同期処理を行うかは本題ではないため、明示的に取り扱いはしない。ただし、それを可能とするインターフェースの整理は必要

168iroha commented 9 months ago

現状のハイドレーションの仕組みの整理

ハイドレーションの改修案

168iroha commented 9 months ago

重要な変更点は以下の通り

コンポーネントを示す関数の実行中にハイドレーション対象のDOMノードを参照できるようにした

ライフサイクルフックで明示的にラベルを指定可能にした

ノードツリー構築中にPromiseを評価できるようにした

[!NOTE] GenStateNode.#mountImplを非同期関数ではなく、GenStateNode.buildCurrentの評価に関するジェネレータ関数として実装することにより、マイクロタスクによる評価の遅延を最小限にしつつ、GenStateNode.mountなどを同期的に評価することを可能としている(ジェネレータはasync/awaitでの実装で内部的に使われているためこのような実装でも問題ない)

168iroha commented 8 months ago

useSSRDataを実装するとしたとき、サーバではデータのフェッチ&書き出し、クライアントではデータのデータのフェッチorフェッチされたデータの読み込みのように行う処理が全く異なるため、サーバとクライアントとで処理を切り替える仕組み(エイリアスの作成)が必要 →前提として、webpackなどのモジュールバンドラを用いてバンドルすることになる →基本方針であるVanilla JSで動作することと乖離が生じてしまうが、AltJSを利用するわけではないためセーフとする

168iroha commented 8 months ago

useSSRDataの概要

サンプルの使い方

168iroha commented 8 months ago

一先ず、今回の修正により以下の要件はすべて満たすような実装となっている そのため、適当にリファクタリングをして、結果をdevelopブランチにマージしたらissueはクローズする。 ※テストについては実施は未定(そのうちやりたいけど、JavaScriptのテスト方法があまり知らないため保留)

  • 必ずサーバが非同期処理の結果をクライアントへ与える
  • クライアント側では初回の非同期処理の結果はサーバが行った内容を用いる
  • 必要なタイミングでクライアント側でも非同期処理を行うことができるようにする
  • ハイドレーションが可能であることを保証する
  • コンポーネント単位で非同期処理が行われる

15

168iroha commented 8 months ago

今まで副作用では状態の伝播のみを許容していたが、利便性が著しく悪くなるためDOMツリーの属性ノードを除く構造が不変であれば伝播を許容するように変更した