コンテンツへスキップ
ブログに戻る

2022年2月17日(木)

Next.js 12.1

投稿者

Next.js 12.1で、最も要望の多かった機能の1つをリリースできることを嬉しく思います。

今すぐnpm i next@latestを実行して更新してください。

オンデマンド増分静的再生成(ベータ版)

Next.jsでは、getStaticPropsを使用する個々のページを再検証できるunstable_revalidate()関数が公開されました。これは、Next.js 9.5でインクリメンタル静的再生成(ISR)を導入して以来、最も要望の多かった機能の1つです。

ISRがリリースされて以来、TripadvisorParachute、HashiCorpなどの企業が、素晴らしいパフォーマンスを維持しながらビルド時間を大幅に改善しているのを見てきました。しかし、間隔ベースの再検証に関するフィードバックも聞いており、より柔軟な機能を提供できることを楽しみにしています。

現在、revalidate時間を60に設定すると、すべての訪問者は1分間、同じ生成されたバージョンのサイトを見ることになります。キャッシュを無効にする唯一の方法は、1分が経過した後に誰かがそのページにアクセスすることでした。これで、特定ページのNext.jsキャッシュをオンデマンドで手動でパージできるようになりました。

これにより、次のような場合にサイトの更新が容易になります。

  • ヘッドレスCMSのコンテンツが作成または更新された場合
  • Eコマースのメタデータ(価格、説明、カテゴリ、レビューなど)が変更された場合
pages/api/revalidate.js
export default async function handler(req, res) {
  // Check for secret to confirm this is a valid request
  if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
    return res.status(401).json({ message: 'Invalid token' });
  }
 
  try {
    await res.unstable_revalidate('/path-to-revalidate');
    return res.json({ revalidated: true });
  } catch (err) {
    // If there was an error, Next.js will continue
    // to show the last successfully generated page
    return res.status(500).send('Error revalidating');
  }
}

getStaticProps内では、オンデマンド再検証を使用するためにrevalidateを指定する必要はありません。revalidateを省略すると、Next.jsはデフォルト値のfalse(再検証なし)を使用し、unstable_revalidate()が呼び出されたときにのみページをオンデマンドで再検証します。

Incremental Static Regenerationは、Next.js Build APInext build)をサポートするすべてのプロバイダーで動作します。本日より、Vercelにデプロイすると、オンデマンド再検証はページをエッジにプッシュする際に約300msでグローバルに伝播します。

デモを見るでオンデマンド再検証の動作を確認し、フィードバックをお寄せください。Svix(エンタープライズ対応のWebhooks)とClerk(認証)も、オンデマンドISRのデモを作成しました

SWCのサポート改善

すべてのNext.jsアプリケーションが本番環境でより速くビルドされ、ローカル開発で即座にフィードバックが得られるようにしたいと考えています。Next.js 12では、ネイティブコンパイルを活用する新しいRustベースのコンパイラが導入されました。

12.1では、Next.jsコンパイラに以下のサポートが追加されました。

上記の6つのトランスフォームが追加され、最も一般的なBabelプラグインを新しいコンパイラを使用してRustに移植しました。他に希望するプラグインがあれば、ディスカッションでお知らせください。さらに、SWCを通じて有効になる高性能WebAssemblyプラグインのシステムにも取り組んでいます。

ゼロ設定のJestプラグイン

Next.jsは、RustベースのNext.jsコンパイラを使用してファイルを変換するようにJestを自動的に設定するようになりました(next/jest)。これには以下のものが含まれます。

  • スタイルシート(.css.module.css、およびその.scssバリアント)と画像インポートの自動モック
  • .env(およびすべてのバリアント)をprocess.envに読み込む
  • テスト解決と変換からnode_modulesを無視する
  • テスト解決から.nextを無視する
  • Next.jsコンパイラの変換を有効にするフラグのためにnext.config.jsを読み込む

詳細についてはドキュメントを確認するか、Jestの例から始めましょう

SWCによる高速な最小化

Next.js 12で、Next.jsコンパイラの一部としてSWCを使用した最小化を導入しました。初期の結果では、Terserよりも7倍高速であることが示されています。SWCによる最小化は12.1でリリース候補(RC)となり、12.2でデフォルトになります。

next.config.jsでSWCによる最小化を有効にできます

next.config.js
module.exports = {
  swcMinify: true,
};

ディスカッションでフィードバックをお寄せください。

より高速な画像最適化

組み込みの画像最適化APIが更新され、画像が古い状態で提供され、バックグラウンドで再検証される(stale-while-revalidateとしても知られています)ISRページと同じパターンをサポートするようになりました。

これは、画像の最適化において重要なパフォーマンス改善です。詳細については、画像キャッシュ動作を参照してください。

自己ホスト型Next.jsの改善

