Image 元件與圖片最佳化

範例

Next.js 中的 Image 元件 next/image,是為了因應現代網頁發展,自 HTML <img>元素延伸而成。它含有許多已內建好的效能最佳化機制,可協助開發者更易達到較高的 網站體驗核心指標(Core Web Vitals),此指標分數為衡量網頁使用者體驗很重要的標準,並且也是影響 Google 搜尋結果排行的關鍵因素

Image 元件內建的最佳化機制包含:

  • 最佳化載入效能: 依據不同載具,正確載入對應的圖片尺寸和現代圖片格式
  • 增強視覺穩定: 自動防止 累計版面配置位移(Cumulative Layout Shift)
  • 加快載入速度: 圖片僅在進入可視範圍時才會載入,未載入完成時,可選擇使圖片先模糊顯示
  • 提升取用彈性: 即便是儲存於遠端伺服器的圖片,取用時也都會重新調整尺寸

使用 Image 元件

若要新增圖片至您的應用程式,請使用 next/image 元件:

import Image from 'next/image'

此外,當您需要使用較貼近原生 <img> 元素時,您也可使用 next/future/image

import Image from 'next/future/image'

現在,您可以為您的圖片定義 src (無論本地或遠端)。

本機圖片

若要使用本機的圖片檔,請匯入您的 .jpg.png.webp 檔案:

import profilePic from '../public/me.png'

這裡不支援動態載入 await import()require(),僅支持靜態載入 import,如此一來,才可於建置時間分析載入的圖片檔。

Next.js 將自動依據載入檔案決定圖片的 寬度(width)高度(height),這樣才可在載入圖片時預防 累計版面配置位移(Cumulative Layout Shift) 的問題。

