Next.jsでSSRを簡単にするには 其の壱「旅立ち」
こちらに同じ内容を書いています
1. Next.jsでのSSRはApolloが優秀
検索Botの性能が微妙な頃、SPAのWebシステムではSSRが重要な位置を占めていました。みんな必死にSSRを行うための取り組みを行いました。しかしクライアントで動くべき物をサーバで実行し、その結果を返すというのは、それなりの無理が生じます。無理を通しているが故に、開発コストに跳ね返ってしまうのです。
コストを抑えつつSSRを導入しようとした場合、GraphQLとApollo導入が無難な流れとなります。Apolloのキャッシュ機能を利用すれば、サーバ側で生成したデータを短いステップでクライアントに引き継ぐことが出来るからです。一回手続を書いておけば、その他の部分ではクライアントとサーバのコードを別々に書く必要はありません。
ではGraphQLを使わなかった場合はどうでしょう?選択肢を調べてみましたが、Apolloのようにサーバ側で生成したキャッシュをまとめて引き渡すような便利なライブラリが見つかりませんでした。大抵の場合、地道に部分部分で引き渡しコードを書いている形です。
2. Next.js上でSSRをする時に使う物
- _app.tsx上でApp.getInitialProps
- 各Page上でgetInitialProps
- 各Page上でgetServerSideProps
現時点で推奨されているのはgetServerSidePropsです。サーバでしか実行されず、その実行結果はクライアント側に送られます。ただこれ、デフォルトだとSPAのページ切り替えごとにサーバにデータを取りに行きます。一応、shallowパラメータを設定すれば再ロードを回避することは可能なのですが、propsには古いデータが残ってしまい、キャッシュの更新判定が面倒なことになります。ぶっちゃけて言うと、キャッシュのことを考えずに、とにかくデータが受け取れれば良いという場合にしか使い道がありません。
各Page上でgetInitialPropsの方も、ページを作るごとに個別に受け渡し処理を作成するのも面倒です。
やはり理想はApolloのApp.getInitialPropsを使ったキャッシュ引き渡しです。Next.jsでのビルド時に、「推奨していないApp.getInitialPropsをまだ使ってるの?getServerSideProps使いなよ」と文句を言われますが、まともな選択肢が他にないのです。
3. useSWRを試してみる
とりあえず上手いやり方は無いかと使い勝手が良いと話題のuseSWRを試してみました。fetchのURLをキーにして、取得データをキャッシュすることが出来ます。しかも取得したキャッシュに自由にアクセスが可能です。これはと思ったのもつかの間、以下の問題により断念しました。
- useSWRは適度なタイミングでデータをとりにいく事が目的で、必要ないときはデータをとらないという機能が無い
- dedupingIntervalに大きな値を設定すれば一応データを取りに行かなくなるけど、とらないフラグ付けて
- タイミングが色々指定できるし便利だけど、今欲しいのはそれじゃない
- そして最も重要なポイント、cacheで自由にキャッシュを書き換えることは出来た、確かに出来た。しかしfetchの戻り値を個別管理していて、次のターンで復元される
useSWRのソースを眺めてみた結果、cacheにはアクセスできるけど、データの流れ的にfetchの戻り値をがっちり持っていて、根本を書き換えないと理想的な動作にならないことが判明。
4. useSWRのような使い勝手でApolloみたいなことをするには
結論「自分で作るしかない」
ということで願いを叶えるため、自前のuseSWRのHooksの構造とApolloキャッシュ構築方法をパクり、オレオレuseFetchを作りはじめした
現在の進行状況(基本的な実装は完了)
天気予報を取得しSSRしつつキャッシュを保持のサンプル
https://github.com/SoraKumo001/use-fetch-sample01
次回 Next.jsでSSRを簡単にするには 其の弐「流浪」