跳到主要內容

圖片最佳化

範例

根據 Web Almanac,圖片在一般網站的 頁面權重 中佔了很大一部分,並且可能對網站的 LCP 效能 產生顯著影響。

Next.js 圖片組件擴展了 HTML <img> 元素,加入了自動圖片最佳化的功能

  • 尺寸最佳化: 自動為每個裝置提供正確尺寸的圖片,並使用現代圖片格式,例如 WebP。
  • 視覺穩定性: 在圖片載入時自動防止版面配置偏移
  • 更快的頁面載入速度: 圖片僅在進入視口時才使用原生瀏覽器延遲載入,並可選用模糊佔位符。
  • 資源彈性: 隨需調整圖片大小,即使是儲存在遠端伺服器上的圖片也是如此

🎥 觀看: 深入瞭解如何使用 next/imageYouTube (9 分鐘)

用法

import Image from 'next/image'

然後,你可以為圖片定義 src(本地或遠端)。

本地圖片

若要使用本地圖片,請 import 你的 .jpg.png.webp 圖片檔案。

Next.js 將自動判斷根據匯入檔案的圖片固有 widthheight。這些值用於判斷圖片比例並防止在圖片載入時發生累計版面配置偏移

pages/index.js
import Image from 'next/image'
import profilePic from '../public/me.png'
 
export default function Page() {
  return (
    <Image
      src={profilePic}
      alt="Picture of the author"
      // width={500} automatically provided
      // height={500} automatically provided
      // blurDataURL="data:..." automatically provided
      // placeholder="blur" // Optional blur-up while loading
    />
  )
}

警告: 不支援動態 await import()require()import 必須是靜態的,以便在建置時進行分析。

你可以選擇在 next.config.js 檔案中設定 localPatterns,以允許特定圖片並封鎖所有其他圖片。

next.config.js
module.exports = {
  images: {
    localPatterns: [
      {
        pathname: '/assets/images/**',
        search: '',
      },
    ],
  },
}

遠端圖片

若要使用遠端圖片,src 屬性應為 URL 字串。

由於 Next.js 在建置過程中無法存取遠端檔案,因此你需要手動提供widthheight 和可選的 blurDataURL 屬性。

widthheight 屬性用於推斷圖片的正確長寬比,並避免圖片載入時發生版面配置偏移。 widthheight決定圖片檔案的渲染大小。深入瞭解圖片尺寸

app/page.js
import Image from 'next/image'
 
export default function Page() {
  return (
    <Image
      src="https://s3.amazonaws.com/my-bucket/profile.png"
      alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}

為了安全地允許最佳化圖片,請在 next.config.js 中定義支援的 URL 模式清單。 請盡可能明確,以防止惡意使用。例如,以下設定僅允許來自特定 AWS S3 儲存貯體的圖片

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 's3.amazonaws.com',
        port: '',
        pathname: '/my-bucket/**',
        search: '',
      },
    ],
  },
}

深入瞭解 remotePatterns 設定。如果你想為圖片 src 使用相對 URL,請使用 loader

網域

有時你可能想要最佳化遠端圖片,但仍然使用內建的 Next.js 圖片最佳化 API。 若要執行此操作,請將 loader 保留為預設設定,並為圖片 src 屬性輸入絕對 URL。

為了保護你的應用程式免受惡意使用者的侵害,你必須定義要與 next/image 組件搭配使用的遠端主機名稱清單。

深入瞭解 remotePatterns 設定。

載入器

請注意,在稍早的範例中,為本地圖片提供了部分 URL ("/me.png")。 這是由於載入器架構而成為可能。

載入器是一個產生圖片 URL 的函式。 它會修改提供的 src,並產生多個 URL 以請求不同尺寸的圖片。 這些多個 URL 用於自動 srcset 產生,以便為網站訪客提供適合其視口的圖片尺寸。

Next.js 應用程式的預設載入器使用內建的圖片最佳化 API,它會最佳化來自網路上任何位置的圖片,然後直接從 Next.js 網頁伺服器提供這些圖片。 如果你想直接從 CDN 或圖片伺服器提供圖片,你可以用幾行 JavaScript 程式碼編寫自己的載入器函式。

你可以使用 loader 屬性為每個圖片定義一個載入器,或使用 loaderFile 設定在應用程式層級定義載入器。

優先權

你應該將 priority 屬性新增至將成為每個頁面的最大內容繪製 (LCP) 元素的圖片。 這樣做可讓 Next.js 預先載入圖片,從而顯著提升 LCP。

