2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.jsの主要な技術、機能についてまとめ

Last updated at Posted at 2023-09-15

Next.jsの主要な技術、機能についてまとめ

目次

1. はじめに

Next.jsの勉強会に参加する機会があったので下調べ。
Next.jsはReact上で動作するフレームワークで、SSRやSSG、APIルーティングなどの多くの機能を備えています。本記事ではこれらの機能と、それを最大限に活用するための戦略について詳しく掘り下げていきます。

2. React: Next.jsの基盤

2.1. UIライブラリとしてのReact

Next.jsはReactの上に構築されており、Reactのコンポーネントベースの設計を利用してアプリケーションを構築します。

2.2. ReactとNext.jsの関係

Next.jsはReactの強力なUIライブラリの能力を拡張し、サーバーサイドレンダリングや静的サイト生成などの追加機能を提供します。

3. レンダリング技術と戦略

3.1. サーバーサイドレンダリング (SSR)

SSRはページロード時にサーバー上でページをレンダリングする技術です。具体的にはgetServerSidePropsを使用することで実現できます。

export async function getServerSideProps(context) {
  return {
    props: {} // ここにデータを渡す
  }
}

戦略:

SSRを使用することで、ユーザーに対してより迅速にページを表示できます。しかし、サーバーのリソースが必要になるため、トラフィックの多いサイトでは適切なスケーリング戦略が必要です。

3.2. 静的サイト生成 (SSG)

SSGはビルド時にページを静的に生成する技術です。getStaticPropsgetStaticPathsを使用して実現します。

export async function getStaticProps(context) {
  return {
    props: {}, // ここにデータを渡す
    revalidate: 10
  }
}

戦略:

SSGを使用することで、サーバーのリソースを節約し、高速なページロードを実現できます。変わらないコンテンツや頻繁に更新されないページに特に適しています。

3.3. ISR (Incremental Static Regeneration)

ISRは静的生成されたページを動的に再生成する技術です。revalidateオプションを使用して実現します。

export async function getStaticProps() {
  return {
    props: {},
    revalidate: 60 // 1分後に再生成
  };
}

3.4. 一般戦略

ISRは、SSGのメリットとリアルタイムのデータ更新のメリットを組み合わせたものです。一度静的に生成されたページは高速に提供され、revalidateの間隔でデータを更新することができます。

Next.js で頻繁にデータが変わるサイトを運営する際の一般的な戦略をコード付きで説明します。

  1. 静的ページの生成とISRの組み合わせ:

    一般的なブログのように、頻繁に新しい投稿が追加されるが、個々の投稿の内容はそんなに頻繁に変わらない場合、ISRを使用することができます。

// pages/posts/[id].js

