Skip to content

Update translations #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
396 changes: 396 additions & 0 deletions apps/docs/content/ja/blog/building-apis-with-nextjs.mdx

Large diffs are not rendered by default.

202 changes: 202 additions & 0 deletions apps/docs/content/ja/blog/composable-caching.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
---
source-updated-at: 2025-05-29T18:05:49.000Z
translation-updated-at: 2025-06-03T22:46:51.057Z
title: Next.js におけるコンポーザブルなキャッシュ
description: キャッシュ機能 'use cache' の API 設計と利点について学びます
author:
- name: Lee Robinson
image: /static/team/lee.jpg
date: 2025-01-03T14:00:00.507Z
image: >-
https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/composable-caching/twitter-card.png
---

Next.js 向けにシンプルで強力なキャッシュモデルの開発を進めています。前回の投稿では、[キャッシュとの歩み](/blog/our-journey-with-caching)と `'use cache'` ディレクティブに至った経緯についてお話ししました。

この投稿では、`'use cache'` の API 設計と利点について説明します。

[`'use cache'` とは?](#what-is-use-cache)
--------------------------------------------

`'use cache'` は、必要に応じてデータやコンポーネントをキャッシュすることでアプリケーションを高速化します。

これは JavaScript の「ディレクティブ」—コードに追加する文字列リテラル—であり、Next.js コンパイラに異なる「境界」に入ることを伝えます。例えば、サーバーからクライアントへの移行などです。

これは React の `'use client'` や `'use server'` といったディレクティブと同様の考え方です。ディレクティブはコードの実行場所を定義するコンパイラ指示であり、フレームワークが個々の要素を最適化・調整できるようにします。

[動作原理](#how-does-it-work)
--------------------------------------

簡単な例から見ていきましょう:

```
async function getUser(id) {
'use cache';
let res = await fetch(`https://api.vercel.app/user/${id}`);
return res.json();
}
```

内部的には、Next.js は `'use cache'` ディレクティブによりこのコードをサーバー関数に変換します。コンパイル時に、このキャッシュエントリの「依存関係」が検出され、キャッシュキーの一部として使用されます。

例えば、`id` はキャッシュキーの一部になります。`getUser(1)` を複数回呼び出すと、キャッシュされたサーバー関数からメモ化された出力が返されます。この値を変更すると、キャッシュに新しいエントリが作成されます。

[クロージャ](https://v0.dev/chat/5kD47RIecQK?b=b_rCP4CvfbFFW)を使用したサーバーコンポーネントでのキャッシュ関数の使用例を見てみましょう。

```
function Profile({ id }) {
async function getNotifications(index, limit) {
'use cache';
return await db
.select()
.from(notifications)
.limit(limit)
.offset(index)
.where(eq(notifications.userId, id));
}

return <User notifications={getNotifications} />;
}
```

この例はより複雑です。キャッシュキーの一部となるべきすべての依存関係を見つけられますか?

引数 `index` と `limit` は理解しやすい—これらの値が変更されると、通知の異なるスライスを選択します。しかし、ユーザー `id` はどうでしょうか?その値は親コンポーネントから来ています。

コンパイラは `getNotifications` が `id` にも依存していることを理解でき、その値は自動的にキャッシュキーに含まれます。これにより、キャッシュキーにおける依存関係の不足や誤りによるキャッシュ問題の全カテゴリを防ぎます。

[キャッシュ関数を使用しない理由](#why-not-use-a-cache-function)
--------------------------------------------------------------

前の例を再考しましょう。ディレクティブの代わりに `cache()` 関数を使用できないでしょうか?

```
function Profile({ id }) {
async function getNotifications(index, limit) {
return await cache(async () => {
return await db
.select()
.from(notifications)
.limit(limit)
.offset(index)
// おっと! id をキャッシュキーに含める場所は?
.where(eq(notifications.userId, id));
});
}

return <User notifications={getNotifications} />;
}
```

`cache()` 関数はクロージャを調べて `id` の値をキャッシュキーの一部にすべきか判断できません。手動で `id` をキーの一部として指定する必要があります。これを忘れたり、誤ったりすると、キャッシュの衝突や古いデータのリスクが生じます。

クロージャはあらゆる種類のローカル変数を捕捉できます。単純なアプローチでは、意図しない変数が誤って含まれたり(または除外されたり)する可能性があります。これにより、誤ったデータがキャッシュされたり、機密情報がキャッシュキーに漏洩してキャッシュ汚染のリスクが生じたりする可能性があります。

`'use cache'` はコンパイラにクロージャを安全に扱い、キャッシュキーを正しく生成するための十分なコンテキストを提供します。`cache()` のようなランタイムのみのソリューションでは、すべてを手動で行う必要があり、ミスを犯しやすくなります。対照的に、ディレクティブは静的に分析でき、すべての依存関係を確実に処理できます。

[シリアライズ不可能な入力値の扱い](#how-are-non-serialized-input-values-handled)
--------------------------------------------------------------------------------------------

キャッシュする入力値には2種類あります:

* **シリアライズ可能**: ここで「シリアライズ可能」とは、意味を失うことなく安定した文字列ベースの形式に変換できる入力を指します。多くの人が最初に `JSON.stringify` を思い浮かべますが、実際には React のシリアライゼーション(例えばサーバーコンポーネント経由)を使用して、プロミス、循環データ構造、その他の複雑なオブジェクトなど、より広範な入力を処理します。これはプレーンな JSON ができることを超えています。
* **シリアライズ不可能**: これらの入力はキャッシュキーの一部ではありません。これらの値をキャッシュしようとすると、サーバー「参照」を返します。この参照は Next.js によってランタイム時に元の値に復元されます。

`id` をキャッシュキーに含めることを覚えていたとしましょう:

```
await cache(async () => {
return await db
.select()
.from(notifications)
.limit(limit)
.offset(index)
.where(eq(notifications.userId, id));
}, [id, index, limit]);
```

これは入力値がシリアライズ可能な場合に機能します。しかし、`id` が React 要素やより複雑な値であった場合、入力キーを手動でシリアライズする必要があります。`id` プロップに基づいて現在のユーザーを取得するサーバーコンポーネントを考えてみましょう:

```
async function Profile({ id, children }) {
'use cache';
const user = await getUser(id);

return (
<>
<h1>{user.name}</h1>
{/* children を変更してもキャッシュが壊れない...なぜ? */}
{children}
</>
);
}
```

この動作を順を追って説明します:

1. コンパイル中、Next.js は `'use cache'` ディレクティブを認識し、キャッシュをサポートする特別なサーバー関数を作成するためにコードを変換します。コンパイル時にキャッシュが行われるわけではなく、Next.js はランタイムキャッシュに必要なメカニズムを設定しています。
2. コードが「キャッシュ関数」を呼び出すと、Next.js は関数の引数をシリアライズします。JSX のように直接シリアライズできないものは、「参照」プレースホルダーに置き換えられます。
3. Next.js は指定されたシリアライズされた引数に対してキャッシュされた結果が存在するかチェックします。結果が見つからない場合、関数はキャッシュする新しい値を計算します。
4. 関数が終了すると、戻り値がシリアライズされます。戻り値のシリアライズ不可能な部分は参照に戻されます。
5. キャッシュ関数を呼び出したコードは出力をデシリアライズし、参照を評価します。これにより、Next.js は参照を実際のオブジェクトや値と交換でき、`children` のようなシリアライズ不可能な入力は元の、キャッシュされていない値を保持できます。

これは、`<Profile>` コンポーネントだけを安全にキャッシュし、子をキャッシュしないことを意味します。後続のレンダリングでは、`getUser()` は再度呼び出されません。`children` の値は動的であるか、異なるキャッシュ寿命を持つ別個にキャッシュされた要素である可能性があります。これがコンポーザブルなキャッシュです。

[これは見覚えが...](#this-seems-familiar)
--------------------------------------------

「サーバーとクライアントのコンポジションと同じモデルのように感じる」と思ったなら、まったく正しいです。これは時々「ドーナツ」パターンと呼ばれます:

* **外側**の部分はデータ取得や重いロジックを処理するサーバーコンポーネント
* 中央の**穴**はインタラクティブ性を持つ可能性のある子コンポーネント

```tsx filename="app/page.tsx"
export default function Page() {
return (
<ServerComponent>
{/* クライアントへの穴を作成 */}
<ClientComponent />
<ServerComponent />
);
}
```

`'use cache'` も同じです。ドーナツは外側のコンポーネントのキャッシュされた値で、穴はランタイム時に埋められる参照です。これが `children` を変更してもキャッシュされた出力全体が無効化されない理由です。子は後で埋められる単なる参照です。

[タグ付けと無効化については?](#what-about-tagging-and-invalidation)
----------------------------------------------------------------------------

キャッシュの寿命はさまざまな[プロファイル](/docs/app/api-reference/functions/cacheLife)で定義できます。デフォルトのプロファイルセットが含まれていますが、必要に応じてカスタム値を定義できます。

```
async function getUser(id) {
'use cache';
cacheLife('hours');
let res = await fetch(`https://api.vercel.app/user/${id}`);
return res.json();
}
```

特定のキャッシュエントリを無効化するには、[キャッシュにタグを付け](/docs/app/api-reference/functions/cacheTag)、`revalidateTag()` を呼び出します。強力なパターンの1つは、データ(例えば CMS から)を取得した後にキャッシュにタグを付けられることです:

```
async function getPost(postId) {
'use cache';
let res = await fetch(`https://api.vercel.app/blog/${postId}`);
let data = await res.json();
cacheTag(postId, data.authorId);
return data;
}
```

[シンプルで強力](#simple-and-powerful)
-------------------------------------------

`'use cache'` の目標は、キャッシュロジックの作成をシンプルかつ強力にすることです。

* **シンプル**: ローカルな推論でキャッシュエントリを作成できます。キャッシュキーエントリの忘却やコードベースの他の部分への意図しない変更といったグローバルな副作用を心配する必要はありません。
* **強力**: 静的に分析可能なコードだけでなく、より多くのものをキャッシュできます。例えば、ランタイム時に変更される可能性がある値でも、評価後の出力結果をキャッシュしたい場合があります。

`'use cache` は Next.js 内部ではまだ**実験的**です。テストする際の早期フィードバックをお待ちしています。

[ドキュメントで詳細を確認](/docs/app/api-reference/directives/use-cache)。
38 changes: 38 additions & 0 deletions apps/docs/content/ja/blog/create-next-app.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
source-updated-at: 2025-05-29T18:05:49.000Z
translation-updated-at: 2025-06-02T19:18:20.141Z
title: Create Next App の紹介
description: >-
本日、新しい Create Next App を紹介できることを嬉しく思います。Create Next App は、1つのコマンドで Next.js を利用したモダンな React アプリケーションをセットアップします。
author:
- name: Joe Haddad
image: /static/team/timer.jpg
- name: Tim Neutkens
image: /static/team/tim.jpg
date: 2019-10-09T15:02:30.543Z
image: >-
https://h8DxKfmAPhn8O0p3.public.blob.vercel-storage.com/static/blog/create-next-app/twitter-card.png
---

本日、新しい Create Next App を紹介できることを嬉しく思います。

Create Next App は、1つのコマンドで Next.js を利用したモダンな React アプリケーションをセットアップします。

開始するには、次のコマンドを実行するだけです:

```bash filename="Terminal"
npx create-next-app
```

Create Next App は、最高の開発者体験を提供するためにゼロから再構築されました:

* **インタラクティブな体験**: 引数なしで `npx create-next-app` を実行すると、プロジェクトセットアップをガイドするインタラクティブな体験が開始されます。
* **依存関係ゼロ**: プロジェクトの初期化はわずか**1秒**で可能です。Create Next App には依存関係がなく、**たったの 604 kB** でインストールされます。最適化前の以前のバージョンは **5.38 MB** でした。これは **4.7 MB 以上**の削減です!
* **オフラインサポート**: Create Next App は自動的にオフライン状態を検出し、ローカルのパッケージキャッシュを使用してプロジェクトをブートストラップします。
* **新しいデフォルトプロジェクトテンプレート**: Create Next App は、モダンな Next.js アプリケーション向けに設計された新しいプロジェクトテンプレートを使用します。Create Next App は Next.js 本体と共にメンテナンスされるため、このテンプレートは常に最新の Next.js バージョンに対応しています!
* **サンプルプロジェクトのサポート**: Create Next App は [Next.js サンプル集](https://github.com/vercel/next.js/tree/canary/examples) のサンプルを使用してアプリケーションをブートストラップできます(例: `npx create-next-app --example api-routes`)。
* **テスト済み**: このパッケージは Next.js モノレポの一部であり、Next.js 自体と同じ統合テストスイートを使用してテストされています。これにより、各リリースで期待通りに動作することが保証されます。

Create Next App は以前は [コミュニティでメンテナンス](https://open.segment.com/create-next-app/) されていましたが、Next.js の第一印象を管理することが重要だと感じました。特に [Next.js サンプル集](https://github.com/vercel/next.js/tree/canary/examples) で推奨しているためです。

[Segment](https://segment.com/) と協力してパッケージの所有権を移管し、特に [Fouad Matin](https://twitter.com/fouadmatin) 氏によるこれまでの管理に非常に感謝しています。
Loading