<Image> (舊版)

範例

從 Next.js 13 開始,next/image 元件經過重寫以提升效能和開發者體驗。為了提供向後相容的升級方案,舊版 next/image 已更名為 next/legacy/image

查看新版 next/image API 參考文件

比較

next/legacy/image 相比,新版 next/image 元件有以下變更:

  • 移除 <img> 周圍的 <span> 包裝,改為使用原生計算寬高比
  • 新增支援標準 style 屬性
    • 移除 layout 屬性,改用 styleclassName
    • 移除 objectFit 屬性,改用 styleclassName
    • 移除 objectPosition 屬性,改用 styleclassName
  • 移除 IntersectionObserver 實現,改用原生懶加載
    • 移除 lazyBoundary 屬性,因為沒有原生替代方案
    • 移除 lazyRoot 屬性,因為沒有原生替代方案
  • 移除 loader 配置,改用 loader 屬性
  • alt 屬性從可選改為必填
  • 變更 onLoadingComplete 回調函式,改為接收 <img> 元素的參考

必要屬性

<Image /> 元件需要以下屬性。

src

必須是以下其中一種:

使用外部 URL 時,必須將其添加到 next.config.js 中的 remotePatterns

width

width 屬性可以表示_渲染_寬度或_原始_寬度(像素),取決於 layoutsizes 屬性。

使用 layout="intrinsic"layout="fixed" 時,width 屬性表示_渲染_寬度(像素),因此會影響圖片顯示的大小。

使用 layout="responsive"layout="fill" 時,width 屬性表示_原始_寬度(像素),因此只會影響寬高比。

width 屬性是必填的,除非是靜態匯入的圖片,或使用 layout="fill" 的情況。

height

height 屬性可以表示_渲染_高度或_原始_高度(像素),取決於 layoutsizes 屬性。

使用 layout="intrinsic"layout="fixed" 時,height 屬性表示_渲染_高度(像素),因此會影響圖片顯示的大小。

使用 layout="responsive"layout="fill" 時,height 屬性表示_原始_高度(像素),因此只會影響寬高比。

height 屬性是必填的,除非是靜態匯入的圖片,或使用 layout="fill" 的情況。

可選屬性

<Image /> 元件接受許多額外屬性。本節描述 Image 元件最常用的屬性。更多較少使用的屬性詳情請參閱進階屬性一節。

layout

圖片在視窗大小變化時的佈局行為。

layout行為srcSetsizes有包裝和調整器
intrinsic (預設)縮小以適應容器寬度,最大至圖片原始尺寸1x, 2x (基於 imageSizes)N/A
fixed嚴格按照 widthheight 設定尺寸1x, 2x (基於 imageSizes)N/A
responsive縮放以適應容器寬度640w, 750w, ... 2048w, 3840w (基於 imageSizesdeviceSizes)100vw
fill在 X 和 Y 軸上擴展以填充容器640w, 750w, ... 2048w, 3840w (基於 imageSizesdeviceSizes)100vw
  • 示範 intrinsic 佈局 (預設)
    • intrinsic 時,圖片會針對較小的視窗縮小尺寸,但對較大的視窗保持原始尺寸。
  • 示範 fixed 佈局
    • fixed 時,圖片尺寸不會隨視窗變化而改變(無響應性),類似原生 img 元素。
  • 示範 responsive 佈局
    • responsive 時,圖片會針對較小的視窗縮小尺寸,並針對較大的視窗放大尺寸。
    • 確保父元素在樣式表中使用 display: block
  • 示範 fill 佈局
    • fill 時,圖片會拉伸寬度和高度以符合父元素的尺寸,前提是父元素為相對定位。
    • 這通常與 objectFit 屬性搭配使用。
    • 確保父元素在樣式表中使用 position: relative
  • 示範背景圖片

loader

用於解析 URL 的自訂函式。在 Image 元件上設置 loader 屬性會覆蓋 next.config.jsimages 區段中定義的預設 loader。

loader 是一個函式,根據以下參數返回圖片的 URL 字串:

以下是使用自訂 loader 的範例:

import Image from 'next/legacy/image'

const myLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