import Image from 'next/image' import profilePic from '../public/me.png' function Home() { return ( <> <h1>My Homepage</h1> <Image src={profilePic} alt="Picture of the author" // width={500} Next.js自動提供 // height={500} Next.js自動提供 // blurDataURL="data:..." Next.js自動提供 // placeholder="blur" // 可自行決定當圖片載入未完成時是否需模糊呈現 /> <p>Welcome to my homepage!</p> </> ) }

遠端圖片

需載入遠端圖片檔時,src 屬性需輸入 URL 字串,其可為 相對絕對 路徑。 因 Next.js 於建置過程中無法分析遠端圖片檔,故您需手動提供 寬度(width)高度(height) 與可自選提供的 blurDataURL 等 prop 參數 :

import Image from 'next/image' export default function Home() { return ( <> <h1>My Homepage</h1> <Image src="/me.png" alt="Picture of the author" width={500} height={500} /> <p>Welcome to my homepage!</p> </> ) }

next/image 可瞭解更多關於 調整圖片尺寸需求

網域(Domains)

若您想使用 Next.js 內建的圖片最佳化載入 API 來取得遠端圖片檔,則須保持 loader 預設的設定,並於圖片的 src 屬性中輸入其 URL 絕對路徑。

為了避免您的應用程式遭受惡意使用者攻擊,您應列出您預計於 next/image 元件中會使用的遠端 主機名稱(hostname) 清單。

可瞭解更多關於 網域(domains) 設定檔

Loaders

您或許有注意到,在 先前的範例 中,取得遠端圖片時,使用得是不完整的 URL ("/me.png")。之所以可以這樣寫,是因為 next/image 內有設計 loader 機制。

Loader 是個可以為您的圖片檔生成許多對應 URL 的功能,他會將根網域(root domain)加至您所提供的 src 中,並生成對應不同圖片尺寸大小的 URL。這些 URL 將在自動產生 srcset 的過程中使用到,使您的網頁使用者可以看到對應其可視範圍正確的圖片尺寸。

Next.js 中的預設 loader 使用內建的圖片最佳化 API,它可以優化所有在網路中的各種圖片載入,並可直接取用於 Next.js 的網頁伺服器。若您需要從您的 CDN 或圖片伺服器取用檔案,則您可選用合適的 built-in loaders 或自己寫所需的 loader。

Loaders 可於每張圖片個別設定,也可在應用程式中統一設定。

優先權

您可以將 優先權(priority) 屬性加入您頁面中,屬於 最大內容繪製 (LCP) 元素 的圖片。如此一來, Next.js 將優先處理此圖片的載入 (例如:透過預載入標籤或優先排序提示),使您的 LCP 指標分數可顯著提升。

最大內容繪製 (LCP) 元素,通常為該頁面可視區域中,最大的圖片或文字區塊。若您未在 LCP 元素中設定 priority 屬性,則在跑 next dev 指令時,您將會於 console 中看到相關警告。

若您已辨認出該頁面的 LCP 圖片,您可參考如下範例,新增 priority 屬性:

import Image from 'next/image' export default function Home() { return ( <> <h1>My Homepage</h1> <Image src="/me.png" alt="Picture of the author" width={500} height={500} priority /> <p>Welcome to my homepage!</p> </> ) }

next/image 元件文件 可瞭解更多關於 priority 屬性

設定圖片尺寸

圖片載入之所以會影響效能常見的原因之一便是版面配置,因為圖片在載入的當下,可能會推擠到周遭其他元素的排列。這個效能問題也被列為網站體驗核心指標(Core Web Vitals)之一,稱作 累計版面配置位移(Cumulative Layout Shift)。若想避免圖片載入造成的版面配置位移問題,便該記得每次都 指定圖片尺寸,這樣瀏覽器才可在圖片載入完成前,預先保留足夠的空間。

由於 next/image 是基於提升效能的目的而設計,應該使用以下三種方法來設定圖片尺寸,以避免版面配置位移問題:

  1. 使用 靜態 import,Next.js 將自動為您設定圖片尺寸
  2. 明確指定該圖片的 寬度(width) and 高度(height) 屬性
  3. 使用 layout="fill" 屬性,則該圖片將延展至填滿母元素

如果不知道圖片的尺寸該怎麼辦?

如果不清楚需要取得的圖片尺寸大小,則您可以參考下列處理方式:

使用 layout='fill'

fill 版面配置模式下,您的圖片尺寸將由其母元素決定。您可考慮用 CSS 來指定該圖片的母元素於頁面的空間範圍, 接著運用 objectFit 屬性 中的 fillcontaincover,並搭配 objectPosition 屬性 來決定該圖片於母元素中的位置。

規範您的圖片

若您能控制您的圖片來源,可以考慮規範您的圖片尺寸為特定大小。

調整您的 API 請求

若您的圖片 URL 是透過 API 請求而來 (例如 CMS),您或許可以使 API 回傳您該圖片的尺寸。

若上述處理方式都無法設定您的圖片尺寸,則 next/image 元件設計便可讓您使用標準的 <img> 元素達到此效果。

調整圖片樣式

注意: 以下列出多數的樣式問題,解決方式可參考 next/future/image

調整 Image 元件樣式與調整一般的 <img> 元素差異不大,您可以把握以下原則:

選擇正確的版面配置模式

圖片元件擁有不同的 版面配置模式 來決定他們在頁面上呈現的尺寸大小。如果您的圖片樣式不如您的預期,可以嘗試更改他的版面配置模式。

使用 className 調整而不依賴 DOM 結構

在多數的版面配置中,通常 DOM 結構裡會有一個母元素 <span> 包住一個子元素 <img>,有時為了保留更多空間,甚至還會存在其他子元素 <span>,這些額外的子元素 <span> 是造成版面配置位移問題的關鍵因素之一。

我們比較推薦的做法,是藉由設定 Image 元件所引用的 CSS ModuleclassName 屬性來調整子元素 <img> 的樣式,而 className 的值將自動套用至其所屬的 <img> 元素。

或者,您也可以匯入 global stylesheet 並於 className 屬性中手動設定需要的樣式。

您無法使用 styled-jsx 因其效果僅限於當前元件。

當使用 layout='fill' 配置模式時,母元素必須設定 position: relative

為了於此配置模式下,更適當的渲染圖片元素,這是必要的設定。

當使用 layout='responsive' 配置模式時,母元素必須設定 display: block

雖然這是 <div> 元素的預設值,但仍須強調此設定。

屬性

觀看所有 next/image 元件可使用的屬性

圖片樣式範例

您可於 Image 元件範例 app 看見使用不同配置模式的 Image 元件。

設定檔

next/image 元件和 Next.js 圖片最佳化 API 可於 next.config.js 檔案做設定,您可於此檔案 處理遠端圖片客製化響應式設計的圖片分界點調整快取機制 或更多相關設定。

您可在圖片設定檔文件中獲得更多資訊

相關參考

我們推薦您下列章節,以獲取更多相關資訊:

本篇文章由dorahs71

dorahs71

貢獻翻譯。瞭解如何參與貢獻