Next.jsは、本番環境へのデプロイに必要なファイルのみをコピーするstandaloneフォルダを自動的に作成できるようになりました。これにより、自己ホスト型Next.jsアプリケーションのDockerイメージが約80%小さくなりました

この自動コピーを活用するには、next.config.jsで有効にすることができます。

next.config.js
module.exports = {
  experimental: {
    outputStandalone: true,
  },
};

これにより、.next/standaloneにフォルダが作成され、node_modulesをインストールすることなく単独でデプロイできます。

ドキュメントを確認するか、Dockerの例から始めましょう。また、環境に基づいて異なる.envファイルを読み込むことをサポートするマルチ環境Dockerの例も用意されています。

React 18、サーバーコンポーネント、SSRストリーミング(アルファ版)

Next.js Confで示されたように、私たちはReact 18、サーバーサイドサスペンス、ストリーミングSSR、そして最終的にはサーバーコンポーネントをNext.jsにもたらすために取り組んできました。

サーバーコンポーネントは、Reactの新しい機能で、サーバーとクライアントサイドのコードを分離することで、JavaScriptバンドルサイズを削減できます。サーバーコンポーネントを使用すると、開発者はサーバーとクライアントにまたがるアプリを構築でき、クライアントサイドアプリの豊富なインタラクティビティと、従来のサーバーレンダリングの改善されたパフォーマンスを組み合わせることができます。

Next.jsのサーバーコンポーネントのアルファ版からベータ版への進捗を追っている開発者向けに、最近の更新をいくつかご紹介します。

私たちは、Next.jsアプリケーション全体をEdgeでサーバーレンダリングできるように取り組んでいます。準備ができたらNode.jsからページを段階的に移行できるよう、どのページをEdge Runtimeにオプトインさせるかを選択できます。

Edge Runtimeについては、近日中にさらに詳細な記事を公開する予定です。両方のデモ(next-server-componentsnext-rsc-demo)は、最新の変更で更新されています。

その他のバグ修正と改善点

  • ESLintで<a>target="blank"を使用しても、next/linkを使用するように警告されなくなりました。
  • .d.tsファイルはページと見なされなくなりました。
  • スクリーンリーダーにページ変更を通知する際、document.titleh1よりも優先されるようになりました。
  • indexが予約語であったため以前は不可能だったpages/index/[...dynamic].jsの作成が可能になりました。
  • dynamic(() => import('./some-component'), { ssr: false })を使用すると、インポートはサーバーコードから自動的にツリーシェイクされます。
  • インストールサイズを小さくし、セキュリティを向上させるため、より多くの依存関係を事前コンパイルする作業を進めています。最新の追加はnode-fetchでした。
  • ミドルウェア使用時のFast Refreshの改善。
  • 組み込みのESLint統合によりESLint 8をサポート。
  • styled-jsxが5.0にアップグレードされ、すべてのstyled-jsxコンパイルエラーに対して新しい便利なエラーリンクが含まれるようになりました。
  • Edge Runtime: AbortControllerAbortSignalのサポート
  • Edge Runtime: CryptoKeyglobalThis.CryptoKeyが追加されました。
  • 大規模なNext.jsアプリケーションでは、最近の改善によりFast Refresh時間が約60%改善されています(1,000以上のモジュールがリロードされる場合)。
  • Fast Refreshが失敗し、完全なページリロードが発生した場合に通知が表示されるようになりました。
  • React 18のstrict modeを使用している場合、初回ページ読み込みの通知が正しくスキップされるようになりました。
  • Next.jsリポジトリのオープンなIssueの数を、2021年12月と比較して約300削減しました(約1000件のIssueを解決しました)。

Next.js開発者アンケート

最初の開発者アンケートでフィードバックを共有し、Next.jsの改善にご協力ください。

このアンケートは2部構成です。8つの質問からなる短いアンケートと、個々の機能に関するフィードバックを深く掘り下げる詳細なアンケートです。お時間があれば両方のセクションにご記入いただけると幸いですが、そうでない場合は最初のセクションの後で回答を送信していただいても構いません。

回答は完全に匿名ですが、必要であればアプリのURLを共有することもできます。

Next.jsの改善にご協力いただきありがとうございます!

貢献者の皆様、ありがとうございました

Next.jsは、2,000人以上の個人開発者、GoogleやFacebookなどの業界パートナー、そして私たちのコアチームの共同作業の成果です。

貢献を容易にするため、Next.jsリポジトリをTurborepoに移行し、ビルドパフォーマンスを向上させました。また、テストの作成を容易にするために、テスト用のスキャフォールディングとエラーリンクも追加しました。最後に、Next.jsへの貢献方法を示す40分間のウォークスルービデオを録画しました。

