このページ内容は2021年1月21日以降、再調査・再検証してません。実際に扱う際は最新の情報にアクセスしてください。
RemixはCDNのEdge部分でSSRできるReactの新しいフレームワークですremix。Remixでは以下4つの理念からなる特徴を持っていますremix_philo。
まず1つ目ですが、Remixではクライアント-サーバーモデルを採用しているため、クライアント側で完結するSSGをサポートせず、Edge領域でのSSRを活用します。このことにより、動的コンテンツを提供するアプリでも静的サイト並みの速度を提供できるそうですremix_performance。
またRemixではネットワーク送信量を減らす機能が豊富にあります。これはサーバー側は高速化できるが、ユーザーのネットワークは改善しようがないことを認識しているためです。例えば、GitHubのGist APIを単純に使う場合は以下のようになりますが、このように書く場合は不要な情報も含まれるため、送信されるデータ量は多くなりますremix_server_client_model。
1export default function Gists() {2const gists = useSomeFetchWrapper("https://api.github.com/gists");3// React18を使うなら、Suspenseで置き換えできるため不要4if (!gists) return <Skeleton />;56return (7<ul>8{gists.map(gist => (9<li>10<a href={gist.html_url}>11{gist.description}, {gist.owner.login}12</a>13<ul>14{Object.keys(gist.files).map(key => (15<li>{key}</li>16))}17</ul>18</li>19))}20</ul>21);22}
対してRemixを使う場合はユーザーにデータを送信する前に、loader関数でデータをフィルタリングできるため、以下のように書くことができます。このようにフィルタリングすることで送信するデータ量を少なくできます。
1// サーバー側でのデータのフィルタリング2export async function loader() {3const res = await fetch("https://api.github.com/gists");4const json = await res.json();5return json.map(gist => {6return { url: gist.html_url, files: Object.keys(gist.files), owner: gist.owner.login };7});8}910export default function Gists() {11const gists = useLoaderData();12return (13<ul>14{gists.map(gist => (15<li>16<a href={gist.url}>17{gist.description}, {gist.owner}18</a>19<ul>20{gist.files.map(key => (21<li>{key}</li>22))}23</ul>24</li>25))}26</ul>27);28}
2つ目として、RemixではWebの標準的な機能を活用するために、独自のリクエスト/レスポンス APIなどを作らず、Fetch APIを活用します。例えば、Fetch APIのHeadersインターフェースremix_headersを使うと、HTTPリクエストやレスポンスヘッダーに応じた処理ができますが、RemixでもloaderHeaders関数として利用できます。また、このようなHTTPヘッダーを各ルート (異なるパス) ごとに作成できるのもRemixの特徴ですremix_path_headers。
1export function headers({ loaderHeaders }) {2return {3"Cache-Control": loaderHeaders.get("Cache-Control")4};5}
ヘッダーだけでなく、metaタグもパスごとに設定できますremix_meta_tag。
1import type { MetaFunction } from "remix";23export const meta: MetaFunction = () => {4return {5title: "Something cool",6description:7"This becomes the nice preview on search results."8};9};
3つ目はRemixではユーザー体験を向上させるために、ページ遷移時はレイアウトの変更部分のみデータ取得するように動きます。これはNested Routingという機能が関わってきます。言葉や図で説明するのが難しいので、こちらをみてくださいremix_routing。
頑張って文で説明すると、/invoices/12から/invoices/12/editにページ遷移する場合を考えます。(Suspenseを使う場合は少し変わりますが) Next.jsの場合は遷移先のページで必要なJavaScriptやCSSを取得してからページが変わります。しかし、Remixでは変更先で必要な部分のみ取得して更新し、共通部分はそのまま維持され再描画しません。また、必要な部分のみを取得して更新できる特性から、そのページで必要なコンポーネントを並行してダウンロードできます。
ここら辺の技術的な話は理解も説明も難しいため、気になる方はまだ未整理のドキュメントremix_routing2や他の文献を探してみてください。Remixのこの機能はreact-routerのv6で追加された機能と同じなので、こちらのリポジトリも参考になるかもしれませんreact_router。
4つ目にRemixのAPIは基本的なHTTPやブラウザ, JavaScriptの機能をラップしてますが、過度に抽象化しないように気をつけて作られているようです。(具体的な例をもって説明はできませんが) 汎用性のある技術を学べる点もRemixの良い点だと感じます。
Remixは他にも以下のような面白い特徴を持っています。
Next.jsだとページが存在しないときに、ステータスコード 404で404ページを返すにはひと手間必要ですnextjs_404。しかし、Remixを使う場合は何も設定しなくても、ページが存在しないときは404のステータスコードと一緒に404ページを返してくれます。
Nuxt3ではビルド時にデプロイ先を決めることができますが、Remixではアプリ作成時にデプロイ先を選びます。候補としてはfly.ioやAWS Lambda, Cloudflare Workersなどがありますremix_deploy。アプリを作り始めたらすぐにデプロイできるようにこのようにしているらしいです。
VercelにもChecksというサービスを統合できるようになりましたが、RemixにもMetronomeというWeb Vitalsやアクセス数、発生したエラーの詳細を確認できるサービスがありますremix_metronome。Rollbarなどをフロントに入れなくても、エラーの詳細が確認できるなら、ありがたいですが、まだ試してないので、詳細は分かりません。
Remixにはいくつかサンプルアプリremix_sampleもあるので、興味のある方はぜひ試してみてください。