LoginSignup
10
6

More than 1 year has passed since last update.

Next.jsでは、アセット類を最適化できるコンポーネントやロジックが提供されており、パフォーマンスの良さに定評があります。

画像の最適化

Imageコンポーネントを用いることで、下記のような最適化を行ってくれます。

  • 最適な拡張子の画像が生成によるパフォーマンス向上
  • レイアウトシフトの防止
  • 遅延読み込みによる、ページの読み込み速度の最適化

使い方

next/imageからimportして使います。

import Image from 'next/image'

export const ImageContainer = () => (
  <Image 
    // props
  />
)

Imageコンポーネントで使えるpropsの型は、ImagePropsでexportされております。

export declare type ImageProps = Omit<JSX.IntrinsicElements['img'], 'src' | 'srcSet' | 'ref' | 'width' | 'height' | 'loading' | 'style'> & {
    src: string | StaticImport;                         // 画像のソース(ex: /images/test.png)
    width?: number | string;                            // 画像の横幅(layout='fill'以外は必須)
    height?: number | string;                           // 画像の高さ(layout='fill'以外は必須)
    layout?: LayoutValue;                               // viewport を変更した時のレイアウト
    loader?: ImageLoader;                               // 画像のURLを生成する関数
    quality?: number | string;                          // 画質(0〜100, デフォ75)
    priority?: boolean;                                 // preloadするか (trueでページ遷移時にpreload)
    loading?: LoadingValue;                             // 遅延ロードする ("lazy" | "eager")
    lazyBoundary?: string;                              // 遅延読み込みをトリガーする閾値の設定(デフォ 200px)
    placeholder?: PlaceholderValue;                     // プレースホルダーの形式("blur" | "empty", デフォ empty)
    blurDataURL?: string;                               // placeholder="blur"の時のブラーする画像のURL
    unoptimized?: boolean;                              // 最適化しないか (デフォ false - 最適化される)
    objectFit?: ImgElementStyle['objectFit'];           // layout='fill'の時のobject-fit
    objectPosition?: ImgElementStyle['objectPosition']; // layout='fill'の時のobject-position
    onLoadingComplete?: OnLoadingComplete;              // 画像を完全ロード直後に実行されるコールバック関数
}; 

ものすごくオプションがたくさんありますが、基本的にはsrc layout width height を使います。

layoutモードに関して

layoutには、fill fixed intrinsic responsive の四種類あります。

fill

親の要素のwidth / heightに合わせて画像の幅と高さが設定される。

fixed

指定したwidth / height に常に固定される。

responsive

指定したwidth / heightの比率は保ちながら、ビューポートに合わせてサイズが変わる。

intrinsic

responsiveと同じく、指定したwidth / heightの比率は保ちながら、ビューポートに合わせてサイズが変わるが、指定したwidthは超えられない。

参考.gif

(筆者本人が神戸でとった写真だよ!天気が悪かったなぁ :umbrella: )

フォントの最適化

Next.js v10.2 以降から、webフォントが最適化されるようになりました。

最適化される内容としては、下記になります。

  • フォントCSSを自動的にインライン化
  • 表示の高速化

下記記事をみていただくとわかる通り、はんっぱなくLCPが改善されます。
すごい。

使い方

1. next/headを使う

Headコンポーネント内でwebフォントを読み込むと最適化されます。

import Head from 'next/head'

export default page = () => {
  return (
    <div>
      <Head>
        <link
          href="https://fonts.googleapis.com/css2?family=Inter&display=optional"
          rel="stylesheet"
        />
      </Head>
    </div>
  )
}

2. next/documentを使う

next/documentのHeadコンポーネントでwebフォントを読み込むと最適化されます。

import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <link
            href="https://fonts.googleapis.com/css2?family=Inter&display=optional"
            rel="stylesheet"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

スクリプトの最適化

Scriptコンポーネントを使うことで、スクリプトの読み込みを最適化することができます。
主に、計測・分析タグなどのサードパーティスクリプトの読み込みを最適化するために使います。

使い方

next/scriptからimportして使います。

import Script from 'next/script'

export const ImageContainer = () => (
  <Script src="https://www.google-analytics.com/analytics.js" />
)

Scriptコンポーネントで使えるpropsの型は、ScriptPropsでexportされております。

export interface ScriptProps extends ScriptHTMLAttributes<HTMLScriptElement> {
  strategy?: 'afterInteractive' | 'lazyOnload' | 'beforeInteractive'; // 読み込みタイミング (デフォはafterInteractive)
  id?: string;                                                        // 読み込みを順を最適するための追跡id
  onLoad?: (e: any) => void;                                          // ロード後に実行する関数
  onError?: (e: any) => void;                                         // エラー時に実行する関数
  children?: React.ReactNode;
}

strategyに関して

strategyには、afterInteractive lazyOnload beforeInteractive の3種類あります。
順序は、beforeInteractiveafterInteractivelazyOnload です。
詳しいタイミングを説明します。

beforeInteractive

ページがインタラクティブになる前に実行されます。
(つまり、自分の書いたjavascriptよりも先に実行されることになります。)

下記のような重要なスクリプトに使われます。

  • ボット検出
  • cookieなどの同意管理

afterInteractive (デフォ値)

ページがインタラクティブになった後に実行されます。

下記のような重要なスクリプトに使われます。

  • タグマネージャー
  • 分析系のタグ

lazyOnload

すべてのリソースがフェッチされた後、アイドル時間中にロードされます。

このコードを本気で読解した記事を発見し、とても興味津々に読んでいたのですが、
よくみたら自分が大尊敬している会社の先輩の記事でした:innocent:

10
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
10
6