圖片最佳化
範例
根據 Web Almanac,圖片佔典型網站的 頁面大小 很大部分,並可能對網站的 LCP 效能 產生顯著影響。
Next.js 圖片元件擴充了 HTML <img>
元素,具備自動圖片最佳化功能
- 大小最佳化:自動提供針對每個裝置正確大小的圖片,使用 WebP 和 AVIF 等現代圖片格式。
- 視覺穩定性:在圖片載入時自動防止 版面偏移。
- 更快的頁面載入:圖片僅在進入視窗時載入,使用原生瀏覽器延遲載入,並提供模糊的暫存區塊。
- 資產彈性:依據需求調整影像大小,即使是儲存在遠端伺服器的影像
🎥 觀看:深入了解如何使用
next/image
→ YouTube(9 分鐘).
用法
import Image from 'next/image'
接著,您可以定義影像的 src
(本機或遠端)。
本機影像
若要使用本機影像,請 import
您的 .jpg
、.png
或 .webp
影像檔案。
Next.js 會 自動判斷 您影像的 width
和 height
,根據匯入的檔案。這些值用於防止 累積佈局偏移 在影像載入時發生。
import Image from 'next/image'
import profilePic from './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
必須是靜態的,以便可以在建置時進行分析。
遠端影像
若要使用遠端影像,src
屬性應為 URL 字串。
由於 Next.js 在建置過程中無法存取遠端檔案,因此您需要手動提供 width
、height
和選用的 blurDataURL
屬性。
width
和 height
屬性用於推斷影像的正確長寬比,並避免影像載入時發生版面位移。width
和 height
不會決定影像檔案的渲染大小。深入了解 影像大小調整。
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 儲存貯體的影像
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
},
],
},
}
深入了解 remotePatterns
設定。如果您想對影像 src
使用相對 URL,請使用 loader
。
網域
有時您可能想要最佳化遠端影像,但仍使用內建的 Next.js 影像最佳化 API。為此,請將 loader
保留為其預設設定,並為影像 src
屬性輸入絕對 URL。
若要保護您的應用程式免於惡意使用者,您必須定義打算與 next/image
元件一起使用的遠端主機名稱清單。
深入了解
remotePatterns
設定。
載入器
請注意,在 先前的範例 中,為本地影像提供了部分 URL("/me.png"
)。這是因為載入器架構而可能的。
載入器是一個用來產生圖片網址的函式。它會修改提供的 src
,並產生多個網址來要求不同大小的圖片。這些多個網址會用於自動 srcset 產生,以便網站訪客會收到符合其視窗大小的圖片。
Next.js 應用程式的預設載入器使用內建的圖片最佳化 API,它會最佳化來自網路任何地方的圖片,然後直接從 Next.js 網路伺服器提供圖片。如果你想要直接從 CDN 或圖片伺服器提供圖片,你可以用幾行 JavaScript 撰寫自己的載入器函式。
你可以使用 loader
prop 為每個圖片定義載入器,或使用 loaderFile
設定 在應用程式層級定義載入器。
優先順序
你應該將 priority
屬性新增到每個頁面的 最大內容繪製 (LCP) 元素 的圖片。這麼做可讓 Next.js 特別優先載入圖片(例如透過預載入標籤或優先提示),從而大幅提升 LCP。
LCP 元素通常是頁面視窗中可見的最大影像或文字區塊。執行 next dev
時,如果 LCP 元素是沒有 priority
屬性的 <Image>
,你會在主控台中看到警告訊息。
找出 LCP 影像後,你可以這樣新增屬性
import Image from 'next/image'
import profilePic from '../public/me.png'
export default function Page() {
return <Image src={profilePic} alt="Picture of the author" priority />
}
在 next/image
元件文件 中查看更多關於優先順序的資訊。
影像大小
影像最常損害效能的方式之一是透過版面偏移,其中影像在載入時會將頁面上的其他元素推擠開來。這個效能問題對使用者來說非常惱人,因此它有自己的核心網路指標,稱為 累計版面偏移。避免基於影像的版面偏移的方法是 始終調整影像大小。這允許瀏覽器在載入影像之前為其保留足夠的空間。
由於 next/image
旨在保證良好的效能結果,因此不能以會導致版面偏移的方式使用,且必須以三種方式之一調整大小
如果我不知道影像大小怎麼辦?
如果你從不知道影像大小的來源存取影像,你可以執行下列幾項操作
使用
fill
fill
屬性允許影像由其父元素調整大小。請考慮使用 CSS 為影像的父元素在頁面上提供空間,並搭配sizes
屬性,以符合任何媒體查詢中斷點。您也可以搭配fill
使用object-fit
(填滿、包含或覆蓋),以及object-position
來定義影像應如何佔用該空間。標準化您的影像
如果您從您控制的來源提供影像,請考慮修改您的影像管線,以將影像標準化為特定大小。
修改您的 API 呼叫
如果您的應用程式使用 API 呼叫(例如,對 CMS)擷取影像網址,您可能可以修改 API 呼叫,以傳回影像尺寸和網址。
如果建議的方法都不適用於調整影像大小,next/image
元件設計為可以在頁面上與標準 <img>
元素搭配使用。
樣式
設定 Image 元件的樣式類似於設定一般 <img>
元素的樣式,但有幾個準則需要記住
- 使用
className
或style
,而不是styled-jsx
。- 在大多數情況下,我們建議使用
className
屬性。這可以是匯入的 CSS 模組、全域樣式表 等。 - 您也可以使用
style
屬性指定內嵌樣式。 - 您無法使用 styled-jsx,因為它限定於目前的組件(除非您將樣式標記為
global
)。
- 在大多數情況下,我們建議使用
- 使用
fill
時,父元素必須具有position: relative
- 這是為了在該佈局模式中正確呈現影像元素。
- 使用
fill
時,父元素必須具有display: block
- 這是
<div>
元素的預設值,但應另行指定。
- 這是
範例
回應式


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>
)
}
背景影像


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 組件示範
這有幫助嗎?