Angular NgOptimizedImage 指令新功能

Alex Castle
Alex Castle

一年多前,Chrome Aurora 團隊推出了 Angular NgOptimizedImage 指令。根據網站體驗核心指標指標測量的結果,這個指令主要著重於改善效能。它可將常見的圖片最佳化和最佳做法,整合成面向使用者的 API,而不是像標準 <img> 元素那麼複雜。

在 2023 年,我們新增了更多指令強化功能。本文章將介紹大部分的新功能,並著重說明我們為何選擇優先推出各項功能,以及這項功能如何協助改善 Angular 應用程式的效能。

新功能

與此同時,NgOptimizedImage 有大幅改善,其中包括下列新功能。

填滿模式

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

為解決這個問題,我們先在開發人員預覽版圖片元件後加入第一項主要功能:填滿模式。這樣一來,開發人員就能在不明確設定大小的情況下,加入圖片,且不會發生版面配置位移。

使用填滿模式時,系統會停用圖片大小大小規定,屆時圖片會自動設定樣式,以填滿所含元素。這會將圖片的顯示比例與頁面佔用的空間區分開來,讓您進一步掌控圖片融入網頁版面配置的方式。

填滿模式會使用 NgOptimizedImage,做為 background-image CSS 屬性成效較佳的替代方案。將圖片放入具有 background-image 樣式的 <div> 或其他元素,然後啟用填滿模式,如上述程式碼範例所示。使用 <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,可以避免您浪費頻寬,並大幅改善 LCP Core Web Vitals

srcset 屬性的缺點是實作起來可能很麻煩。手動編寫 srcset 值是指在應用程式中為每個圖片元素新增多行標記,並為每個 srcset 設定多個自訂網址。您也必須決定一系列相當複雜的中斷點,因為中斷點可能同時代表螢幕密度和常見裝置的可視區域大小。

因此,在 NgOptimizedImage 指令中加入自動化 srcset 產生功能,是產品發布後的重要里程碑。有了這項新增功能,凡是使用 CDN 支援圖片大小調整功能的應用程式,都能將 NgOptimizedImage 指令產生的圖片完整加入可自訂的 srcset,

我們加入簡化的 API,方便您設定 sizes 屬性,確保每張圖片都能取得正確的 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 圖片,或下載的檔案過大),Google 會通知您,即使並未使用 NgOptimizedImage,

圖像效能對於所有應用程式來說都很重要,我們很高興能夠繼續打造防護機制,避免 Angular 應用程式發生常見錯誤。

展望未來

我們已經在努力為 NgOptimizedImage 開發下一組功能。雖然圖像效能仍是我們首要考量,但我們也希望加入可提升開發人員體驗的功能,確保 NgOptimizedImage 仍然是引人入勝的選擇,將圖片納入 Angular 應用程式。

我們的優先功能之一是圖片預留位置。這類設定檔常可讓網頁應用程式在載入圖片時看起來更美觀,但如果實作方式錯誤,效能可能會降低。我們希望在 NgOptimizedImage 中建構出首重效能優先的圖片預留位置系統。敬請持續關注我們的網誌,掌握更多最新消息!