const MyImage = (props) => {
  return (
    <Image
      loader={myLoader}
      src="me.png"
      alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}

sizes

一個字串,提供有關圖片在不同斷點下寬度的資訊。sizes 的值會極大影響使用 layout="responsive"layout="fill" 的圖片效能。對於使用 layout="intrinsic"layout="fixed" 的圖片則會被忽略。

sizes 屬性對圖片效能有兩個重要作用:

首先,瀏覽器使用 sizes 的值來決定從 next/legacy/image 自動生成的來源集中下載哪個大小的圖片。當瀏覽器選擇時,它還不知道圖片在頁面上的大小,因此會選擇與視窗相同或更大的圖片。sizes 屬性讓您可以告訴瀏覽器圖片實際上會比全螢幕小。如果不指定 sizes 值,則預設使用 100vw(全螢幕寬度)。

其次,sizes 值會被解析並用於修剪自動建立的來源集中的值。如果 sizes 屬性包含如 50vw 這樣的值,表示視窗寬度的百分比,則來源集會被修剪,排除任何可能永遠不需要的過小值。

例如,如果您知道您的樣式會導致圖片在行動裝置上為全寬,在平板電腦上為 2 欄佈局,在桌面上為 3 欄佈局,則應包含如下的 sizes 屬性:

import Image from 'next/legacy/image'
const Example = () => (
  <div className="grid-element">
    <Image
      src="/example.png"
      layout="fill"
      sizes="(max-width: 768px) 100vw,
              (max-width: 1200px) 50vw,
              33vw"
    />
  </div>
)

這個 sizes 範例可能對效能指標有顯著影響。如果沒有 33vw 的 sizes,從伺服器選擇的圖片寬度會是實際需要的 3 倍。由於檔案大小與寬度的平方成正比,沒有 sizes 時,使用者會下載比實際需要大 9 倍的圖片。

了解更多關於 srcsetsizes

quality

最佳化圖片的品質,介於 1100 之間的整數,100 為最佳品質。預設為 75

priority

當設為 true 時,圖片會被視為高優先級並預加載。對於使用 priority 的圖片,懶加載會自動停用。

您應該在檢測為最大內容繪製 (LCP) 元素的任何圖片上使用 priority 屬性。對於不同的視窗大小,不同的圖片可能是 LCP 元素,因此可能需要設定多個優先級圖片。

僅適用於首屏可見的圖片。預設為 false

placeholder

圖片載入時使用的佔位符。可能的值為 blurempty。預設為 empty

當為 blur 時,將使用 blurDataURL 屬性作為佔位符。如果 src靜態匯入的物件,且匯入的圖片為 .jpg.png.webp.avif,則會自動填充 blurDataURL

對於動態圖片,您必須提供 blurDataURL 屬性。可以使用 Plaiceholder 等工具生成 base64

當為 empty 時,圖片載入時不會有佔位符,只有空白空間。

試試看:

進階屬性

在某些情況下,您可能需要更進階的用法。<Image /> 元件可選地接受以下進階屬性。

style

允許傳遞 CSS 樣式給底層的圖片元素。

請注意,所有 layout 模式都會自動應用自己的樣式到圖片元素,這些自動樣式會優先於 style 屬性。

還要注意,必要的 widthheight 屬性可能會與您的樣式互動。如果使用樣式修改圖片的 width,則必須同時設置 height="auto" 樣式,否則圖片會變形。

objectFit

定義在使用 layout="fill" 時,圖片如何適應其父容器。

此值傳遞給 src 圖片的 object-fit CSS 屬性

objectPosition

定義在使用 layout="fill" 時,圖片在其父元素中的定位方式。

此值傳遞給應用於圖片的 object-position CSS 屬性

onLoadingComplete

一個回調函式,在圖片完全載入且佔位符被移除後調用。

onLoadingComplete 函式接受一個參數,一個包含以下屬性的物件:

loading

注意:此屬性僅用於進階用途。將圖片切換為 eager 加載通常會損害效能

我們建議改用 priority 屬性,它在幾乎所有使用情況下都能正確地積極加載圖片。

圖片的加載行為。預設為 lazy

當為 lazy 時,延遲加載圖片直到它到達與視窗的計算距離。

當為 eager 時,立即加載圖片。

了解更多

blurDataURL

一個 Data URL,在 src 圖片成功載入前作為佔位圖片使用。僅與 placeholder="blur" 結合時有效。

必須是 base64 編碼的圖片。它會被放大和模糊處理,因此建議使用非常小的圖片(10px 或更小)。包含較大的圖片作為佔位符可能會損害應用程式效能。

試試看:

您也可以生成純色 Data URL 來匹配圖片。

lazyBoundary

一個字串(語法類似 margin 屬性),用作檢測視窗與圖片交集並觸發懶加載的邊界框。預設為 "200px"

如果圖片嵌套在根文件以外的可滾動父元素中,您還需要指定 lazyRoot 屬性。

了解更多

lazyRoot

一個 React Ref,指向可滾動的父元素。預設為 null(文件視窗)。

Ref 必須指向一個 DOM 元素或一個將 Ref 轉發到底層 DOM 元素的 React 元件。

指向 DOM 元素的範例

import Image from 'next/legacy/image'
import React from 'react'

const Example = () => {
  const lazyRoot = React.useRef(null)

  return (
    <div ref={lazyRoot} style={{ overflowX: 'scroll', width: '500px' }}>
      <Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
      <Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
    </div>
  )
}

指向 React 元件的範例

import Image from 'next/legacy/image'
import React from 'react'

const Container = React.forwardRef((props, ref) => {
  return (
    <div ref={ref} style={{ overflowX: 'scroll', width: '500px' }}>
      {props.children}
    </div>
  )
})

const Example = () => {
  const lazyRoot = React.useRef(null)

  return (
    <Container ref={lazyRoot}>
      <Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
      <Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
    </Container>
  )
}

了解更多

unoptimized

當設定為 true 時,原始圖片將以原樣提供,不會改變品質、大小或格式。預設值為 false

import Image from 'next/image'

const UnoptimizedImage = (props) => {
  return <Image {...props} unoptimized />
}

自 Next.js 12.3.0 起,可以透過更新 next.config.js 並加入以下配置,將此屬性套用至所有圖片:

next.config.js
module.exports = {
  images: {
    unoptimized: true,
  },
}

其他屬性

<Image /> 元件的其他屬性將傳遞給底層的 img 元素,但以下屬性除外:

配置選項

遠端模式 (Remote Patterns)

為保護您的應用程式免受惡意使用者攻擊,使用外部圖片時需要進行配置。這確保只有來自您帳戶的外部圖片可以透過 Next.js 圖片最佳化 API 提供。這些外部圖片可以在 next.config.js 檔案中透過 remotePatterns 屬性進行配置,如下所示:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        port: '',
        pathname: '/account123/**',
        search: '',
      },
    ],
  },
}

