00:06
6月1日、水曜日ですね。遅刻10時を回りました。
今日はですね、めでたく、実は私の誕生日なんですね。
今日で35歳になります。後ほどTwitterでも欲しいものあげようと思います。
はい、おはようございます。
では本日は朝活を始めていきたいと思います。
本日もタイトルにある通りですけども、
昨日に引き続き、RFCですね、ReactのサーバーコンポーネンツのRFCの続きを読んでいこうと思います。
昨日はひたすらFAQに入ったところだと思います。
FAQに入って、ずっと読んでいっていきます。
今日で多分終わると思うので、今日はそのまま時間が早く終わったら、
もともと読んでいたNext.jsのLayoutRFCのブログがあるんですけど、
そこのサーバーコンポーネンツのところだけ割愛してしまったので、
そこに改めて戻って読んでいこうかなと思っております。
という感じですね。
昨日どこまで読んだのか、僕が実は全然覚えていないので、
多分これだろうみたいなところからざっくり読んでいこうかなと思います。
なので今日のところは、What is the Response Format?
というところから読んでいこうかなと思いますね。
オート形式はどのようなものですか?というところですけど、
主にはJSONのようなものになりますけど、
後ほど記入できるスロットを持っていますよと。
これによってコンテンツを段階的に幅を持たせて流すことができますよと。
サスペンス的な境界というのは、
意図的にデザインされた視覚的な状態を示すもので、
全てのコンテンツが完全に流れ込む前に結果を表示し始めることができますと。
このプロトコルというのは、最初の非インタラクティブなレンダリングを高速化するために、
HTMLストリームに変換することができる、よりリッチな形式になっていますよという感じでした。
ちょっと具体的なものが出てきていないので、
それを後ほど見てからって感じになると思いますけど、
方針としてはこんな感じらしいですね。
エバダさんですね。
ご参加いただきありがとうございます。
ダラダラダラと読んでます。
主中優先さんですね。大阪です。
今日もタイトルにある通り、リアクトのサーバーコンポーネントのRFOをダラダラと読んでます。
続いての質問ですね。
タイプスクリプトって動作しますか?というところですね。
これの答えとしては、はい、動作します。
制限としては、サーバーとクライアントの境界がシリアライズ可能であること、
つまりクライアントに渡されるすべてのプロプスがシリアライズ可能であることということを、
現在は強制できないというのがありますよと言ってますね。
それが今の制限らしいです。
では、続いての質問ですね。
続いての質問は、サスペンスとの関連は何ですか?という話をしてました。
03:02
サーバーコンポーネントのデータ取得APIというのは、サスペンスと統合されていますと。
サスペンスを利用して、ロードの状態を提供して、
ストリームの一部をアンブロックすることで、
レスポンス全体が終了する前に、
クライアントが何かを表示できるようにしていますということでした。
なるほどですね。
統合されているんですね。
続いて、コンカレントモードとの関連は?という質問ですね。
コンカレントモードは、リアクト全体の最適化をセットで、
サーバーコンポーネントとも統合されています。
そうなんや。
例えば、コンカレントモードでは、
レスポンス全体の終了を待たずに、
データストリームが入力されると、
クライアントコンポーネントのレンダリングを開始することができますと言ってます。
いいですね。
ちゃんと統合されているんですね。
続いて、ルーティングはどのように行うのですか?という質問ですね。
こちらの回答ですけど、まだわかってないんですと。
活発、今現在研究している途中ではありますと言ってますね。
サーバーのコンテキストと同じような機能が不足しているので、
とりあえずまだリアクトに組み込む必要があるんじゃないかなという話をしていました。
ここはまだまだ更新を待つしかないという感じですね。
続いての質問ですけども、
なぜSync Awaitを使わないんですか?というような質問でしたね。
これの回答はちょっと長いんですけども。
デモとかRCで使用しているリアクトIoLibraryというのは、
以前説明したサスペンス互換のデータ取得APIの書き方の監修に則っています。
サスペンス対応のAPIというのは、
既にデータがある場合は同期的に返し、
エラーがある場合はスローし、
リアクトに値を返さないことを示すためにサスペンドします。
サスペンドする仕組みというのはプロミスの値を投げることです。
リアクトはAPIが値を提供する準備ができたとき、
または失敗したときを検知するために
プロミスのResolveを使用してコンポーネントを再びレンダリングする
という試みをスケジューリングしています。
この提案からサスペンションの設計で新たに考慮したことというのは、
サーバーコンポーネンツ、クライアントコンポーネンツ、
シェアドコンポーネンツの間でデータにアクセスするために
一貫したAPIを使用したいということです。
しかし全体としてサスペンションの設計はこのRFCの範囲外ではあります。
私たちはこの設計を明確に文書化することに同意し、
新年にはその優先順位を上げる予定です。
なるほどね。
この辺まだまだ難しそうですね。
では続いての質問ですね。
続いてはサーバーコンポーネンツというのは
プロプスが変更されるためにリフェッチされるのでしょうか?
という質問でした。
これの答えはノーですね。
ツリーの中間にあるサーバーコンポーネントというのは
親クライアントコンポーネントが再レンダリングしても再取得されません。
06:00
クライアントの視点からはサーバーコンポーネントは全く存在せず、
Libやその他のクライアントコンポーネントを含む
すでに解決されたツリーのみが表示されます。
サーバーコンポーネントの更新が必要な場合は
リアクトは上から下へレンダリングする
サーバーコンポーネントツリー出力全体を再取得します。
ただしより細かい無効化の研究も今進行中ではあります。
まるっとやる感じですね。
現在サーバーコンポーネントツリーというのは
アプリのルートから始まりますけども
明示的に選択されたエントリーポイントから
よりきめ細かいリフェッチができるようにする予定です。
それはでもできてほしいですね。
今のところは全部上から下まで持ってきちゃうのであれば
細かいリフェッチできたほうがいいですからね。
続いての質問が
常にアプリ全体をリフェッチしてるんですか
それは遅くないんですかっていう質問を受けてます。
これに対する回答としては
デモではアプリ全体をリフェッチしています。
これは非常に多いように聞こえますけども
昔ながらのHTMLページをフェッチするのと同じだと考えてください。
もっと細かいリフェッチの仕組みを導入して
画面の一部だけをリフェッチするオプションも
用意する予定ですがまだ利用可能ではありません。
それはその通りだと思いますね。
全部持ってくるのはさすがに確かに重いと思いますけどもね。
続いての質問ですけども
サーバーコンポーネントとパフォーマンスの利点は何ですか
サーバーコンポーネントを使用すると
データ取得の大部分をサーバーにおいて
クライアントが多くの要求をする必要がなくなりますよと
またユーズエフェクトでのフェッチにありがちな
クライアントネットワークのウォーターホールを回避することができます。
もちろんサーバーコンポーネントとグラフQLを組み合わせて
使用することも可能ですよと言ってますね。
続いて
コメントが続いてましたね。
サーバーコンポーネントを使用すると
バンドルサイズを大きくすることなく
アプリにインタラクティブな機能を追加することもできます。
機能をクライアントからサーバーに移すことで
初期コードサイズとクライアント.jsのパース時間が減少します。
クライアントコンポーネントのレイヤーを少なくすることで
クライアントのCPU時間も改善されます。
クライアントはサーバーが生成したツリーの一部を
最初の更新で影響を受けていないことが分かっているので
リコンサイル時にスキップすることができるようになります。
続いての質問が
UIを常に再取得するとインタラクションが遅くなるんじゃないの?
という質問ですけども
これの回答としては
高速なインタラクションのために
ツリーのどのレベルでもクライアントコンポーネントを
使用することができます。
そしてそうすべきだよというふうに我々は考えています。
常に再取得する必要はもちろんなくて
取得したツリーはクライアントキャッシュに残って
09:02
バックボタンのようなナビゲーションに再利用することができます。
なるほど。キャッシュもないことで使えるんですね。
続いて
PHPとかRailsなどのモノリティックなフレームワークと何が違うの?
クライアントとサーバーの間で
いくつかのコンポーネントを再利用して
異なるトレードオフのユースケースを実現することができるようになります。
例えばクライアントでライブプレビューを提供して
サーバーで消費するために
レンダリングされるマークダウンレンダラーなどというのがあります。
これは同じパラダイムと同じ言語で書かれているため
可能になりますよというふうに言ってますね。
確かにPHPとRailsとかだと
クライアント側との言語も違うので
同期的に書くことはできないですよね。
続いての質問が
もうぼちぼち質問終わりますね。
今日ちょっと早めに終わっちゃいますね。
続いての質問というのは
ASPとか.NET、Webフォームとどう違うんですかということですね。
こちらですけども
プログラムの全状態をサーバーに送らないというのが大きい違いだと
インタラクティブなウィットというのは
クライアントコンポーネントでなければなりませんと言ってますね。
という話でした。
続いてPhoenixライブビューとどう違うんですか。
Phoenixライブビューというのは僕はちょっとわからないんですけど
別の言語かな。
ここはちょっと僕が不勉強で申し訳ないですけど。
私たちのサーバーはステータフルではないですよと
その代償としてより荒くリフェッチしていますと言ってますね。
あえてしてるのかな。
なるほどですね。
続いてサーバーコンポーネントの欠点は何ですかと。
それは欠点の項目なんでそこを読んでくださいということでした。
続いてなんでRxではないんですかと。
これは面白い観点ですね。
確かにRxでもいいじゃんという気はしましたね。
Rxというのはデータのストリームを管理するための優れたソリューションですと。
フレームワークの作者はリアクトがサーバー上で作成したレンダリング
UIチャンクのストリームを受信して
クライアントにストリームするトランスポートレイヤーの実装に
Rxが適していることに気づくかもしれないと予想はしています。
なるほど。ちょっと分かってないぞ。
ものによってRxが適しているというのは確かにあるかもしれないので
一概にリアクトがダメと言っているわけでもないんですね。
そもそもRxのデータストリームというのは優れたソリューションだということは認めてますからね。
リアクトチームも。なるほどですね。
そのレンダリングUIチャンクのストリームを受信して
クライアントにストリームするトランスポートレイヤーの実装に適しているということがあるということですね。
なるほど。これはちょっと書いてみないと分からないですけど概念的には確かにそうかもしれないですね。
一応トランスポートしなきゃいけないので
12:00
そこのレイヤーにRxが結構ぴったりはまるというケースはあるかもしれないということですね。
続いてクロスサイドスクリプトについてはどうですか?
ここは僕は気になってますね。
サーバーコンポーネンツの出力をエンコードするために
使用されるストリーミングプロトコルというのは
クロスサイドスクリプト攻撃を防ぐために
ユーザー提供の入力をエンコードしてますよというふうに言ってました。
という感じで質問は以上で最後にハッピーホリデーということで
質問じゃないけどハッピーホリデーっていうのがあるのでそちらもよろしくお願いしますと言ってました。
という感じでざーっと読んできましたけど
リアクトサーバーコンポーネンツのRFCでした。
結構長かったし難しかったんですけど
ただこれの実装がちゃんと実現すると
結構有名なパフォーマンス改善が行われる気が僕はしていて
割とワクワクしましたね。
なのでこれの実際のRFCに対して実装がどうなるかというのを
結構心待ちにしたいかなと思いますが
ではRFCは読んだので最後ですね。
最後というかもともと読んでたのが
Next.jsのLayoutsRFCっていうのを読んでたんですけど
そのNext.jsのLayoutsRFCを読む中で
サーバーコンポーネンツっていう章があったんですね。
そこについては先ほどの
リアクトのサーバーコンポーネンツのRFCを読んでからじゃないと
多分理解しづらいよっていう話があったので
そこをすっとばしたんですよね。
なので改めてNext.jsのLayoutsRFCっていうものの
リアクトサーバーコンポーネンツの章に戻って
そこを今から読んでいこうかなと思っております。
では最初の注意事項からあって
その注意事項が先ほど今言ったやつですね。
リアクトサーバーコンポーネンツのRFCを先に読んでから
こっちの章を見ることをお勧めします。
本題に戻りますね。
このRFCを利用することで
リアクトの機能を使い始め
Next.jsのアプリケーションにリアクトサーバーコンポーネンツを
段階的に採用することができます。
この段階的っていうのが
そのNext.jsのLayoutsRFCに関しての
結構大きなコンセプトらしいですね。
新しいルーティングシステムの内部っていうのは
ストリーミング、サスペンス、トランジッションなど
最近リリースされたリアクトの機能を活用しています。
これらはリアクトサーバーコンポーネンツの
構成要素でもあります。
サーバーコンポーネンツっていうのは
新しいデフォルトになりますよという風に言ってますね。
ページとアプリのディレクトリの
最も大きな変更点の一つっていうのは
デフォルトでアプリ内のファイルは
リアクトサーバーコンポーネンツとして
サーバー上でレンダリングされる
ということになります。
これは先ほど、前回まで読んだやつに書いてましたね。
これによってPagesか、もしくはAppに移行する
今のPagesディレクトリから
Appディレクトリって新しいレイアウト構成ですね。
に移行する際に
自動的にリアクトサーバーコンポーネンツを
採用することができるようになります。
そうなんだ、なるほどですね。
そのまま続きを読んでいきますね。
15:03
そうですね。
ネクストのレイアウトってやつが
今までのPagesからAppっていうディレクトリを
アプリ直下に置いて
そこでレイアウト構成を変えていくっていうのは
結構大きい変更になるので
ただもちろん介護官じゃないですけど
既存のPagesっていうディレクトリも
ちゃんと機能はしますよっていうのを
サポートするって書いてましたね。
では続いてレンダリング環境と
コンポーネント処理っていうところですね。
最初注意事項から入っていて
リアクトでは新しいコンポーネント
過去モジュールタイプが導入されています。
サーバーとクライアント
およびシェアコンポーネントというのは
3つに分かれています。
これらの新しいタイプの詳細については
Capabilities and Constraints of Server and Client Components
およびServer Module Convention RFCっていうのがあって
そこの項目を読んでくださいっていう風に
言ってました。
本題に入ると
新しいリアクトの規約を使用して
クライアントサイドのJavaScriptバンドルに
どのようなコンポーネントが含まれるかっていうのを
詳細に制御できるようになります。
クライアントコンポーネントとサーバーコンポーネントを
定義するための規約が
具体的にどのようなものになるのか
現在議論が行われています。
私たちはこの議論の決着を追っています
って言ってました。
ここはリアクトのチームの更新を
ずっとNexusJSは待っていると。
今のところApp Directoryでは
ルート内のコンポーネント
レイアウトとかページっていうのを
サーバークライアントその両方で
レンダリングできることを注目すると
よいでしょうと言ってますね。
続いて
ちょっと翻訳が遅いんですけども
これはNexusJSのPages Directory
っていうのは異なっていて
デフォルトではデータフェッチ要件がない限り
ページは静的に生成されます。
ページでは
NexusJSのデータ取得メソッド
いわゆるGetStaticPropsと
GetServerSidePropsですね。
とかクライアントサイドからの
データ取得によって
いつっていうのはその構築時とか
実行時とかですかね。
どこで、どこでっていうのは
サーバーサイドとかクライアントサイド
またはその組み合わせで
ページを表示させるかっていうのを
柔軟に決定することができるようになります
と言ってますね。
しかしAppFolder内で
レンダリング環境っていうのは
データ取得メソッドから切り離され
コンポーネントレベルで設定されますと
この場合でもクライアントコンポーネントと
サーバーコンポーネントの制約を
尊重する必要はあります。
例えばクライアントコンポーネントで
ゲットサーバーサイドプロプスメソッド
使用することはできないでしょうと
クライアントコンポーネントで
サーバーサイドプロプス
ゲットサーバーサイドプロプスメソッドを
使うことはもちろんできませんよ
と言ってますね。
そこの辺は守ってますと言ってますね。
柔軟だけどそこ
サーバーとクライアントの区分けってところは
厳密に守りますよと言ってますね。
続きまして
18:03
なんだ
チルドレンプロプスを使用した
サーバーコンポーネントの
その根材の配置についてって話ですね。
リアクトでは
サーバーコンポーネントを
クライアントコンポーネント内に
インポートする際に制限があります。
サーバーコンポーネントには
サーバー専用のコード
データベースやファイルシステムの
ユーティリティなどが含まれる可能性があるからです。
例えばサーバーコンポーネントを
インポートしまうといけないでしょうと言って
サンプルコードがあるんですけど
サンプルコードちょっと音読になりますけど
インポートで
クライアントコンポーネント.jsというファイルを
インポートして
クライアントコンポーネント
これ関数コンポーネントとして定義してますけど
exportdefaultでfunctionで
クライアントコンポーネントというのを定義して
そのリターンのjsxの中に
先ほど読み込んだサーバーコンポーネント
っていうのを配置しても
動くわけないですよねって話をしています。
それに関して
コメントがあって
しかしながら
サーバーコンポーネントっていうのは
クライアントコンポーネントの
別のサーバーコンポーネントで
ラップすることで可能になります。
例えばこんなソースコードですよって言って
ソースコード長ぇな
ちょっとまだわかりづらいですけど
すいませんが口頭で読んでいきますね。
まずクライアントコンポーネント.jsですね。
こちらでは
単純に関数定義してますね。
exportdefaultのfunctionで
クライアントコンポーネントっていうのを定義してます。
引数にchildrenを受け取って
リターンの中でそのchildrenを
jsxで展開してますよっていうのが
クライアントコンポーネントです。
サーバーコンポーネント.jsの方では
同じように
関数コンポーネントを定義してます。
こっちはexportdefaultのfunctionで
サーバーコンポーネントっていう関数を定義して
リターンで
普通にjsxを返しているって感じですね。
最後page.jsっていうファイルですね。
page.jsっていうので
先ほどのクライアントコンポーネントと
サーバーコンポーネントっていうのを
コンポーネントをインポートしますと。
page.jsの方で
最後関数コンポーネントを定義してます。
こっちはexportdefaultのfunctionで
サーバーコンポーネントページっていうような
関数を定義してます。
その中にリターンで
jsxで囲ってあげて
クライアントコンポーネントを配置して
その中に
個要素としてサーバーコンポーネントを
配置してます。
こういう使い方をすることができますよと
言ってますね。
これによって何と混在とかした配置の
コンポーネントと
クライアントコンポーネントは
チルド連で受け取ってるので
そのチルド連がサーバーコンポーネントで
返ってくると。
サーバーコンポーネントは基本的には
計算処理とか
レンダリングのhtmlのところの処理が
終わったものが文字列として返ってくるはず
なんでそれを単純に受け取って
ただ組み込んでるだけっていうので
それはできるんだなって感じがしますね。
これについてちょっとコメントがあるので
21:01
そのコメントも読んでいきますと
翻訳しますと
このパターンですね
先ほどの例のパターンでは
リアクトはサーバーコンポーネントを
サーバーでレンダリングしてからその結果
サーバー専用のコーダー含まれないものを
クライアントに送信する必要がある
っていうのを認識してくださいと。
クライアントコンポーネントの観点では
その子はすでにレンダリングをされていると。
レイアウトでは
このパターンが子供のプロプスで
適用されるので
追加のラッパーコンポーネントを
受け取ることができますよというふうに
言っていますね。
例えば
クライアントレイアウトコンポーネントというのは
サーバーページコンポーネントというのを
子供として受け取ることができますよと
言っていますね。
それのソースコードを見ていくと
ダッシュボードレイアウトというのを
クライアントコンポーネントで見ていますよと。
ディレクトリ構成としては
アップの下にダッシュボードディレクトリを切って
その下にレイアウト.jsというファイルがある
というふうに認識してください。
このファイルは
エクスポードデフォルトのファンクションで
クライアントレイアウトという関数コンポーネントを
定義しています。
引数にチルドレンを受け取っていますね。
そのチルドレンを
リターンの.jsxの中に含めています。
もう1個
さっきと別のファイルですね。
アップの下にダッシュボードディレクトリを
切ってあってそこは一緒ですね。
そこにさらにセッティングスという
ディレクトリを切ってページ.jsですね。
これはセッティングというページを
この中にサーバーページというような
関数コンポーネントを切って
.jsxを返していると。
こんな感じでやると
レイアウトというのは
基本的には適用されますという感じですね。
これはすみません。
Next.jsのこのブログの
もっと前の方を読んで
予備知識で持ってないと
多分何の話だねってなると思いますけど
AppDirectoryの回想構造の中で
上の方で定義した
レイアウト.jsというファイルは
そのネストした下の方の
ページでもそのレイアウトというのが
適用されますよって言ってて
なのでそのレイアウト.jsという
ファイルの中にチルドレンを
引数で受け取っているのであれば
その下の方のページでも
そのレイアウトが適用される
ということを言っているなと思います。
じゃあ最後ですね。
ちょっと注意書きがあるので
そこを見ていきますが
このスタイルの構成というのは
サーバーコンポーネンツを
クライアントコンポーネンツの中に
レンダリングするための
クライアントコンポーネンプロパティーを
使用することにした理由の一つにも
なりますよと言ってましたね。
といったところで
サーバーコンポーネンツの
章も終わりって感じですね。
これで
エクゾ.jsのレイアウトRFCも
一応一通り読み切ったというところで
今日の朝会はこちらで
読むものすべて読み切ったので
以上にしたいかなと思います。
では最後に宣伝になりますけども
コンパスで
勉強会を
24:00
始めまして
フロントエンドエンジニアの
ビアバッシュっていう勉強会を
開き始めました。
前回、先月かな
先月終わりに一回オフラインのイベント
やったんですけど
今度はオンラインイベントをやろうと思います。
7月2日の土曜日の10時から
フロントエンドエンジニアLT
ビアバッシュっていうのをやってます。
これはオフラインとオンラインを
交互にやる会です。
次回はオンラインで
次はまたオフラインでやろうかなと思ってます。
なので7月2日もし
ご興味ある方は参加していただけたら
嬉しいなと思います。
ゆるいフロントエンドの領域の話を
みんなでワイワイとしゃべりつつ
ビール飲もうぜっていう感じになってますので
ご参加いただければなと思います。
では今日の朝活は
ちょっと早いですけど
こちらで以上にしたいかなと思います。
では今日も一日頑張っていきましょう。
お疲れ様でした。