NgOptimizedImage
ディレクティブは、画像の読み込みにおけるパフォーマンスのベストプラクティスを簡単に採用できるようにします。
このディレクティブは、Largest Contentful Paint (LCP) 画像の読み込みが以下の方法で優先されるようにします。
<img>
タグにfetchpriority
属性を自動的に設定する- デフォルトで他の画像を遅延読み込みする
- ドキュメントのヘッドにプリコネクトリンクタグを自動的に生成する
srcset
属性を自動的に生成する- アプリケーションがSSRを使用している場合、プリロードヒントを生成する
LCP画像の読み込みを最適化することに加えて、NgOptimizedImage
は以下のようないくつかの画像のベストプラクティスを強制します。
- 画像最適化を適用するための画像CDNのURLの使用
width
とheight
を要求することでレイアウトシフトを防ぐwidth
またはheight
が誤って設定されている場合に警告する- 画像がレンダリング時に視覚的に歪む場合に警告する
CSSで背景画像を使用している場合は、こちらから開始してください。
NOTE: NgOptimizedImage
ディレクティブはAngularバージョン15で安定版機能となりましたが、バックポートされており、バージョン13.4.0および14.3.0でも安定版機能として利用可能です。
はじめに
-
NgOptimizedImage
ディレクティブのインポートNgOptimizedImage
ディレクティブを@angular/common
からインポートします。import { NgOptimizedImage } from '@angular/common'
そして、スタンドアロンコンポーネントまたはNgModuleの
imports
配列に含めます。imports: [ NgOptimizedImage, // ...],
-
(オプション)ローダーの設定
NgOptimizedImageを使用するために画像ローダーは必須ではありませんが、画像CDNと組み合わせて使用すると、画像の自動
srcset
を含む強力なパフォーマンス機能が有効になります。ローダーの設定に関する簡単なガイドは、このページの最後にある画像ローダーの設定セクションにあります。
-
ディレクティブの有効化
NgOptimizedImage
ディレクティブを有効にするには、画像のsrc
属性をngSrc
に置き換えます。<img ngSrc="cat.jpg">
組み込みのサードパーティローダーを使用している場合は、
src
からベースURLパスを省略してください。これはローダーによって自動的に前置されます。 -
画像を
priority
としてマークするページのLCP画像は、その読み込みを優先するために常に
priority
としてマークしてください。<img ngSrc="cat.jpg" width="400" height="200" priority>
画像を
priority
としてマークすると、以下の最適化が適用されます。fetchpriority=high
を設定します(プライオリティヒントの詳細についてはこちらを参照してください)loading=eager
を設定します(ネイティブ遅延読み込みの詳細についてはこちらを参照してください)- サーバーでレンダリングする場合、プリロードリンク要素を自動的に生成します。
LCP要素が
priority
属性を持たない画像である場合、Angularは開発中に警告を表示します。ページのLCP要素は、ユーザーの画面の寸法など、さまざまな要因に基づいて変化する可能性があるため、ページにはpriority
としてマークすべき複数の画像が存在する場合があります。詳細については、CSS for Web Vitalsを参照してください。 -
幅と高さを含める
画像関連のレイアウトシフトを防ぐため、NgOptimizedImageでは次のように画像の高さと幅を指定する必要があります。
<img ngSrc="cat.jpg" width="400" height="200">
レスポンシブ画像(ビューポートに対して拡大縮小するようにスタイル設定された画像)の場合、
width
およびheight
属性は画像ファイルの固有のサイズである必要があります。レスポンシブ画像の場合、sizes
の値を設定することも重要です。固定サイズ画像の場合、
width
およびheight
属性は画像の目的のレンダリングサイズを反映する必要があります。これらの属性のアスペクト比は、常に画像の固有のアスペクト比と一致する必要があります。NOTE: 画像のサイズが不明な場合は、以下で説明するように、親コンテナのサイズを継承するために「フィルモード」の使用を検討してください。
fill
モードの使用
画像をコンテナ要素にフィットさせたい場合、fill
属性を使用できます。これは、「背景画像」のような動作を実現したい場合にしばしば役立ちます。また、画像の正確な幅と高さが不明な場合でも、既知のサイズを持つ親コンテナに画像をフィットさせたい場合に役立ちます(下記の「object-fit」を参照)。
画像にfill
属性を追加する場合、以下の例のようにwidth
とheight
を含める必要はなく、含めるべきではありません。
<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
へ移行するための簡単なステップバイステッププロセスです。これらのステップでは、画像背景を持つ要素を「コンテナ要素」と呼びます。
- コンテナ要素から
background-image
スタイルを削除します。 - コンテナ要素が
position: "relative"
、position: "fixed"
、またはposition: "absolute"
を持つことを確認します。 - コンテナ要素の子として新しい画像要素を作成し、
ngSrc
を使用してNgOptimizedImage
ディレクティブを有効にします。 - その要素に
fill
属性を付与します。height
とwidth
を含めないでください。 - この画像が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%を占める場合、sizes
を100vw
に設定すると、ブラウザは(ピクセル密度を考慮した上で)ビューポート幅に最も近いsrcset
内の画像を選択します。画像が画面の半分しか占めない可能性が高い場合(例: サイドバー内)、ブラウザがより小さな画像を選択するようにsizes
を50vw
に設定します。以下同様です。
上記が目的の画像動作をカバーしない場合、高度な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>
画像の遅延読み込みの無効化
デフォルトでは、NgOptimizedImage
はpriority
とマークされていないすべての画像に対してloading=lazy
を設定します。優先度の低い画像に対してこの動作を無効にするには、loading
属性を設定します。この属性はeager
、auto
、lazy
の値をサポートします。詳細については、標準の画像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を返し、src
とwidth
を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機能を制御することです。
カスタムローダーの例
以下にカスタムローダー関数の例を示します。この例の関数はsrc
とwidth
を連結し、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-image
CSSプロパティをサポートしていますか?
NgOptimizedImageはbackground-image
CSSプロパティを直接サポートしていませんが、別の要素の背景として画像を使用するユースケースに容易に対応できるように設計されています。
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画像を見つけるにはどうすればよいですか?
Chrome DevToolsのパフォーマンスタブを使用して、左上にある「プロファイリングを開始してページを再読み込み」ボタンをクリックします。これはページ更新アイコンのように見えます。
これにより、Angularアプリケーションのプロファイリングスナップショットがトリガーされます。
プロファイリング結果が利用可能になったら、タイミングセクションで「LCP」を選択します。
下部のパネルに概要エントリが表示されます。「関連ノード」の行でLCP要素を見つけることができます。それをクリックすると、要素がElementsパネルに表示されます。

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