須知:以上範例將確保 next/legacy/imagesrc 屬性必須以 https://example.com/account123/ 開頭,且不能有查詢字串。任何其他協定、主機名稱、連接埠或不匹配的路徑將返回 400 Bad Request。

以下是 next.config.js 檔案中使用 hostname 萬用字元模式的 remotePatterns 屬性範例:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
        port: '',
        search: '',
      },
    ],
  },
}

須知:以上範例將確保 next/legacy/imagesrc 屬性必須以 https://img1.example.comhttps://me.avatar.example.com 或任何數量的子網域開頭。不能有連接埠或查詢字串。任何其他協定或不匹配的主機名稱將返回 400 Bad Request。

萬用字元模式可用於 pathnamehostname,並具有以下語法:

  • * 匹配單一路徑段或子網域
  • ** 匹配任意數量的路徑段(在結尾)或子網域(在開頭)

** 語法不能在模式的中間使用。

須知:當省略 protocolportpathnamesearch 時,將隱含使用萬用字元 **。這不建議使用,因為它可能允許惡意使用者最佳化您無意允許的 URL。

以下是 next.config.js 檔案中使用 searchremotePatterns 屬性範例:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'assets.example.com',
        search: '?v=1727111025337',
      },
    ],
  },
}

須知:以上範例將確保 next/legacy/imagesrc 屬性必須以 https://assets.example.com 開頭,且必須具有確切的查詢字串 ?v=1727111025337。任何其他協定或查詢字串將返回 400 Bad Request。

網域 (Domains)

