詳細ガイド
ディレクティブ

NgOptimizedImage の使用開始

NgOptimizedImage ディレクティブは、画像の読み込みにおけるパフォーマンスのベストプラクティスを簡単に採用できるようにします。

このディレクティブは、Largest Contentful Paint (LCP) 画像の読み込みが以下の方法で優先されるようにします。

  • <img> タグに fetchpriority 属性を自動的に設定する
  • デフォルトで他の画像を遅延読み込みする
  • ドキュメントのヘッドにプリコネクトリンクタグを自動的に生成する
  • srcset 属性を自動的に生成する
  • アプリケーションがSSRを使用している場合、プリロードヒントを生成する

LCP画像の読み込みを最適化することに加えて、NgOptimizedImage は以下のようないくつかの画像のベストプラクティスを強制します。

CSSで背景画像を使用している場合は、こちらから開始してください

NOTE: NgOptimizedImage ディレクティブはAngularバージョン15で安定版機能となりましたが、バックポートされており、バージョン13.4.0および14.3.0でも安定版機能として利用可能です。

はじめに

  1. NgOptimizedImageディレクティブのインポート

    NgOptimizedImageディレクティブを@angular/commonからインポートします。

          
    import { NgOptimizedImage } from '@angular/common'

    そして、スタンドアロンコンポーネントまたはNgModuleのimports配列に含めます。

          
    imports: [  NgOptimizedImage,  // ...],
  2. (オプション)ローダーの設定

    NgOptimizedImageを使用するために画像ローダーは必須ではありませんが、画像CDNと組み合わせて使用すると、画像の自動srcsetを含む強力なパフォーマンス機能が有効になります。

    ローダーの設定に関する簡単なガイドは、このページの最後にある画像ローダーの設定セクションにあります。

  3. ディレクティブの有効化

    NgOptimizedImageディレクティブを有効にするには、画像のsrc属性をngSrcに置き換えます。

          
    <img ngSrc="cat.jpg">

    組み込みのサードパーティローダーを使用している場合は、srcからベースURLパスを省略してください。これはローダーによって自動的に前置されます。

  4. 画像をpriorityとしてマークする

    ページのLCP画像は、その読み込みを優先するために常にpriorityとしてマークしてください。

          
    <img ngSrc="cat.jpg" width="400" height="200" priority>

    画像をpriorityとしてマークすると、以下の最適化が適用されます。

    LCP要素がpriority属性を持たない画像である場合、Angularは開発中に警告を表示します。ページのLCP要素は、ユーザーの画面の寸法など、さまざまな要因に基づいて変化する可能性があるため、ページにはpriorityとしてマークすべき複数の画像が存在する場合があります。詳細については、CSS for Web Vitalsを参照してください。

  5. 幅と高さを含める

    画像関連のレイアウトシフトを防ぐため、NgOptimizedImageでは次のように画像の高さと幅を指定する必要があります。

          
    <img ngSrc="cat.jpg" width="400" height="200">

    レスポンシブ画像(ビューポートに対して拡大縮小するようにスタイル設定された画像)の場合、widthおよびheight属性は画像ファイルの固有のサイズである必要があります。レスポンシブ画像の場合、sizesの値を設定することも重要です。

    固定サイズ画像の場合、widthおよびheight属性は画像の目的のレンダリングサイズを反映する必要があります。これらの属性のアスペクト比は、常に画像の固有のアスペクト比と一致する必要があります。

    NOTE: 画像のサイズが不明な場合は、以下で説明するように、親コンテナのサイズを継承するために「フィルモード」の使用を検討してください。

fillモードの使用

画像をコンテナ要素にフィットさせたい場合、fill属性を使用できます。これは、「背景画像」のような動作を実現したい場合にしばしば役立ちます。また、画像の正確な幅と高さが不明な場合でも、既知のサイズを持つ親コンテナに画像をフィットさせたい場合に役立ちます(下記の「object-fit」を参照)。

画像にfill属性を追加する場合、以下の例のようにwidthheightを含める必要はなく、含めるべきではありません。

      
<img ngSrc="cat.jpg" fill>

object-fitCSSプロパティを使用して、画像がコンテナをどのように埋めるかを変更できます。画像をobject-fit: "contain"でスタイル設定すると、画像はアスペクト比を維持し、要素にフィットするように「レターボックス」されます。object-fit: "cover"を設定すると、要素はアスペクト比を維持し、要素を完全に埋めますが、一部のコンテンツは「切り取られる」場合があります。

上記の視覚的な例は、MDN object-fitドキュメントを参照してください。

object-positionプロパティを使用して画像をスタイル設定し、コンテナ要素内での位置を調整できます。

IMPORTANT:「fill」画像が適切にレンダリングされるには、その親要素はposition: "relative"position: "fixed"、またはposition: "absolute"でスタイル設定されている必要があります

背景画像の移行方法

background-imageからNgOptimizedImageへ移行するための簡単なステップバイステッププロセスです。これらのステップでは、画像背景を持つ要素を「コンテナ要素」と呼びます。

  1. コンテナ要素からbackground-imageスタイルを削除します。
  2. コンテナ要素がposition: "relative"position: "fixed"、またはposition: "absolute"を持つことを確認します。
  3. コンテナ要素の子として新しい画像要素を作成し、ngSrcを使用してNgOptimizedImageディレクティブを有効にします。
  4. その要素にfill属性を付与します。heightwidthを含めないでください。
  5. この画像がLCP要素である可能性があると考える場合は、画像要素にpriority属性を追加します。

背景画像がコンテナをどのように埋めるかは、フィルモードの使用セクションで説明されているように調整できます。

プレースホルダーの使用

自動プレースホルダー

NgOptimizedImageは、CDNまたは画像ホストが自動画像リサイズを提供している場合、画像の低解像度の自動プレースホルダーを表示できます。この機能を利用するには、画像にplaceholder属性を追加します。

      
<img ngSrc="cat.jpg" width="400" height="200" placeholder>

この属性を追加すると、指定された画像ローダーを使用して、画像の2番目の小さいバージョンが自動的にリクエストされます。この小さい画像は、画像が読み込まれる間、CSSのぼかしを伴うbackground-imageスタイルとして適用されます。画像ローダーが提供されていない場合、プレースホルダー画像は生成されず、エラーがスローされます。

生成されるプレースホルダーのデフォルトサイズは幅30pxです。このサイズは、以下に示すようにIMAGE_CONFIGプロバイダーでピクセル値を指定することで変更できます。

      
providers: [  {    provide: IMAGE_CONFIG,    useValue: {      placeholderResolution: 40    }  },],

ぼかされたプレースホルダーの周りにシャープなエッジが必要な場合は、画像をoverflow: hiddenスタイルを持つコンテナ<div>でラップできます。<div>が画像と同じサイズである限り(例えばwidth: fit-contentスタイルを使用するなど)、プレースホルダーの「ぼやけたエッジ」は非表示になります。

データURLプレースホルダー

画像ローダーなしで、base64 データURLを使用してプレースホルダーを指定できます。データURLの形式はdata:image/[imagetype];[data]で、[imagetype]pngのような画像形式、[data]は画像のbase64エンコーディングです。このエンコーディングはコマンドラインまたはJavaScriptで行うことができます。具体的なコマンドについては、MDNドキュメントを参照してください。データが切り詰められたデータURLプレースホルダーの例を以下に示します。

      
<img  ngSrc="cat.jpg"  width="400"  height="200"  placeholder="data:image/png;base64,iVBORw0K..."/>

しかし、大きなデータURLはAngularバンドルのサイズを増やし、ページロードを遅くします。画像ローダーを使用できない場合、Angularチームはbase64プレースホルダー画像を4KB未満に保ち、重要な画像にのみ使用することを推奨しています。プレースホルダーの寸法を小さくすることに加えて、画像形式や画像を保存する際に使用するパラメーターの変更も検討してください。非常に低い解像度では、これらのパラメーターがファイルサイズに大きな影響を与える可能性があります。

ぼかしなしプレースホルダー

デフォルトでは、NgOptimizedImageは画像プレースホルダーにCSSのぼかし効果を適用します。ぼかしなしでプレースホルダーをレンダリングするには、blurプロパティをfalseに設定したオブジェクトを含むplaceholderConfig引数を指定します。例:

      
<img  ngSrc="cat.jpg"  width="400"  height="200"  placeholder  [placeholderConfig]="{blur: false}"/>

画像のスタイル調整

画像のスタイル設定によっては、width属性とheight属性を追加すると画像の表示が異なる場合があります。NgOptimizedImageは、画像のスタイル設定によって画像が歪んだアスペクト比で表示される場合に警告します。

通常、画像のスタイルにheight: autoまたはwidth: autoを追加することでこれを修正できます。詳細については、<img>タグに関するweb.devの記事を参照してください。

画像のwidth属性とheight属性が、CSSで画像を希望どおりにサイズ調整するのを妨げている場合は、代わりにfillモードを使用し、画像の親要素をスタイル設定することを検討してください。

パフォーマンス機能

NgOptimizedImageには、アプリケーションの読み込みパフォーマンスを向上させるために設計された多くの機能が含まれています。これらの機能は本セクションで説明します。

リソースヒントの追加

画像オリジンに対するpreconnectリソースヒントは、LCP画像が可能な限り迅速に読み込まれることを保証します。

プリコネクトリンクは、ローダーへの引数として提供されたドメインに対して自動的に生成されます。画像オリジンを自動的に識別できない場合、またはLCP画像に対してプリコネクトリンクが検出されない場合、NgOptimizedImageは開発中に警告を表示します。その場合、index.htmlにリソースヒントを手動で追加する必要があります。ドキュメントの<head>内に、以下に示すようにrel="preconnect"を持つlinkタグを追加します。

      
<link rel="preconnect" href="https://my.cdn.origin" />

プリコネクト警告を無効にするには、PRECONNECT_CHECK_BLOCKLISTトークンをインジェクトします。

      
providers: [  {provide: PRECONNECT_CHECK_BLOCKLIST, useValue: 'https://your-domain.com'}],

自動プリコネクト生成に関する詳細情報はこちらを参照してください。

自動srcsetによる適切なサイズの画像リクエスト

srcset属性を定義することで、ブラウザがユーザーのビューポートに適切なサイズの画像をリクエストするようになります。これにより、大きすぎる画像をダウンロードする時間の無駄を省きます。NgOptimizedImageは、画像タグのsizes属性の有無と値に基づいて、画像に適切なsrcsetを生成します。

固定サイズの画像

画像がサイズ「固定」である(つまり、ピクセル密度を除いてデバイス間で同じサイズ)場合、sizes属性を設定する必要はありません。画像のwidth属性とheight属性から、追加の入力なしでsrcsetを自動的に生成できます。

生成されるsrcsetの例:

      
<img ... srcset="image-400w.jpg 1x, image-800w.jpg 2x">

レスポンシブ画像

画像がレスポンシブである(つまり、ビューポートサイズに応じて拡大縮小する)場合、srcsetを生成するためにsizes属性を定義する必要があります。

sizesを以前に使用したことがない場合、ビューポート幅に基づいて設定することから始めるのが良いでしょう。例えば、CSSによって画像がビューポート幅の100%を占める場合、sizes100vwに設定すると、ブラウザは(ピクセル密度を考慮した上で)ビューポート幅に最も近いsrcset内の画像を選択します。画像が画面の半分しか占めない可能性が高い場合(例: サイドバー内)、ブラウザがより小さな画像を選択するようにsizes50vwに設定します。以下同様です。

上記が目的の画像動作をカバーしない場合、高度なsizes値に関するドキュメントを参照してください。

NOTE: NgOptimizedImageは、提供されたsizes値の前に自動的に"auto"を付加します。これはsizes="auto"をサポートするブラウザでのsrcset選択の精度を高める最適化であり、サポートしないブラウザでは無視されます。

デフォルトでは、レスポンシブブレークポイントは次のとおりです:

[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]

これらのブレークポイントをカスタマイズしたい場合、IMAGE_CONFIGプロバイダーを使用して行うことができます:

      
providers: [  {    provide: IMAGE_CONFIG,    useValue: {      breakpoints: [16, 48, 96, 128, 384, 640, 750, 828, 1080, 1200, 1920]    }  },],

srcset属性を手動で定義したい場合、ngSrcset属性を使用して独自のものを指定できます:

      
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w">

ngSrcset属性が存在する場合、NgOptimizedImageは含まれるサイズに基づいてsrcsetを生成および設定します。ngSrcsetに画像ファイル名を含めないでください。ディレクティブはこの情報をngSrcから推測します。このディレクティブは、幅記述子(例: 100w)と密度記述子(例: 1x)の両方をサポートしています。

      
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w" sizes="50vw">

自動srcset生成の無効化

単一の画像に対してsrcset生成を無効にするには、画像にdisableOptimizedSrcset属性を追加できます。

      
<img ngSrc="about.jpg" disableOptimizedSrcset>

画像の遅延読み込みの無効化

デフォルトでは、NgOptimizedImagepriorityとマークされていないすべての画像に対してloading=lazyを設定します。優先度の低い画像に対してこの動作を無効にするには、loading属性を設定します。この属性はeagerautolazyの値をサポートします。詳細については、標準の画像loading属性に関するドキュメントを参照してください

      
<img ngSrc="cat.jpg" width="400" height="200" loading="eager">

高度な'sizes'値

異なるサイズの画面で画像を異なる幅で表示したい場合があります。このパターンの一般的な例は、モバイルデバイスでは単一の列を、より大きなデバイスでは2つの列をレンダリングするグリッドベースまたはカラムベースのレイアウトです。この動作は、以下のような「メディアクエリ」構文を使用してsizes属性で表現できます。

      
<img ngSrc="cat.jpg" width="400" height="200" sizes="(max-width: 768px) 100vw, 50vw">

上記の例のsizes属性は、「この画像は幅768px未満のデバイスでは画面幅の100%になることを想定しています。それ以外の場合は、画面幅の50%になることを想定しています。」という意味です。

sizes属性に関する追加情報については、web.devまたはmdnを参照してください。

NgOptimizedImageの画像ローダーを設定する

「ローダー」とは、指定された画像ファイルに対して画像変換URLを生成する関数です。必要に応じて、NgOptimizedImageは画像のサイズ、フォーマット、画質の変換を設定します。

NgOptimizedImageは、変換を適用しない汎用ローダーと、様々なサードパーティ画像サービス用のローダーの両方を提供します。また、独自のカスタムローダーを作成することもサポートしています。

ローダーの種類 動作
汎用ローダー 汎用ローダーが返すURLは常にsrcの値と一致します。つまり、このローダーは変換を適用しません。Angularを使用して画像を配信するサイトが、このローダーの主な想定されるユースケースです。
サードパーティ画像サービス用ローダー サードパーティ画像サービス用ローダーが返すURLは、その特定の画像サービスで使用されるAPI規約に従います。
カスタムローダー カスタムローダーの動作は、その開発者によって定義されます。NgOptimizedImageに事前設定されているローダーで画像サービスがサポートされていない場合は、カスタムローダーを使用する必要があります。

Angularアプリケーションで一般的に使用される画像サービスに基づいて、NgOptimizedImageは以下の画像サービスで動作するように事前設定されたローダーを提供します。

画像サービス Angular API ドキュメント
Cloudflare Image Resizing provideCloudflareLoader ドキュメント
Cloudinary provideCloudinaryLoader ドキュメント
ImageKit provideImageKitLoader ドキュメント
Imgix provideImgixLoader ドキュメント
Netlify provideNetlifyLoader ドキュメント

汎用ローダーを使用するために、追加のコード変更は不要です。これがデフォルトの動作です。

組み込みローダー

サードパーティ画像サービス用の既存のローダーを使用するには、選択したサービスのプロバイダーファクトリをproviders配列に追加します。以下の例では、Imgixローダーが使用されています。

      
providers: [  provideImgixLoader('https://my.base.url/'),],

画像アセットのベースURLは、プロバイダーファクトリに引数として渡す必要があります。ほとんどのサイトでは、このベースURLは以下のいずれかのパターンに一致する必要があります。

ベースURL構造の詳細については、対応するCDNプロバイダーのドキュメントで確認できます。

カスタムローダー

カスタムローダーを使用するには、IMAGE_LOADER DIトークンの値としてローダー関数を提供します。以下の例では、カスタムローダー関数はhttps://example.comで始まるURLを返し、srcwidthをURLパラメータとして含んでいます。

      
providers: [  {    provide: IMAGE_LOADER,    useValue: (config: ImageLoaderConfig) => {      return `https://example.com/images?src=${config.src}&width=${config.width}`;    },  },],

NgOptimizedImageディレクティブのローダー関数は、ImageLoaderConfig型(@angular/commonから)のオブジェクトを引数として受け取り、画像アセットの絶対URLを返します。ImageLoaderConfigオブジェクトには、srcプロパティと、オプションのwidthおよびloaderParamsプロパティが含まれています。

NOTE: widthプロパティが常に存在するとは限りませんが、ngSrcsetが正しく機能するためには、カスタムローダーが様々な幅で画像をリクエストすることをサポートするためにこれを使用する必要があります。

loaderParamsプロパティ

NgOptimizedImageディレクティブには、loaderParamsと呼ばれる追加の属性があり、これはカスタムローダーの使用をサポートするために特別に設計されています。loaderParams属性は、任意のプロパティを持つオブジェクトを値として受け取りますが、それ自体では何も行いません。loaderParams内のデータは、カスタムローダーに渡されるImageLoaderConfigオブジェクトに追加され、ローダーの動作を制御するために使用できます。

loaderParamsの一般的な用途は、高度な画像CDN機能を制御することです。

カスタムローダーの例

以下にカスタムローダー関数の例を示します。この例の関数はsrcwidthを連結し、loaderParamsを使用して角丸のためのカスタムCDN機能を制御します。

      
const myCustomLoader = (config: ImageLoaderConfig) => {  let url = `https://example.com/images/${config.src}?`;  let queryParams = [];  if (config.width) {    queryParams.push(`w=${config.width}`);  }  if (config.loaderParams?.roundedCorners) {    queryParams.push('mask=corners&corner-radius=5');  }  return url + queryParams.join('&');};

上記の例では、カスタムローダーの機能を制御するために「roundedCorners」というプロパティ名を考案したことに注意してください。この機能は、画像を生成する際に次のように使用できます。

      
<img ngSrc="profile.jpg" width="300" height="300" [loaderParams]="{roundedCorners: true}">

よくある質問

NgOptimizedImageはbackground-imageCSSプロパティをサポートしていますか?

NgOptimizedImageはbackground-imageCSSプロパティを直接サポートしていませんが、別の要素の背景として画像を使用するユースケースに容易に対応できるように設計されています。

background-imageからNgOptimizedImageへの移行の段階的なプロセスについては、上記の背景画像の移行方法セクションを参照してください。

NgOptimizedImageでsrcを使用できないのはなぜですか?

ngSrc属性は、ブラウザが画像を読み込む方法に関する技術的な考慮事項から、NgOptimizedImageのトリガーとして選択されました。NgOptimizedImageはloading属性にプログラムによる変更を加えます。ブラウザがこれらの変更が行われる前にsrc属性を認識すると、画像ファイルの積極的なダウンロードを開始し、読み込みの変更は無視されます。

画像ドメインのプリコネクト要素が生成されないのはなぜですか?

プリコネクトの生成は、アプリケーションの静的解析に基づいて実行されます。つまり、画像ドメインは、次の例のように、ローダーパラメーターに直接含める必要があります。

      
providers: [  provideImgixLoader('https://my.base.url/'),],

変数を使用してドメイン文字列をローダーに渡している場合、またはローダーを使用していない場合、静的解析はドメインを識別できず、プリコネクトリンクは生成されません。この場合、上記で説明されているように、ドキュメントのヘッドにプリコネクトリンクを手動で追加する必要があります。

同じページで2つの異なる画像ドメインを使用できますか?

画像ローダープロバイダーパターンは、コンポーネント内で単一の画像CDNのみを使用するという一般的なユースケースに対して、可能な限りシンプルになるように設計されています。ただし、単一のプロバイダーを使用して複数の画像CDNを管理することは依然として非常に可能です。

これを行うには、カスタム画像ローダーを作成し、loaderParamsプロパティを使用して、どの画像CDNを使用すべきかを指定するフラグを渡し、そのフラグに基づいて適切なローダーを呼び出すことをお勧めします。

優先するCDN用の新しい組み込みローダーを追加できますか?

メンテナンス上の理由から、現在Angularリポジトリで追加の組み込みローダーをサポートする予定はありません。代わりに、開発者には追加の画像ローダーをサードパーティパッケージとして公開することを推奨しています。

これを<picture>タグで使用できますか?

いいえ、しかしこれは私たちのロードマップにありますので、ご期待ください。

この機能を待っている場合は、Githubのイシューをこちらでアップボートしてください。

Chrome DevToolsでLCP画像を見つけるにはどうすればよいですか?

  1. Chrome DevToolsのパフォーマンスタブを使用して、左上にある「プロファイリングを開始してページを再読み込み」ボタンをクリックします。これはページ更新アイコンのように見えます。

  2. これにより、Angularアプリケーションのプロファイリングスナップショットがトリガーされます。

  3. プロファイリング結果が利用可能になったら、タイミングセクションで「LCP」を選択します。

  4. 下部のパネルに概要エントリが表示されます。「関連ノード」の行でLCP要素を見つけることができます。それをクリックすると、要素がElementsパネルに表示されます。

Chrome DevToolsのLCP

NOTE: これは、テストしているページのビューポート内のLCP要素のみを識別します。より小さな画面のLCP要素を識別するために、モバイルエミュレーションを使用することも推奨されます。