Angular NgOptimizedImage ディレクティブの新機能

Alex Castle
Alex Castle

1 年ほど前に、Chrome Aurora チームAngular NgOptimizedImage ディレクティブをリリースしました。この指示は、Core Web Vitals 指標で測定されるパフォーマンスの向上に主眼を置いています。一般的な画像の最適化とベスト プラクティスを、標準の <img> 要素とそれほど変わらない複雑さのユーザー向け API にバンドルしています。

2023 年には、このdirectiveに新機能を追加しました。この投稿では、最も重要な新機能について説明します。各機能に優先順位を付けた理由と、Angular アプリケーションのパフォーマンスを改善する方法に重点を置いています。

新機能

NgOptimizedImage は、以下の新機能など、時間の経過とともに大幅に改善されています。

塗りつぶしモード

width 属性と height 属性を指定して画像のサイズを調整することは、レイアウト シフトを減らすために極めて重要な最適化です。ブラウザは、画像のサイズを確保するために画像のアスペクト比を認識する必要があるためです。ただし、画像のサイズ調整はアプリ デベロッパーにとって追加の作業であり、画像のユースケースによっては意味がありません。

この問題を解決するために、デベロッパー プレビュー後に画像コンポーネントに追加された最初の主要機能である塗りつぶしモードが役立ちます。これは、デベロッパーが画像のサイズを明示的に指定せずに、レイアウト シフトを発生させることなく画像を含める方法です。

フィットモードでは、画像のサイズ要件が無効になり、画像は、その親要素を埋めるように自動的にスタイル設定されます。これにより、画像のアスペクト比とページ上の占有スペースが分離され、画像がページ レイアウトにどのように収まるかをより細かく制御できるようになります。

塗りつぶしモードでは、background-image CSS プロパティの代わりに NgOptimizedImage を使用することで、パフォーマンスが向上しています。<div> または background-image スタイルが適用される他の要素内に画像を配置し、上記のコード例に示すように、塗りつぶしモードを有効にします。<div>object-fitobject-position の CSS プロパティを使用して、背景に画像を配置する方法を制御します。

// Height and width are required
<img ngSrc="example.com" height="300" width="400">

// Unless you use fill mode!
<div style="width: 100vw; height: 50em; position: relative">
  <img ngSrc="example.com" fill>
</div>

Srcset の生成

画像の最適化で最も効果的な手法の 1 つは、srcset 属性を使用することです。これにより、アプリケーションにアクセスするすべてのデバイスに適切なサイズの画像がダウンロードされるようになります。アプリ全体で srcset を使用すると、帯域幅の浪費を防ぎ、LCP Core Web Vital を大幅に改善できます。

srcset 属性の欠点は、実装が面倒になる可能性があることです。srcset 値を手動で記述する場合は、アプリ内の各画像要素に複数行のマーカーアップを追加し、各 srcset に複数のカスタム URL を指定します。また、一連のブレークポイントを決定する必要があります。これは、一般的なデバイスの画面密度とビューポート サイズの両方を表すため、複雑です。

そのため、srcset の自動生成を NgOptimizedImage ディレクティブに追加することが、リリース後の重要なマイルストーンとなりました。この追加により、画像のサイズ変更をサポートする CDN を使用するすべてのアプリケーションで、NgOptimizedImage ディレクティブで生成されたすべての画像に、カスタマイズ可能な完全な srcset が自動的に追加されるようになりました。

sizes プロパティを設定するための簡素な API が追加されました。この API は、各画像に正しいタイプの srcset が確実に取得されるようにするために使用されます。sizes 属性を含めない場合、画像は固定サイズであることが認識され、次のような密度に依存する srcset が取得されます。

<img src="www.example.com/image.png" srcset="www.example.com/image.png?w=400 1x, www.example.com/image.png?w=800 2x" >

このタイプの srcset を使用すると、ユーザーのデバイスのピクセル密度を考慮したサイズで画像が提供されます。

一方、sizes プロパティを含めると、NgOptimizedImage は、このデフォルトのブレークポイント リストを使用して、多くの一般的なデバイスと画像サイズのブレークポイントを含むレスポンシブ srcset を生成します。

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