警告:自 Next.js 14 起已棄用,建議改用嚴格的 remotePatterns 以保護您的應用程式免受惡意使用者攻擊。僅在您擁有該網域提供的所有內容時使用 domains

remotePatterns 類似,domains 配置可用於提供允許的外部圖片主機名稱列表。

然而,domains 配置不支援萬用字元模式匹配,且無法限制協定、連接埠或路徑名稱。

以下是 next.config.js 檔案中的 domains 屬性範例:

next.config.js
module.exports = {
  images: {
    domains: ['assets.acme.com'],
  },
}

載入器配置 (Loader Configuration)

如果您想使用雲端供應商來最佳化圖片,而不是使用 Next.js 內建的圖片最佳化 API,您可以在 next.config.js 檔案中配置 loaderpath 前綴。這允許您為圖片的 src 使用相對 URL,並自動為您的供應商生成正確的絕對 URL。

next.config.js
module.exports = {
  images: {
    loader: 'imgix',
    path: 'https://example.com/myaccount/',
  },
}

內建載入器 (Built-in Loaders)

以下圖片最佳化雲端供應商已包含:

  • 預設:自動適用於 next devnext start 或自訂伺服器
  • Vercel:部署在 Vercel 時自動適用,無需配置。了解更多
  • Imgixloader: 'imgix'
  • Cloudinaryloader: 'cloudinary'
  • Akamailoader: 'akamai'
  • 自訂:loader: 'custom' 透過在 next/legacy/image 元件上實作 loader 屬性來使用自訂雲端供應商

如果您需要其他供應商,可以使用 next/legacy/imageloader 屬性。

使用 output: 'export' 時,圖片無法在構建時最佳化,僅能按需最佳化。要將 next/legacy/imageoutput: 'export' 一起使用,您需要使用非預設的載入器。詳見討論。

next/legacy/image 元件的預設載入器使用 squoosh,因為它安裝快速且適合開發環境。在生產環境中使用 next start 時,強烈建議您透過在專案目錄中執行 npm i sharp 來安裝 sharp。Vercel 部署無需此操作,因為 sharp 會自動安裝。

進階

以下配置適用於進階使用情境,通常不需要。如果您選擇配置以下屬性,將覆蓋未來更新中 Next.js 預設值的任何變更。

裝置尺寸 (Device Sizes)

如果您知道使用者的預期裝置寬度,可以在 next.config.js 中使用 deviceSizes 屬性指定裝置寬度斷點列表。當 next/legacy/image 元件使用 layout="responsive"layout="fill" 時,這些寬度將用於確保為使用者的裝置提供正確的圖片。

如果未提供配置,則使用以下預設值:

next.config.js
module.exports = {
  images: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  },
}

圖片尺寸 (Image Sizes)

您可以在 next.config.js 檔案中使用 images.imageSizes 屬性指定圖片寬度列表。這些寬度與 裝置尺寸 陣列連接,形成用於生成圖片 srcset 的完整尺寸陣列。

之所以有兩個獨立的列表,是因為 imageSizes 僅用於提供 sizes 屬性的圖片,這表示圖片小於螢幕的完整寬度。因此,imageSizes 中的尺寸應全部小於 deviceSizes 中的最小尺寸。

如果未提供配置,則使用以下預設值:

next.config.js
module.exports = {
  images: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}

可接受的格式 (Acceptable Formats)

預設的 圖片最佳化 API 會透過請求的 Accept 標頭自動檢測瀏覽器支援的圖片格式。

如果 Accept 標頭匹配多個配置的格式,則使用陣列中的第一個匹配項。因此,陣列順序很重要。如果沒有匹配(或原始圖片是 動畫),圖片最佳化 API 將回退到原始圖片的格式。

如果未提供配置,則使用以下預設值:

next.config.js
module.exports = {
  images: {
    formats: ['image/webp'],
  },
}

您可以透過以下配置啟用 AVIF 支援:

next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
}

須知:AVIF 通常比 WebP 多花 20% 的時間編碼,但壓縮率比 WebP 小 20%。這意味著首次請求圖片時通常會較慢,但後續快取的請求會較快。

快取行為

以下描述預設 載入器 的快取演算法。對於所有其他載入器,請參考您的雲端供應商的文件。

