Open17

雑なメモ

flowerflower

https://engineers.weddingpark.co.jp/about/frontend/

Next.jsではデフォルトで
pre rendering
が有効になっている。

pre renderingはページのHTMLを事前に生成する。SEOも良くなる。
生成されたHTMLはブラウザで最低限のJSを実行して、
インタラクティブな
ページを完成させる。

→ これをhydrationと呼ぶ(静的なHTMLを読み込んだ後にページを操作可能にするためにJavaScriptを読み込む処理をハイドレーション(Hydration)と呼びます。)

React では、初回表示のものはなく、すべてのReact Component がJSの実行を待ってから表示される。
そのため初期描画に時間がかかってしまう。

Next.jsでは2種類のpre renderingがある。

  1. Static Generation:ビルド時にHTMLを事前生成、それをリクエストごとに再利用
    → Next.jsは基本的にこちらを推奨。一度ページを生成してCDNの利用が可能
    →ブログ投稿、商品一覧、ヘルプページ
  2. Server side renderign:リクエストのたびにHTMLが再生成される
    →データ更新が頻繁にある、リクエストごとに表示するコンテンツを切り替えたいページ
    →SSGと比べるとページ表示速度パフォーマンスは下がるがページを常に最新の状態にすることができる

また、ページごとに使用するpre renderd方式を選ぶことができるため上記2種類のハイブリッド構成が可能になる

なお事前にデータを取得しないとHTMLの生成ができない場合がある(ビルド時に画像ファイルを取得したり外部APIをフェッチしたりなど)
getStaticPropsを使うと事前処理が可能になります。
getStaticPropsはasync関数で、本番ビルド時に実行され、関数内では外部データをフェッチしてページに渡されます。

https://www.ragate.co.jp/blog/articles/10524

CSR(Client Side Rendering)
CSR はブラウザ側で HTML/CSS を生成する際に JavaScript が実行されます。
初回にページ全体を処理するため、初回の読み込みは重くなりますが初回以降のページ遷移などのインタラクションは高速です。

1 ブラウザが指定 URL へリクエストし、<body>が空っぽの HTML を取得
2 ブラウザは JS を実行し HTML や CSS 等を<body>へレンダリング
3 ブラウザは HTML の<body>に展開された HTML 情報を表示
※ CSR で配信されているアプリケーションを一般的に SPA(Single Page Application)と呼びます

SSR(Server Side Rendering)
SSR はサーバー側でレンダリング(描画)を行うため、CSR と比較するとブラウザで Javascript を実行するコストがないのが大きな利点です。

1 ブラウザが指定 URL へリクエスト
2 サーバー(NodeJS)がリクエストを受け取り、リクエストに応じて HTML/CSS 等を生成
 3 完成した HTML/CSS をブラウザへレスポンス
※ SSR については後述で詳しく解説

SSG(Static Site Generator)
SSG はビルド時に HTML などのコンテンツが生成され、
各リクエスト時に再利用してブラウザに渡す手法です。

CSR・SSR はリクエスト時にビルドを行なっていましたが、
SSG は事前に作成された静的ファイルを返すだけなので表示速度が CSR・SSR に比べ高速です。

ページの更新時にアプリケーション全体をビルドしないといけないため
ページ数が多い大規模なアプリケーションには不向きです。

ブラウザが指定 URL へリクエスト
ビルド時に生成された静的ファイルをブラウザへレスポンス
flowerflower

CSR(Client Side Rendering)
ブラウザでJSが実行されて画面が描画される、そのためクライアントの性能に大きく影響を受ける
SEOに関してクローラがちゃんと読んでくれないと言われていた→現在は問題ないらしいが、SNSなどのOGP表示はいまだに問題がある?

flowerflower

レンダリングとは

まぁ「レンダリング」って単語が出てきたら「もとになる情報を整形して表示することなんだな~」と、お考えください。

Reactライフサイクルに関して
https://zenn.dev/yodaka/articles/7c3dca006eba7d

