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

2019年4月16日(火)

Next.js 8.1

投稿者

本日、AMPページ作成エクスペリエンスをNext.jsに拡張したことを発表できることを嬉しく思います。

AMPとは?

AMPは、レンダリングオーバーヘッドを最小限に抑え、拡張された動作で有名な検索エンジンにインデックスされる高性能ウェブサイトを構築するための標準です。たとえば、AMPページはGoogleのモバイル検索結果に直接読み込まれ、稲妻アイコンでマークされます。

Next.js Google search result
Next.js Google検索結果

AMP HTMLはHTMLのより厳密なバージョンであり、より信頼性の高いパフォーマンスとスケーラビリティを実現するためにいくつかの制限を課しています。一部のHTMLタグは、対応するHTMLタグよりも優れたエクスペリエンスを提供するために、AMP固有のHTMLタグに置き換えられています。たとえば、amp-imgタグは、まだサポートしていないブラウザでも完全なsrcsetサポートを提供します。

AMPページは、それをサポートする検索エンジンによって自動的に検出されます。これらの検索エンジンは通常、AMPキャッシュ(例:GoogleおよびBing)を実装しています。AMPキャッシュは、検索結果からページをより高速にレンダリングするのに役立ちます。

Next.jsにおけるAMP

本日、AMPページ作成エクスペリエンスをNext.jsに拡張したことを発表できることを嬉しく思います。これにより、Reactコンポーネントのパワーを活用してAMPページを作成できるようになります。AMPサポートはページごとに定義されており、AMPの段階的な導入が可能です。Next.jsでAMPを有効にするには、ハイブリッドAMPページまたはAMPファーストページの2つの方法があります。

ハイブリッドAMPページ

ハイブリッドAMPページでは、従来のページのAMPバージョンを用意できるため、検索エンジンはモバイル検索結果でAMPバージョンを表示し、既存のページバージョンを維持できます。これにより、AMPをアプリケーションに組み込みながら、クライアントサイドルーティングなどのNext.js機能をメインのユーザーエクスペリエンスに活用できます。

ハイブリッドAMPページをオプトインするには、hybrid: trueオプションを提供しながらwithAmp関数を使用します。

pages/index.js
function HomePage() {
  return <p>Welcome to AMP + Next.js.</p>;
}
 
export default withAmp(HomePage, { hybrid: true });

本番環境でハイブリッドAMPパターンが使用されている例として、Redditがあります。各スレッドは、GoogleのAMPキャッシュに保存されており、モバイルウェブ全体で高速なユーザーエクスペリエンスを提供しながら、デスクトップおよびその後のナビゲーションのためにRedditのフルバージョンを提供しています。

Image of Reddit using AMP to better SEO
SEO向上のためにAMPを使用するRedditの画像
Image of Reddit in AMP viewer
AMPビューアーのRedditの画像

AMPファーストページ

AMPファーストページは、ウェブサイトの主要なトラフィックおよび検索エンジンからのトラフィックに配信されます。AMPファーストページを使用することで、デスクトップを含むメインのウェブサイトにAMPの高速エクスペリエンスをもたらします。

AMPファーストページを実装するには、withAmp関数でページをラップします。

pages/index.js
import { withAmp } from 'next/amp';
function HomePage() {
  return <p>Welcome to AMP + Next.js.</p>;
}
 
export default withAmp(HomePage);

Next.jsランタイムの必要がない場合は、AMPファーストページを使用することで開発をスピードアップできます。AMPファーストでは、ページを構築するためにAMP互換コンポーネントのみを使用する必要があります。AMPファーストページは、現在nextjs.org/docsおよびnextjs.org/blogで本番稼働しています。

コンポーネントでのAMPレンダリングの区別

プロジェクト内の任意のReactコンポーネントはuseAmpを活用して、AMPおよび非AMPレンダリングモードを区別できます。これにより、<img><amp-img>の間でロジックを共有する<Image>コンポーネントを実装できます。

components/image.js
import { useAmp } from 'next/amp';
 
export function Image({ src, width, height }) {
  const isAmp = useAmp();
  return isAmp ? (
    <amp-img src={src} width={width} height={height} />
  ) : (
    <img src={src} width={width} height={height} />
  );
}
pages/index.js
import { withAmp } from 'next/amp';
import { Image } from '../components/image';
 
function HomePage() {
  return (
    <>
      <p>Hello! Welcome to AMP + Next.js.</p>
      <Image src="https://placehold.it/120" width="120" height="120" />
    </>
  );
}
 
export default withAmp(HomePage, { hybrid: true });

AMP開発の自動リロード

開発中は、ホットモジュールリプレイスメントを使用する代わりに、現在表示しているページへの変更を追跡し、ページが変更された場合にのみページをリロードします。ホットモジュールリプレイスメントではなくフルリロードを使用する理由は、常にAMPページの最新のサーバーサイドレンダリングを確認できるようにするためです。

AMPバリデーション

有効なAMPページのみが生成されるようにするために、開発中にamphtml-validatorで自動的に検証します。エラーや警告は、Next.jsを起動したターミナルに表示されます。

next export中もページは検証され、問題があればターミナルに出力されます。AMPエラーが発生すると、エクスポートが無効なAMPとなるため、next exportは失敗します。

Next.jsでのAMPの使用方法を学ぶ

Next.jsの使用方法を学ぶことに加えて、Next.jsでAMPを使用する方法を学ぶための新しいセクションを追加しました。

または、AMPサンプルを使用して開始してください。

npx create-next-app --example amp amp-app