Next.js 12 発表内容 まとめ

投稿: 2021年10月27日
タグ: 
  Web  Developer(Java等)  ニュースネタ

昨夜オンライン(Youtube) で Next.js CONF が開催され、Next.js 12 が発表されました。 発表内容を見ていきたいと思います。
Next.js CONF の発表では、Next.js 12 の話と Vercel のサービス(Checks や Edge 等) の話が混ぜこまれて話されていたのですが、 ここでは以下ページに書かれた Next.js 12 の機能のみ見ていきます。

Next.js 12
https://nextjs.org/blog/next-12open_in_new

Next.js CONF の動画は  ここopen_in_new で見れます。キーノートは Rustコンパイラと Middleware(というか Vercel Edge) の説明に多くの時間が割かれていたので、 これらが Next.js 12 の一押しなのかな、と思います。

  • Rust コンパイラ
  • コード縮小化/圧縮も Rustコンパイラに
  • ES modules(モジュール) の既定化と URLインポート
  • Middleware によるエッジ応答
  • AVIF 画像フォーマットのサポート
  • React 18 対応
  • その他
  • Rust コンパイラ

    より高速にビルドを行うために、JavaScript/TypeScript の変換を Bebel から Rustコンパイラに移植したとのことです。

    Next.js CONF の中では Next.js 10.2 との比較がデモされていました。
    Next.js 10.2 のビルドは 3分41秒かかったけど(以下画像左)、Next.js 12 の Rustコンパイラを使った場合は 1分58秒で終わったよ(以下画像右) というデモになっていました。

    画像_next_conf_1.jpg

    ただ、数千のページ/コンポーネントを含む環境でのデモ、とのことなので、結構な大規模環境が前提になっています。

    開発元の Vercel によると Rustによるコンパイルは「Babel より 17倍速い」とのことです。
    Rustコンパイラは Next.js 12 にアップデートした時点で既定で有効になりますが、 Babel でカスタム設定(babel.config.js) されている場合は、 Rustコンパイラは使用されず Babel を引き続き使用するようになっているようです。

    対応を計画するので、Babel 設定してるユーザーは GitHub の以下スレッドで共有してね、とのことです。既に結構フィードバックが来てます。

    Opted out of SWC feedback #30174
    https://github.com/vercel/next.js/discussions/30174open_in_new

    コード縮小化/圧縮も Rustコンパイラに

    こちらはまだプレビュー的な扱いですが、Minification (日本語だとコード縮小、コード圧縮?) でも Rustコンパイラを利用できるようになったとのことです。 既定では無効になっており、next.config.js の module.exports に以下設定することで有効にできました。

    JavaScript
    swcMinify: true

    こちらも Vercel によると「Terser よりも 7倍速い」とのことです。 ただ、まだ評価しており、今後長期間かけて検証していく間は既定にはならない、とのことです。 尚、実際有効にしてみるとビルドの際に以下 Warning が出力されるようになりました。

    warn  - SWC minify beta enabled. https://nextjs.org/docs/messages/swc-minify-enabled

    ES modules(モジュール) の既定化と URLインポート

    Next.js 11.1 の実験的機能として ESモジュールを使った npmパッケージをインポートできるようになっていましたが、 Next.js 12 では ESモジュールが既定になったとのことです。 引き続き、CommonJS でしか実装されていない npm モジュールのインポートもサポートされるとのことですが、ESモジュールが優先されるとのことです。

    加えて、Next.js 12 で追加された実験的な機能として、パッケージ等の URL指定でのインポート機能が紹介されていました。

    JavaScript
    import confetti from 'https://cdn.skypack.dev/canvas-confetti'

    npm パッケージ以外も import できるようになってます。(あまり使いどころはない気もしますが)
    試しにやってみると、以下のようなコードで画像を表示できました。

    TypeScript
    import Image from "next/image"; import webImg from "https://let-value.com/images/tn/web.jpg"; - 省略 - <Image src={webImg} />

    尚、URLインポートは実験的な機能のため、next.config.js に以下のようにインポート元URLプレフィックスと共に設定が必要です。

    JavaScript
    experimental: { urlImports: ['https://let-value.com/'], },

    Middleware によるエッジ応答

    Middleware という機能が発表されました。『(クライアント側での) リクエストが完了する前に指定したコードを実行できる』機能です。 何のための機能なのかは Next.js CONF のセッションの中で出てきた以下が分かりやすかったです。

    画像_next_conf_2.jpg
    *Next.js CONF 2021 Stage S セッションより

  • パーソナライズ表示しようとするとサーバーとのラウンドトリップが必要になる
  • その結果、1-2秒 ロード時間が長くなる
  • SSG は速いがパーソナラズしたコンテンツを表示しようとすると遅延読み込みが必要になる
  • 『パーソナライズするにはユーザーに応じたデータ取得が必要だけど、サーバーとのやりとりは時間がかかる、 そうなりゃエッジで応答できるようにしよう』 というのは既にある話ですが、 それをフロントエンドで実装できる機能として組み込んでいるのが特徴的で新しいように思います。

    エッジで返すだけなら、AWS の Lambda@Edge や CloudFront Function でも(簡単なものなら) 実装できますが、 Middleware (_middleware.ts) を追加することで個別のページのリクエスト前に Middleware のコードが実行されるようです。 まだ細かく見れていませんが、ドキュメントには『Middleware は `redirects` と `headers` の直後に実行される』と記載されています。

    Next.js CONF の中では、Middleware と連携するエッジ環境として Vercel Edge の紹介+デモもされていましたので、 Youtube 動画も参照すると良さそうです。

    クライアント側のリクエストライフサイクルの途中で動的に処理できるのは良いな、と思いつつもエッジと密になるので テストとかで検討すべきことが出てきそうではあります。

    AVIF 画像フォーマットのサポート

    ImageOptimization API が扱える画像フォーマットとして AVIF がサポートされたそうです。 Next.js 12 の時点では既定では有効になっておらず、next.config.js の module.exports に以下設定を追加することで有効になるようです。

    JavaScript
    module.exports = { images: { formats: ['image/avif', 'image/webp'] } }

    AVIF がサポートされるブラウザも増えてきて(Safari とかは対応してないですが)、 Next.js 以外でも AVIF 対応を打ち出しているライブラリとか増えてきたので、そろそろ AVIF 対応する時期が来たのかもしれません。

    React 18 対応

    まだ Alpha版という状況ですが、React 18 が利用できる状態のようです。 Next.js のページでは「サーバーサイドストリーミング」と「サーバーコンポーネント」が紹介されていますが、 どちらも React 18 自体の機能のため、ここでは割愛します。

    The Plan for React 18
    https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.htmlopen_in_new

    その他

    その他にも幾つかアップデートが Webページで紹介されていました。

  • webpack 4 の削除
  • next/image で出力する画像のタグを<div>から<span>に変更
  • クローラー(やボット) を想定した ISR フォールバック
  • 各ページや API で必要な依存関係ファイルをビルド時のトレース出力に追加
  • サーバーサイドメインのソフトウェアエンジニアから見ると、ほんとにフロントエンドは移り変わりが激しくて大変そうです。
    いろいろ変わるけど課題が解決されないソフトウェアも多い中 Next.js は比較的 課題が解決されるような内容に向かっているように見えるので 引き続き追っていければと思っています。