Angular NgOptimizedImage 指令新功能

亞歷克斯城堡
Alex Castle

一年多前,Chrome Aurora 團隊推出了 Angular NgOptimizedImage 指令。這項指令主要著重於提升效能,依網站體驗核心指標指標衡量。此版本整合了常見的圖片最佳化和最佳做法,並納入面向使用者的 API,這比標準 <img> 元素簡單許多。

2023 年,我們增加了新功能的指令。本文將介紹這些功能中最重要的部分,並著重說明我們選擇優先處理各項功能的原因,以及這項功能如何協助改善 Angular 應用程式的效能。

新功能

隨著時間的推移,NgOptimizedImage 已大幅改善,包括以下新功能。

填滿模式

提供 widthheight 屬性調整圖片大小是減少版面配置位移的重要最佳化做法,因為瀏覽器必須知道圖片的長寬比,才能節省圖片空間。然而,調整大小圖片對應用程式開發人員來說是額外的工作,且在部分圖片用途中並不合理。

開發人員預覽版圖片元件新增後,第一個主要功能就是協助解決這個張力:填滿模式。這個方法可讓開發人員加入未明確調整大小的圖片,也不會產生版面配置位移。

使用填滿模式時,系統會停用圖片大小規定,而圖片會自動調整樣式,填滿其所含元素。這會將圖片的顯示比例與所在網頁的空間分隔開來,方便您進一步掌控圖片符合網頁版面配置的方式。

填滿模式使用 NgOptimizedImage 做為 background-image css 屬性中成效較佳的替代方案。將圖片放在 <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

使用 srcset 屬性是最有效的圖片最佳化技巧之一,確保為存取您應用程式的裝置下載大小適當大小的圖片。在整個應用程式中使用 srcset 可避免您浪費頻寬,並大幅改善 LCP Core Web Vitals

srcset 屬性的缺點是實作方式可能相當麻煩。手動撰寫 srcset 值,表示為應用程式中的每個圖片元素新增多行標記,並為每個 srcset 加入多個自訂網址。您也必須決定一組較為複雜的中斷點,因為這些中斷點分別可以代表一般裝置的螢幕密度和可視區域大小。

因此,在 NgOptimizedImage 指令中加入自動化的 srcset 產生,是推出後的主要里程碑。新增後,凡是使用 CDN 且支援圖片大小調整機制的應用程式,都能將具備完整且可自訂的 srcset 新增至 NgOptimizedImage 指令產生的每張圖片。

我們納入了簡化的 sizes 屬性設定 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" 標記,立即開始連線至您的圖片網域。

如果您未預先連線至 LCP 映像檔網域,但警告並非理想解決方案,NgOptimizedImage 即發出警告,只是想為您解決問題。正如 NgOptimizedImage 帶來的成效,現在有了自動預先連線產生的功能。

為支援這項功能,我們會使用靜態程式碼分析,嘗試偵測 NgOptimizedImage 載入器中的圖片網域,並自動產生這些網域的預先連結代碼。在某些情況下,您可能還是必須手動預先連結,但對多數使用者來說,自動預先連線功能可讓您不需完成一個步驟就能提升映像檔效能。

強化對自訂載入器的支援

NgOptimizedImage 的一個關鍵元素是載入器架構,可讓該指令自動產生為應用程式圖片 CDN 量身打造的網址。廣受使用的 CDN 皆內建一組內建載入器。您也可以使用自訂載入器,將 NgOptimizedImage 與幾乎任何圖片代管解決方案整合。

這些自訂載入器啟動時,僅受範圍內限制,只能讀取圖片元素中的 width 屬性。為了回應使用者的意見回饋,我們開始支援可自訂的 loaderParams 資料結構,讓圖片元素任意從圖片元素傳遞任意資料至自訂載入器。有了擴展功能,自訂載入器可以十分簡單,也可視應用程式的映像檔基礎架構而定,十分簡單或十分複雜。

以下範例說明簡易自訂載入器如何使用 loaderParams API 在兩個替代圖片網域之間選取:

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 應用程式。現在,如果系統偵測到可能提升效能的圖片模式 (例如延遲載入 LCP 圖片,或者下載的檔案對網頁過大),即使未使用 NgOptimizedImage,您也會收到通知。

圖片效能對所有應用程式而言都相當重要。我們很高興能持續開發防護機制,避免 Angular 應用程式發生的常見錯誤。

展望未來

我們已經開始努力開發 NgOptimizedImage 的下一組功能。雖然圖片效能仍是我們的核心考量,但我們也希望加入可改善開發人員體驗的功能,確保 NgOptimizedImage 仍是很有吸引力的選項,您可以在 Angular 應用程式中加入圖片。

其中一項功能是圖片預留位置。這類資料通常用於改善網頁應用程式上的圖片載入速度,但如果實作不正確,就會降低效能。我們希望在 NgOptimizedImage 中建構出效能優先的映像檔預留位置系統。敬請持續關注我們的網誌,掌握更多公告事項!