このリリースは、以下の皆様の貢献によって実現しました: @MaedahBatool, @mutebg, @sokra, @huozhi, @hanford, @shuding, @sean6bucks, @jameshfisher, @devknoll, @yuta-ike, @zh-lx, @amandeepmittal, @alunyov, @stefanprobst, @leerob, @balazsorban44, @kdy1, @brittanyrw, @jord1e, @kara, @vvo, @ismaelrumzan, @dlindenkreuz, @MohammadxAli, @nguyenyou, @thibautsabot, @hanneslund, @vertti, @KateKate, @stefee, @mikinovation, @Leticijak, @mohsen1, @ncphillips, @ehowey, @lancechentw, @krychaxp, @fmacherey, @pklawansky, @RyanClementsHax, @lakbychance, @sannajammeh, @oliviertassinari, @alexander-akait, @u-yas, @Cheprer, @msp5382, @chrispat, @getspooky, @Ryz0nd, @klaasman, @midgleyc, @kumard3, @jesstelford, @neeraj3029, @glenngijsberts, @pie6k, @wouterraateland, @timneutkens, @11koukou, @thesyedbasim, @aeneasr, @ijjk, @lfades, @JuniorTour, @xavhan, @mattyocode, @padmaia, @Skn0tt, @gwer, @Nutlope, @styfle, @stipsan, @xhoantran, @eolme, @sespinosa, @zenorocha, @hjaber, @benmvp, @T-O-R-U-S, @dburrows, @atcastle, @kiriny, @molebox, @Vienio99, @kyliau, @PepijnSenders, @krystofex, @PizzaPete, @souljuse, @Schniz, @Nelsonfrank, @Mhmdrza, @hideokamoto-stripe, @Emrin, @gr-qft, @delbaoliveira, @redbar0n, @lxy-yz, @Divlo, @kachkaev, @teleaziz, @OgbeniHMMD, @goncy, @bennettdams, @hsynlms, @callumgare, @jonrosner, @karaggeorge, @rpie3, @MartijnHols, @bashunaimiroy, @NOCELL, @rishabhpoddar, @omariosouto, @theMosaad, @javivelasco, @pierrenel, @lobsterkatie, @tharakabimal, @saevarb, @nbouvrette, @paulnbrd, @ecklf, @renbaoshuo, @chozzz, @tbezman, @karlhorky, @j-mendez, @ffan0811, @arthurfiorette, @chimit, @joperron, @moh12594, @rasmusjp, @bryanrsmith, @TrySound, @josharsh, @thecrypticace, @arturparkhisenko, @segheysens, @thevinter, @AryanBeezadhur, @xiaohp, @tknickman, @oriolcp, @smakosh, @jorrit, @mix3d, @Clecio013, @michielvangendt, @intergalacticspacehighway, @jbraithwaite, @marcelocarmona, @benmerckx, @haykerman, @steven-tey, @jaredpalmer, @pi-guy-in-the-sky, @JuanM04, @apollisa, @D-Pagey, @Kikobeats, @ramosbugs, @dan-weaver, @chris-stytch, @MikevPeeren, @janpio, @emw3, @nubpro, @cmdcolin, @joostdecock, @sgallese, @housseindjirdeh, @minervabot, @cjboco, @Ryuurock, @dm430, @mkarkachov, @nvh95, @gfortaine, @zifeo, @vicente-s, @Rohithgilla12, @brookton, @skirsten, @davidfateh, @DavidBabel, @mannybecerra, @pveyes, @kaykdm, @xhiroga, @mzaien, @losfair, @ykzts, @knezevicdev, @yang-feng-yfeng, @xuchaobei, @elkevinwolf, @fabienheureux, @nilskaspersson, @Andarist, @mathcrln, @dferber90, @FranciscoMoretti, @benschwarz, @wendellhu95, @gazdagergo, @imabp, @ljosberinn, @samuliasmala, @ka2jun8, @monsonjeremy, @pqt, @leoortizz, @michel-kraemer, @ntkoopman, @iicdii, @chentsulin, @ericmatthys, @lennym, @balogunkeji, @wnr, @chemicalkosek, @KittyGiraudel, @OKinane, @KonstHardy, @BrandonRomano, @furcan, @dusanralic, @elliottsj, @hi-ogawa, @panva, @genetschneider, @thundermiracle, @stefano-rainieri, @ericbiewener, @vordgi, @stevejarvis, @ihmpavel, @matamatanot, @dyarfaradj, @iheyunfei, @ascorbic, @fytriht, @emzoumpo, @onurtemiz, @a-ursino, @mxschmitt, @bywo, @OArnarsson, @TurekBot, @gish, @vadymshymko, @kamsar, @skhaz, @Prashoon123, @IrisvanOllefen, @evan-bradley, @ntltd, @EzequielDM, @oBusk, @martpie, @BruceRodrigues, @luke-h1, @lucasvazq, @velocity23, @AkiraTsuboi, @mitheelgajare, @JamiesWhiteShirt, @leroydev, @JulienZD, @leotaku, @mattfwood, and @kripod.