関数コンポーネントにおける useEffect について (ブラウザに描画されるまでの流れとか)
https://overreacted.io/ja/a-complete-guide-to-useeffect/

flowerflower

https://zenn.dev/taroro28/articles/49e95f01bab7ae

なぜクリーンアップでは変化前の値を参照するのか?
これはクリーンアップの目的を考えると自然に理解できます。

クリーンアップはUnmount時と再render後にその前の副作用を解除するために使われ、解除するためには通常、変化前の値を使用します。

flowerflower

Node.jsはJSのランタイム環境。フロントエンドの開発にも使用される
ReactはJSのライブラリ。Next.jsはReactをベースにしたフレームワーク。

Node.jsはサーバーサイドのJavaScript開発に使用され、Next.jsはNode.js上で動作するReactフレームワークである。

ランタイム環境とは

ランタイム環境(Runtime Environment)は、ソフトウェアの実行時に必要な実行環境のことを指します。プログラムが実行されるためには、そのプログラムを解釈・実行するための実行環境が必要です。
具体的な例として、JavaScriptの場合を考えてみましょう。JavaScriptはブラウザ上で実行されることが一般的ですが、そのためにはJavaScriptエンジンと呼ばれる実行環境が必要です。代表的なJavaScriptエンジンには、Google ChromeのV8エンジンやMozilla FirefoxのSpiderMonkeyエンジンなどがあります。これらのエンジンは、JavaScriptコードを解釈して実行する役割を担っています。
同様に、Node.jsもJavaScriptのランタイム環境です。Node.jsはサーバーサイドでJavaScriptを実行するための環境を提供します。Node.jsはV8エンジンをベースにしており、JavaScriptコードを解釈・実行する機能を提供します。これにより、サーバーサイドでJavaScriptを使用してアプリケーションを開発することができます。
言語によって異なりますが、ランタイム環境はプログラムの実行に必要な機能やライブラリ、リソースを提供するものです。それによって、プログラムが実行される環境やプラットフォームに依存せずに、コードを実行できるようになります。
つまり、ランタイム環境はプログラムが実行されるために必要な実行エンジンやライブラリ、リソースを提供する実行環境のことを指し、それによって特定のプログラミング言語やフレームワークが動作する基盤を提供します。

サーバーサイドの定義

サーバーサイド(Server-Side)は、ウェブアプリケーションやクライアント-サーバーモデルにおいて、サーバー側のコンポーネントや処理を指す用語です。一般的に、サーバーサイドはクライアントからのリクエストを処理し、必要なデータや動的なコンテンツを生成してクライアントに応答する役割を担います。
具体的なサーバーサイドの定義は以下のような要素を含みます:
サーバーソフトウェア:サーバーソフトウェアは、ハードウェア上で動作するサーバーのソフトウェアコンポーネントです。例えば、Apache、Nginx、Microsoft IISなどが一般的なウェブサーバーソフトウェアです。これらのソフトウェアは、クライアントからのリクエストを受け取り、それに対する応答を生成します。
バックエンド処理:サーバーサイドは、クライアントからのリクエストに対して必要なデータの処理やビジネスロジックの実行を行います。データベースへのクエリの実行、外部APIとの通信、セキュリティの処理など、バックエンド処理の多くがサーバーサイドで行われます。
サーバーサイド言語やフレームワーク:サーバーサイドでは、特定のプログラミング言語やフレームワークを使用してアプリケーションを開発します。例えば、Node.jsやRuby on Rails、PythonのDjangoなどは一般的なサーバーサイドの開発ツールです。これらのツールは、サーバーサイドの処理やリクエストのハンドリングを支援します。
データの保存と管理:サーバーサイドでは、データベースやキャッシュなどのデータストアを使用してデータを永続化および管理します。クライアントからのリクエストに基づいてデータを読み書きし、必要な情報を提供するためにデータの保存と管理が行われます。
サーバーサイドの役割は、クライアントとのインタラクションやデータ処理、セキュリティ、パフォーマンスの最適化など、多岐にわたります。クライアントからのリクエストに対して適切な応答を返すために、サーバーサイドの開発は重要な役割を果たします。

