javascript

Next.js Image 指南:sizes、fill 和远程图片

基于当前 Next.js Image 官方文档,解释 width/height、fill、sizes、preload、placeholder、remotePatterns 的作用,以及哪些旧教程里的 layout、objectFit 写法已经不该继续照搬。

·更新于 ·阅读约 12 分钟·计算中...
Next.js Image 指南:sizes、fill 和远程图片

现在写 Next.js Image,最容易踩坑的不是“怎么显示图片”,而是拿旧教程里的 layout="responsive"layout="fill"objectFit 直接照搬。当前官方文档已经把 API 重心放在 widthheightfillsizespreloadremotePatterns 上,很多老示例已经过时。

目录

先理解 Image 帮你做了什么

官方文档把 Image 定义成对原生 <img> 的扩展,用于自动图片优化。它的核心价值是:

  • 根据设备生成更合适的图片尺寸
  • 减少布局抖动
  • 支持懒加载与占位图
  • 统一本地与远程图片的处理方式

但它不会自动替你决定:

  • 哪张图该优先加载
  • 哪些图需要响应式 sizes
  • 远程源是否可信

最基础的固定尺寸写法

import Image from "next/image"

export default function Avatar() {
  return (
    <Image
      src="/images/avatar.png"
      alt="作者头像"
      width={160}
      height={160}
    />
  )
}

当前官方文档强调:widthheight 表示图片的固有尺寸,用来帮助浏览器预留比例、减少布局偏移。它们不是最终显示大小的唯一控制源,真正的渲染尺寸还会受 CSS 影响。

fill 什么时候用

如果你不知道图片的固定宽高,或者它必须铺满父容器,用 fill

<div className="relative h-64 w-full">
  <Image
    src="/images/hero.jpg"
    alt="首页横幅"
    fill
    sizes="100vw"
    style={{ objectFit: "cover" }}
  />
</div>

这里有两个关键点,都是官方文档明确要求的:

  • 父元素必须有定位,比如 relative
  • 使用 fill 时通常应该写 sizes

为什么 sizes 很重要

这是 Next.js Image 最容易被漏掉、但又最影响真实性能的点。

<Image
  fill
  src="/images/card-cover.jpg"
  alt="文章封面"
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  style={{ objectFit: "cover" }}
/>

根据当前官方文档:

  • fill 场景应该写 sizes
  • 如果缺少 sizes,浏览器会假定图片接近 100vw
  • 这可能导致下载比实际需要更大的资源

所以 sizes 不是装饰项,而是响应式图片真正省流量的关键。

旧教程里最该停掉的写法

1. layout="responsive" / layout="fill"

这是旧 API 风格。当前 Image 文档已经改为:

  • 固定尺寸:width + height
  • 铺满容器:fill

2. objectFit / objectPosition 直接当组件 prop 写

现在更推荐通过 style 或 class 控制:

<Image
  fill
  src="/images/banner.jpg"
  alt="Banner"
  style={{ objectFit: "cover", objectPosition: "center" }}
/>

3. 把 priority 当成所有首屏图默认开关

当前官方文档已经把 preload 列为主要 prop,而 priority 不再是唯一心智入口。真正重要的是:只有极少数 LCP 关键图值得优先加载。

preload、loading 和 placeholder

preload

首屏最关键的大图可以考虑:

<Image
  src="/images/hero.jpg"
  alt="首页主视觉"
  width={1440}
  height={720}
  preload
/>

不要给列表里每张图片都开 preload,否则会和优化目标相反。

loading

普通内容图通常保持默认懒加载就够,只有你明确知道某张图必须更早加载时才去改。

placeholder 与 blurDataURL

<Image
  src="/images/cover.jpg"
  alt="文章封面"
  width={1200}
  height={630}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>

适合封面图、详情页主图这类“加载前空白会很突兀”的场景。

远程图片别忘了 remotePatterns

如果 src 是外部 URL,当前官方文档要求把来源加入 remotePatterns 配置,而不是像旧项目那样只配 domains

这点本质上是安全边界:你要明确哪些远程源允许被优化管线抓取。

什么时候该用 unoptimized

官方文档提到一个容易被忽略的细节:默认优化 loader 抓远程图片时不会转发请求头。如果图片源需要鉴权,直接走默认优化可能拿不到资源。

这时可以评估:

  • 是否改成公开可访问图片
  • 是否改成自己代理
  • 是否临时用 unoptimized

unoptimized 不是性能最佳实践,而是“我明确知道这里不走默认优化”的选择。

一个更贴近真实项目的模式

文章封面:

<Image
  src={coverImage}
  alt={title}
  width={1200}
  height={630}
  sizes="(max-width: 768px) 100vw, 720px"
  style={{ width: "100%", height: "auto" }}
/>

卡片缩略图:

<div className="relative aspect-[16/9] overflow-hidden rounded-xl">
  <Image
    src={thumbnail}
    alt={title}
    fill
    sizes="(max-width: 768px) 100vw, 33vw"
    style={{ objectFit: "cover" }}
  />
</div>

如果你正在同时处理路由结构和服务端组件边界,配合看 Next.js 路由指南Next.js Server / Client Components 指南 会更完整。

结论

  • 新版 Image 的主心智是 width/heightfillsizes 和可信远程源配置。
  • fill 几乎总该和 sizes 一起考虑。
  • 旧教程里的 layout 写法不应该继续照搬。
  • preloadplaceholderunoptimized 都是场景化选项,不是默认全开。

参考资料

18 分钟

理解与掌控副作用:前端开发(Vue 3 和 React)中的关键环节

在现代前端开发中,副作用(Side Effects)是一个经常被提到的概念。它指的是那些在执行计算或操作时,不仅影响当前函数的输出,还可能对外部世界产生某些影响的操作。常见的副作用包括:数据请求、事件监听、定时器、DOM 操作等。处理副作用是前端开发中非常重要的一部分,尤其是在构

8 分钟

Vue 3 响应式:ref、reactive 和 toRefs 怎么选

围绕基本类型、对象、解构丢失响应性这三个高频问题,解释 Vue 3 里什么时候用 ref,什么时候用 reactive,以及 toRefs 到底解决什么。

13 分钟

深入理解 DOM 和 CSSOM:网页渲染的核心

DOM 是浏览器用于表示网页内容和结构的对象模型。它将网页的 HTML 或 XML 文档表示为一个树形结构,每个部分(如元素、文本和属性)都成为一个节点。通过 JavaScript,开发者可以操作这些节点,从而动态地修改页面的内容和结构。CSSOM 是浏览器用来表示 CSS 样式

订阅 FreeMac

每周精选:免费 Mac 软件评测、可信来源更新、替代方案和少折腾指南。