圖片在請求時動態最佳化,並儲存在 <distDir>/cache/images 目錄中。最佳化的圖片檔案將用於後續請求,直到過期為止。當請求匹配到已快取但已過期的檔案時,會立即提供過期的圖片(稱為「過期但仍有效」)。然後圖片會在背景重新最佳化(也稱為重新驗證),並以新的過期日期儲存到快取中。

可以透過讀取 x-nextjs-cache(部署在 Vercel 時為 x-vercel-cache)回應標頭的值來確定圖片的快取狀態。可能的值如下:

  • MISS - 路徑不在快取中(最多發生一次,在首次訪問時)
  • STALE - 路徑在快取中但已超過重新驗證時間,因此將在背景更新
  • HIT - 路徑在快取中且未超過重新驗證時間

過期時間(或稱最大存留時間)由 minimumCacheTTL 配置或上游圖片的 Cache-Control 標頭中的較大者定義。具體來說,使用 Cache-Control 標頭的 max-age 值。如果同時找到 s-maxagemax-age,則優先使用 s-maxagemax-age 也會傳遞給任何下游客戶端,包括 CDN 和瀏覽器。

  • 您可以配置 minimumCacheTTL 以在上游圖片不包含 Cache-Control 標頭或值非常低時增加快取時間。
  • 您可以配置 deviceSizesimageSizes 以減少可能生成的圖片總數。
  • 您可以配置 格式 以停用多種格式,僅使用單一圖片格式。

最小快取 TTL (Minimum Cache TTL)

您可以為快取的最佳化圖片配置存留時間(TTL,單位:秒)。在許多情況下,最好使用 靜態圖片匯入,它會自動對檔案內容進行雜湊處理,並以 Cache-Control 標頭 immutable 永久快取圖片。

next.config.js
module.exports = {
  images: {
    minimumCacheTTL: 60,
  },
}

最佳化圖片的過期時間(或稱最大存留時間)由 minimumCacheTTL 或上游圖片的 Cache-Control 標頭中的較大者定義。

如果需要按圖片變更快取行為,可以配置 headers 在上游圖片(例如 /some-asset.jpg,而非 /_next/image 本身)上設定 Cache-Control 標頭。

目前沒有機制可以手動使快取失效,因此最好將 minimumCacheTTL 設定為較低的值。否則,您可能需要手動變更 src 屬性或刪除 <distDir>/cache/images

停用靜態匯入 (Disable Static Imports)

預設行為允許您匯入靜態檔案,例如 import icon from './icon.png',然後將其傳遞給 src 屬性。

在某些情況下,如果與其他預期匯入行為不同的外掛衝突,您可能希望停用此功能。

您可以在 next.config.js 中停用靜態圖片匯入:

next.config.js
module.exports = {
  images: {
    disableStaticImages: true,
  },
}

危險允許 SVG (Dangerously Allow SVG)

預設 載入器 不會最佳化 SVG 圖片,原因如下:首先,SVG 是一種向量格式,意味著可以無損調整大小。其次,SVG 具有許多與 HTML/CSS 相同的功能,如果沒有適當的 內容安全政策 (CSP) 標頭,可能導致安全漏洞。

因此,當 src 屬性已知為 SVG 時,建議使用 unoptimized 屬性。當 src".svg" 結尾時,這會自動發生。

但是,如果您需要使用預設的圖片最佳化 API 提供 SVG 圖片,可以在 next.config.js 中設定 dangerouslyAllowSVG

next.config.js
module.exports = {
  images: {
    dangerouslyAllowSVG: true,
    contentDispositionType: 'attachment',
    contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
  },
}

此外,強烈建議同時設定 contentDispositionType 以強制瀏覽器下載圖片,以及 contentSecurityPolicy 以防止嵌入在圖片中的腳本執行。

動畫圖片 (Animated Images)

預設 載入器 會自動繞過動畫圖片的圖片最佳化,並以原樣提供圖片。

對動畫檔案的自動檢測是盡力而為的,支援 GIF、APNG 和 WebP。如果您想明確繞過特定動畫圖片的圖片最佳化,請使用 unoptimized 屬性。

版本歷史

版本變更
v13.0.0next/image 更名為 next/legacy/image