flowerflower

awaitの役目?Promiseから中身を取り出す

特殊なフック RFC

従来のSuspenseと異なる点は、従来はReactは「投げられたPromiseが解決したら再度レンダリングを試みる」ことのみをサポートしており、Promiseの中身を取り出すことは我々に任されていました。それに加えて、useではPromiseの中身を取り出すところまでやってくれるのが新しい点です。
https://zenn.dev/uhyo/articles/react-use-rfc

flowerflower

コンパイル→ソースコード(人間が理解できるコード)をコンピュータが理解できるコード(オブジェクトコード、バイナリコード)に変換すること

ビルド→ソースコード上に問題がないかどうかを解析を行った上で、問題なければオブジェクトコードに変換し、複数のオブジェクトファイルを1つにまとめて実行可能なファイルを作成する作業
(コンパイル < ビルド)

flowerflower

React Server Componentsの仕組み:詳細ガイド
https://postd.cc/how-react-server-components-work/

RSCのハイレベルな戦略を簡略化すると以下のような形になります。 サーバは、いつも通りサーバコンポーネントをレンダリングし、ReactコンポーネントをdivやpなどのネイティブHTML要素に変換します。 しかし、ブラウザ上でレンダリングされるクライアントコンポーネントに遭遇すると、代わりにプレースホルダを出力します。 サーバは、プレースホルダーに適切なクライアントコンポーネントとpropsを適用するように指示を加えます。 ブラウザはこの出力を受け取り、クライアントコンポーネントで穴埋めを行います。

flowerflower

S3にビルドしたものを配置する

動的なアプリケーションを作成する場合でも、フロントエンドがReact Next.jsで実装され、バックエンドがRailsである場合は、フロントエンドをS3にデプロイすることが可能です。

動的なアプリケーションには、ユーザーの入力に応じてリアルタイムでコンテンツを更新する機能が含まれることが一般的です。React Next.jsとRailsの組み合わせを使用することで、Reactを使ってクライアント側でインタラクティブなUIを作成し、Railsを使ってバックエンドのデータ処理やAPIエンドポイントを提供することができます。

フロントエンドをS3にデプロイするためには、次のような手順を実行します:

React Next.jsアプリケーションをビルドします:
bash
Copy code
npm run build
ビルドされたアプリケーションをS3バケットにアップロードします。

S3バケットのパブリックアクセス設定を適切に構成し、必要に応じてCloudFrontを設定してコンテンツをキャッシュすることができます。

ユーザーはブラウザからS3にホストされたReact Next.jsアプリケーションにアクセスします。

React Next.jsアプリケーションはユーザーのリクエストに応じてバックエンドのRailsアプリケーションと通信し、動的なコンテンツを取得・表示します。

この構成では、React Next.jsアプリケーションはクライアント側で動作し、バックエンドのRailsアプリケーションとAPI通信を行いながら、ユーザーに対してリアルタイムな体験を提供します。フロントエンドをS3にデプロイすることにより、コスト効率を向上させ、スケーラビリティを確保できます。また、バックエンドのRailsアプリケーションは別のサーバーにデプロイすることで、フロントエンドとバックエンドの分離が可能になります。

flowerflower

RSCサーバコンポーネント
CCクライアントコンポーネント
fetch を RSC で実行すると Next.js 側でキャッシュされるため、パフォーマンスの改善や重複した API 呼び出しの排除が期待されます。
fetch を CC で実行する場合は、useEffect 等の Hooks を用いて過剰な呼び出しを抑制する必要があります。

https://github.com/ZDK-UTsukuba/ipc-web-training-2024/blob/master/phase3/handouts/3-コンポーネント.md#サーバコンポーネントクライアントコンポーネント