LCP 元素通常是頁面視口中可見的最大圖片或文字區塊。 當你執行 next dev 時,如果 LCP 元素是沒有 priority 屬性的 <Image>,你將會看到控制台警告。

一旦你識別出 LCP 圖片,你就可以像這樣新增屬性

app/page.js
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 組件文件,以瞭解有關優先權的更多資訊。

圖片尺寸

圖片最常損害效能的方式之一是透過版面配置偏移,也就是圖片在載入時會將頁面上的其他元素推開。 這個效能問題對於使用者來說非常惱人,以至於它有自己的核心網頁指標,稱為累計版面配置偏移。 避免基於圖片的版面配置偏移的方法是始終調整圖片尺寸。 這可讓瀏覽器在圖片載入之前預留精確足夠的空間。

由於 next/image 旨在保證良好的效能結果,因此不能以會導致版面配置偏移的方式使用,並且必須透過以下三種方式之一調整大小

  1. 自動,使用靜態匯入
  2. 手動,透過包含用於判斷圖片長寬比的 widthheight 屬性。
  3. 隱含地,透過使用 fill,這會使圖片展開以填滿其父元素。

如果我不知道圖片的大小怎麼辦?

如果你從來源存取圖片,但不知道圖片的大小,你可以執行以下幾項操作

使用 fill

fill 屬性允許圖片由其父元素調整大小。 考慮使用 CSS 為頁面上的圖片父元素提供空間,並使用 sizes 屬性來符合任何媒體查詢斷點。 你也可以將 object-fitfillcontaincover 搭配使用,並將 object-position 用於定義圖片應如何佔據該空間。

標準化你的圖片

如果你要從你控制的來源提供圖片,請考慮修改你的圖片管線,將圖片標準化為特定大小。

修改你的 API 呼叫

如果你的應用程式正在使用 API 呼叫 (例如 CMS) 檢索圖片 URL,你或許可以修改 API 呼叫以傳回圖片尺寸以及 URL。

如果建議的方法都無法調整圖片大小,則 next/image 組件旨在與標準 <img> 元素在頁面上並排運作良好。

樣式

圖片組件的樣式設定與設定一般 <img> 元素樣式類似,但有一些準則需要牢記

  • 使用 classNamestyle,而不是 styled-jsx
    • 在大多數情況下,我們建議使用 className 屬性。 這可以是匯入的 CSS 模組全域樣式表 等。
    • 你也可以使用 style 屬性來指派內嵌樣式。
    • 你無法使用 styled-jsx,因為它的範圍限定於目前的組件 (除非你將樣式標記為 global)。
  • 當使用 fill 時,父元素必須具有 position: relative
    • 這對於在該版面配置模式下正確渲染圖片元素是必要的。
  • 當使用 fill 時,父元素必須具有 display: block
    • 這是 <div> 元素的預設值,但否則應指定。

範例

響應式

Responsive image filling the width and height of its parent container
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
 
export default function Responsive() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column' }}>
      <Image
        alt="Mountains"
        // Importing an image will
        // automatically set the width and height
        src={mountains}
        sizes="100vw"
        // Make the image display full width
        style={{
          width: '100%',
          height: 'auto',
        }}
      />
    </div>
  )
}

填滿容器

Grid of images filling parent container width
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
 
export default function Fill() {
  return (
    <div
      style={{
        display: 'grid',
        gridGap: '8px',
        gridTemplateColumns: 'repeat(auto-fit, minmax(400px, auto))',
      }}
    >
      <div style={{ position: 'relative', height: '400px' }}>
        <Image
          alt="Mountains"
          src={mountains}
          fill
          sizes="(min-width: 808px) 50vw, 100vw"
          style={{
            objectFit: 'cover', // cover, contain, none
          }}
        />
      </div>
      {/* And more images in the grid... */}
    </div>
  )
}

背景圖片

Background image taking full width and height of page
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
 
export default function Background() {
  return (
    <Image
      alt="Mountains"
      src={mountains}
      placeholder="blur"
      quality={100}
      fill
      sizes="100vw"
      style={{
        objectFit: 'cover',
      }}
    />
  )
}

如需將圖片組件與各種樣式搭配使用的範例,請參閱 圖片組件示範

其他屬性

檢視 next/image 組件可用的所有屬性。

設定

next/image 組件和 Next.js 圖片最佳化 API 可以在 next.config.js 檔案中設定。 這些設定可讓你啟用遠端圖片定義自訂圖片斷點變更快取行為等等。

閱讀完整的圖片設定文件以取得更多資訊。