<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 尺寸時,從伺服器選擇的圖片會是所需寬度的 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/**',
      },
    ],
  },
}

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

以下是 next.config.js 檔案中 remotePatterns 屬性的另一個範例:

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

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

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

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

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

網域 (Domains)

警告:為保護應用程式免受惡意使用者攻擊,建議配置嚴格的 remotePatterns 而非 domains。僅在您擁有該網域提供的所有內容時才使用 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/image 上使用 loader 屬性。

使用 output: 'export' 時,圖片無法在建置時優化,僅能按需優化。要在 output: 'export' 中使用 next/legacy/image,需使用非預設的載入器。詳見討論。

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%。這意味著首次請求圖片時通常會較慢,但後續的快取請求會較快。

快取行為 (Caching Behavior)

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

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

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

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

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

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

最小快取 TTL (Minimum Cache TTL)

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

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

優化圖片的過期時間(或稱 Max Age)由 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) 標頭,可能導致安全漏洞。

如果需要透過預設的圖片優化 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