RedisでNext.jsアプリケーションを高速化する方法
Next.jsは、サーバーサイドレンダリング(SSR)と静的サイト生成(SSG)を組み合わせた、非常に人気の高いWebフレームワークです。SSGはCDNキャッシュによってWebサイトの表示速度を向上させ、SSRはSEO対策や動的なデータ処理において大きな強みとなります。
サーバーサイドレンダリングは、フルスタックアプリケーション開発を支援してくれる優れた機能です。しかし、注意深く設計しないと、Next.jsサイトのパフォーマンスは容易に低下してしまいます。本記事では、Redisを活用してNext.jsのAPI呼び出しを高速化する方法を解説します。その前に、まずはよりシンプルなパフォーマンス改善手法についても簡単にご紹介します。
API呼び出しにはSWRを活用する
SWRは非常に賢いデータフェッチライブラリです。HTTP RFC 5861で定義されているキャッシュ戦略「stale-while-revalidate」を採用しています。SWRでAPIを呼び出すと、まずキャッシュされたデータを即座に返し、その後バックグラウンドで非同期に最新データを取得してUIを更新します。さらに、データの鮮度に対する許容度に応じてrefreshIntervalを設定することも可能です。
const { data: user } = useSWR('/api/user', { refreshInterval: 2000 })
上記のコードでは、ユーザーAPIが2秒ごとに自動的に更新されます。
Redisによるキャッシング
SWRはシンプルかつ効果的ですが、サーバーサイドでのキャッシングが必要になるケースもあります。
- クライアント数が多い場合: クライアントサイドキャッシュはクライアント側のパフォーマンスを向上させますが、クライアント数が膨大になるとサーバー側のリソースに高負荷がかかり、結果としてクライアント側のパフォーマンスにも悪影響を及ぼします。
- 外部APIに利用制限がある場合: クォータ付きの外部APIを利用している場合は、サーバー側でAPI使用量を管理したいはずです。管理しないと、多数のクライアントによってあっという間にAPIの上限に達してしまいます。
- 動的な入力値を扱う場合: サーバー側で動的な入力をもとに計算・取得・加工されるリソースについては、クライアントサイドキャッシュはあまり効果を発揮しません。
実例プロジェクト:Covidトラッカー
ここでは、Javier Aviles氏のCovid APIを使用し、感染者数の多い上位10カ国を表示するプロジェクトを取り上げます。デモサイトとソースコードも公開されているので、ぜひ確認してみてください。
このプロジェクトでは、Covid APIからのレスポンスをRedisでキャッシュします。これにより以下のメリットが得られます。
- レスポンスの大幅な高速化: 実際のサイトで確認すると、Covid APIへの直接アクセスには数百ミリ秒かかるのに対し、Redisからの取得はわずか1〜2ミリ秒で完了します。
- 外部APIの保護: 大量のリクエストによってCovid APIへ過度な負荷をかけることを防ぎます。
APIコード
以下のコードは、まずAPIの結果がRedisにキャッシュ済みかどうかを確認します。キャッシュが存在しない場合は、Covid APIから全世界の国リストを取得し、当日の感染者数順にソートして上位10カ国をRedisに保存します。保存時にはEX 60パラメータを指定しており、これにより60秒後にエントリが自動的に削除されます。
import Redis from "ioredis";
let redis = new Redis(process.env.REDIS_URL);
export default async (req, res) => {
let start = Date.now();
let cache = await redis.get("cache");
cache = JSON.parse(cache);
let result = {};
if (cache) {
console.log("loading from cache");
result.data = cache;
result.type = "redis";
result.latency = Date.now() - start;
return res.status(200).json(result);
} else {
console.log("loading from api");
start = Date.now();
return fetch("https://coronavirus-19-api.herokuapp.com/countries")
.then((r) => r.json())
.then((data) => {
data.sort(function (a, b) {
return b.todayCases - a.todayCases;
});
result.data = data.splice(1, 11);
result.type = "api";
result.latency = Date.now() - start;
redis.set("cache", JSON.stringify(result.data), "EX", 60);
return res.status(200).json(result);
});
}
};
UIコード
UI部分はシンプルなReactコードです。SWRを使ってAPIからデータを取得します。
export default function Home() {
function refresh(e) {
e.preventDefault();
window.location.reload();
}
const { data, error } = useSWR("api/data", fetcher);
if (error) return "An error has occurred.";
if (!data) return "Loading...";
return (
<div className={styles.container}>
<Head>
<title>Covid Tracker</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>Covid Tracker</h1>
<p className={styles.description}>
Top 10 countries with the most cases today
</p>
<div className={styles.grid}>
<div className={styles.card} onClick={refresh}>
<table className={styles.table}>
<thead>
<tr>
<th>Country</th>
<th>Today Cases</th>
<th>Today Deaths</th>
</tr>
</thead>
<tbody>
{data.data.map((item) => (
<tr>
<td>{item.country}</td>
<td>{item.todayCases}</td>
<td>{item.todayDeaths}</td>
</tr>
))}
</tbody>
</table>
<br />
<em>
Loaded from {data.type} in <b>{data.latency}</b> milliseconds.
Click to reload.
</em>
</div>
</div>
</main>
<footer className={styles.footer}>
This is a sample project for the blogpost
<a
href="https://blog.upstash.com/nextjs-caching-with-redis"
target="_blank"
rel="noopener noreferrer"
>
Speed up your Next.js application using Serverless Redis for caching.
</a>
</footer>
</div>
);
}
外部リンク
-
Cloudflare WorkersとRedisで実現するエッジコンピューティング活用術
エッジコンピューティングは、近年もっとも注目されている技術のひとつです。CDNがファイルをユーザーの近くに配置できるようにしたのと同じように、エッジコンピューティングはアプリケーションそのものをユーザーの近くで実行できるようにします。これにより、開発者はグローバルに分散され、高いパフォーマンスを発揮するアプリケーションを構築できるようになります。 Cloudflare Workersとステートレス性の課題 現在この分野をリードしている製品がCloudflare Workersです。コールドスタートのないサーバーレス実行環境を提供し、Cloudflareのグローバルネットワークを活かすことで、ア
-
MSCONFIGでPCを高速化する方法|Windowsの起動を最適化する手順を解説
Windows向けに作られたコマンドの中で、最も優れていると私たちが考えるのがMSCONFIGです。MSCONFIGは過去のWindowsバージョンから搭載されており、Windows 10にも当然のように存在しています。この記事を読み進めれば、その理由がきっと分かるはずです。MSCONFIGを使ってPCを高速化する方法を、ぜひマスターしましょう。 MSCONFIGはなぜ便利なのか? MSCONFIGではさまざまな設定を管理できますが、特に注目したいのは、自動的に起動するプログラム(スタートアップ)を制御できる点です。これらのプログラムは貴重なメモリを消費しており、PCの読み込み時間を長引かせ、