跳至內容

圖片最佳化 (Image Optimization)

範例

根據 Web Almanac 的數據,圖片佔據了典型網站 頁面大小 的很大一部分,並且會對您網站的 LCP 效能 產生相當大的影響。

Next.js 的 Image 元件擴展了 HTML <img> 元素,並加入了自動圖片優化的功能。

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

🎥 觀看影片: 了解更多關於如何使用 next/image 的資訊 → YouTube (9 分鐘)

用法

import Image from 'next/image'

您可以接著定義圖片的 src(本地或遠端)。

本地圖片

要使用本地圖片,請 `import` 您的 `.jpg`、`.png` 或 `.webp` 圖片檔案。

Next.js 會根據匯入的檔案 自動判斷 圖片的原始 `width` 和 `height`。這些值用於確定圖片比例,並在圖片載入時防止 累積版面偏移 (CLS)

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/**',
      },
    ],
  },
}

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

網域

深入瞭解 remotePatterns 設定。

載入器 先前的範例中,為本地圖片提供了部分 URL ("/me.png")。這是由於載入器架構才得以實現。

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

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

您可以使用 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 元件說明文件 中查看更多關於優先順序的資訊。

圖片大小調整

圖片最常損害效能的方式之一是透過 *版面偏移 (layout shift)*,也就是圖片在載入時會將頁面上的其他元素推擠。這個效能問題對使用者來說非常惱人,它甚至有一個自己的核心網頁指標,稱為累積版面偏移 (Cumulative Layout Shift)。避免圖片造成版面偏移的方法是永遠設定圖片尺寸。這讓瀏覽器可以在圖片載入之前預留足夠的空間。

由於 next/image 的設計旨在確保良好的效能,因此它的使用方式不能導致版面偏移,而且**必須**透過以下三種方式之一設定尺寸:

  1. 自動設定,使用靜態匯入
  2. 手動設定,透過加入用於決定圖片長寬比的 widthheight 屬性。
  3. 隱式設定,使用 fill 屬性,使圖片擴展以填滿其父元素。

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

如果您從來源存取圖片但不知道圖片的尺寸,您可以執行以下幾項操作:

使用 fill

fill 屬性允許圖片根據其父元素調整大小。您可以考慮使用 CSS 為圖片的父元素在頁面上分配空間,並搭配 sizes 屬性來匹配任何媒體查詢斷點。您也可以搭配 fillcontaincover 使用 object-fit,並使用 object-position 來定義圖片應如何佔據該空間。

標準化您的圖片

如果您從您控制的來源提供圖片,請考慮修改您的圖片處理流程,將圖片標準化為特定尺寸。

修改您的 API 呼叫

如果您的應用程式是使用 API 呼叫(例如呼叫 CMS)來擷取圖片網址,您可以修改 API 呼叫,使其連同圖片尺寸一起傳回網址。

如果上述建議的方法都無法調整圖片尺寸,next/image 元件的設計使其可以與標準的 <img> 元素在頁面上良好地搭配使用。

樣式

設定 Image 元件樣式與設定一般 <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>
  )
}

填滿容器
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',
      }}
    />
  )
}

關於 Image 元件搭配各種樣式的範例,請參閱 Image 元件展示

其他屬性

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

設定

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

請閱讀完整的圖片設定文件以了解更多資訊。