プリコネクションの生成

LCP を改善するには、ユーザーが LCP 画像のダウンロードに費やす時間を短縮することが重要です。前のセクションでは、srcset が小さい画像ファイルを転送することで役立つ方法について説明しましたが、転送をできるだけ早く開始することも同様に重要な最適化です。たとえば、link rel="preconnect" タグを使用して、イメージ ドメインへの接続をすぐに開始できます。

NgOptimizedImage は、LCP イメージのドメインに事前接続できない場合に警告してきましたが、警告は理想的な解決策ではありません。Google は、問題を解決することをおすすめします。NgOptimizedImage は、自動プリコネクト生成によって、まさにそのことを実現しています。

この機能をサポートするため、静的コード分析を使用して NgOptimizedImage ローダ内の画像ドメインを検出し、それらのドメインのプリコネクト リンクタグを自動的に生成します。手動でリンクをプリコネクトする必要がある場合もありますが、ほとんどのユーザーにとって、自動プリコネクトは画像のパフォーマンスを高めるために必要な手順を 1 つ減らすことができます。

カスタム ローダのサポートの強化

NgOptimizedImage の重要な要素はローダー アーキテクチャです。これにより、ディレクティブはアプリケーションのイメージ CDN に合わせて URL を自動的に生成できます。広く使用されている CDN のために、組み込みのローダーのセットが含まれています。また、NgOptimizedImage をほぼすべての画像ホスティング ソリューションと統合できるカスタム ローダの使用も提供しています。

リリース当初、これらのカスタム ローダーのスコープは限定されており、画像要素から width 属性のみを読み取ることができました。ユーザーからのフィードバックに基づいて、カスタマイズ可能な loaderParams データ構造のサポートを追加しました。これにより、任意のデータを画像要素からカスタム ローダーに渡すことができます。拡張により、カスタムのローダーは、アプリケーションのイメージ インフラストラクチャが必要とするだけのシンプルなものから複雑なものまでさまざまです。

次の例は、シンプルなカスタム ローダで loaderParams API を使用して 2 つの代替画像ドメインを選択する方法を示しています。

const myCustomLoader = (config: ImageLoaderConfig) => {
  if (config.loaderParams?.alternateDomain) {
    return `https://alternate.domain.com/images/${config.src}`
  }
  return `https://primary.domain.com/images/${config.src}`;
};

より複雑なカスタム ローダの例については、Angular のドキュメントをご覧ください。

画像のパフォーマンスに関するガイダンスの拡充

これまで、Angular に追加した画像パフォーマンス アラートにはすべて、NgOptimizedImage ディレクティブが含まれていました。アプリでディレクティブを使用していない場合は、画像のパフォーマンスに関する問題に関するガイダンスは表示されません。

Angular 17 では、画像パフォーマンスのガイダンスの範囲をすべての Angular アプリに拡大します。パフォーマンスに悪影響を及ぼす間違いが画像パターンで検出されると、NgOptimizedImage を使用していない場合でも、その旨が通知されます。たとえば、LCP 画像の遅延読み込みや、ページに大きすぎるファイルのダウンロードなどです。

画像のパフォーマンスはすべてのアプリにとって重要です。Google は、Angular アプリでよくあるミスを防ぐためのガードレールを引き続き構築していきます。

今後の展望

私たちはすでに、NgOptimizedImage の今後の機能セットの開発に力を入れています。画像のパフォーマンスは依然として Google の中心的な懸念事項ですが、デベロッパー エクスペリエンスを向上させる機能も追加し、NgOptimizedImage が Angular アプリケーションに画像を含めるための魅力的なオプションであり続けるようにしたいと考えています。

優先して取り組んでいる機能の一つが、画像のプレースホルダです。これらは、ウェブ アプリケーションで画像の読み込みをより見栄えよくするためによく使用されますが、正しく実装しないとパフォーマンスが低下する可能性があります。パフォーマンス重視の画像プレースホルダ システムを NgOptimizedImage に組み込む予定です。今後の発表については、YouTube のブログでご確認ください。