function Post({ post }) {
  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

export async function getStaticPaths() {
  const posts = await fetchPosts();
  const paths = posts.map(post => ({ params: { id: post.id.toString() } }));

  return {
    paths,
    fallback: true  // 新しい投稿に対応
  };
}

export async function getStaticProps({ params }) {
  const post = await fetchPostById(params.id);

  return {
    props: { post },
    revalidate: 10
  };
}

export default Post;
  1. 新しいデータとのリアルタイムな対応:

    よりリアルタイム性を求める場面では、SWR やクライアントサイドのデータフェッチを使用するのが一般的です。

// pages/dashboard.js

import useSWR from 'swr';

function Dashboard() {
  const { data, error } = useSWR('/api/live-data', fetcher);

  if (error) return <div>Error loading data</div>;
  if (!data) return <div>Loading...</div>;

  return (
    <div>
      <h1>Dashboard</h1>
      <p>Live Data: {data.value}</p>
    </div>
  );
}

export default Dashboard;
  1. 完全なSSGと再ビルド:

    サイトの内容があまり頻繁に変わらない場合や、高いパフォーマンスを求める場合、完全なSSGと周期的な再ビルドを選択することができます。

// pages/about.js

function About({ data }) {
  return (
    <div>
      <h1>About Us</h1>
      <p>{data.description}</p>
    </div>
  );
}

export async function getStaticProps() {
  const data = await fetchData();

  return {
    props: { data }
  };
}

export default About;

そして、変更があった場合、Webhook や CI/CD ツールを使用してサイトを自動的に再ビルドします。

最後に、どの戦略を選択するかは、アプリケーションの要件、利用者の期待、そして開発・運営の複雑さによって異なります。これらのアプローチは相互に排他的ではなく、一つのアプリケーション内で複数のアプローチを組み合わせることができます。

4. ルーティングとAPI

4.1. API Routes

API Routesは、pages/api/ディレクトリ内に配置することで簡単にAPIエンドポイントを作成できる機能です。これらはローカル環境ではNode.jsサーバー上で動作し、デプロイ時にはVercel上でサーバーレス関数として変換されます。

// pages/api/hello.js
export default (req, res) => {
  res.status(200).json({ text: 'Hello' })
}

戦略とメリット:

サーバーレス関数はリクエストに応じてスケールするため、リソースを節約しながらも高いパフォーマンスを維持することができます。サーバーレスは、維持費が低く、スケーラビリティが高いというメリットがあります。

4.2. Dynamic Routes

Next.jsは、ファイル名やディレクトリ名に[]を使用することで動的なルーティングをサポートします。

// pages/posts/[id].js
import { useRouter } from 'next/router'

function Post() {
  const router = useRouter()
  const { id } = router.query

  return <h1>Post: {id}</h1>
}

戦略:

動的ルーティングは、大量のページを持つサイトやアプリケーションでのルーティングを簡素化するために使用されます。例えば、ブログの各投稿や商品の詳細ページなど、パターンは同じでもコンテンツが異なるページに理想的です。

5. パフォーマンスと最適化

5.1. Fast Refresh

Fast Refreshは、開発中の即時フィードバックを可能にするNext.jsの機能です。コンポーネントの状態を維持したまま、変更を即座に反映させることができます。

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

上記のようなカウンターコンポーネントを考えた場合、Fast Refreshによりカウントの状態は維持されたまま、他の部分のコードを変更・保存しても更新が即座に画面に反映されます。

5.2. Web Vitals

Web Vitalsは、ページのユーザーエクスペリエンスを測定するための主要な指標を提供します。Next.jsはこれらの指標を簡単に取得・表示するツールを組み込んでいます。

import { useWebVitals } from 'next/app'

function MyApp({ Component, pageProps }) {
  useWebVitals(console.log)

  return <Component {...pageProps} />
}

上記のコードは、Web Vitalsのデータをコンソールにログとして出力します。

5.3. Image Component & Image Optimization

Next.jsのImageコンポーネントは、自動的な画像最適化をサポートしています。

import Image from 'next/image'

function MyComponent() {
  return <Image src="/path/to/image.jpg" alt="Description" width={500} height={500} layout="responsive" />
}

layout属性をresponsiveに設定することで、画像は親要素のサイズに応じて自動的にサイズ変更されます。

6. スタイリング

6.1. Styled JSX

Styled JSXは、コンポーネントレベルのスコープ付きCSSを実現します。

function MyComponent() {
  return (
    <div>
      <p className="description">Styled with JSX</p>
      <style jsx>{`
        .description {
          color: blue;
        }
      `}</style>
    </div>
  );
}

この方法で、.descriptionクラスはMyComponent内でのみ有効となります。

6.2. CSS Modules

CSS Modulesは、スタイルのクラス名が一意になるように変換することで、スタイルの競合を回避します。

styles.module.css:

.container {
  padding: 20px;
  background-color: #f9f9f9;
}

MyComponent.js:

import styles from './styles.module.css'

function MyComponent() {
  return <div className={styles.container}>Hello, Next.js!</div>
}

CSSモジュールは、スタイルが他のコンポーネントと干渉しないようにするための効果的な方法です。

7. 拡張性とカスタマイズ

7.1. Plugins and Integrations

Next.jsは多くのプラグインや統合をサポートしており、さまざまなツールやサービスと簡単に連携することができます。

7.2. Custom Configuration

next.config.jsファイルを使用すると、Next.jsのデフォルトの設定をカスタマイズすることができます。

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?