深入掌握 Next.js<Image />组件:图片优化、属性详解与实战配置
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
导读:本文以 Next.js 内置的图片优化能力为主题,系统讲解
next/image的<Image />组件在静态/远程图片场景下的用法、全部核心属性、next.config.js配置项,并结合本仓库examples/with-nextjs示例项目(基于 Next.js 14 与 App Router)进行落地验证。读完本文,你将能独立完成图片格式选型、尺寸适配、懒加载与预加载、占位图、自定义 loader、外链域名白名单等全套图片优化实践,显著改善页面加载性能、CLS 指标与 SEO 表现。
一、为什么要在 Next.js 中专门优化图片
图片是现代 Web 应用的重要组成部分,用得恰当与否,直接影响开发者与终端用户体验。图片既影响用户体验,也在合理使用的前提下深刻影响搜索引擎优化(SEO)排名——Google 在排名时会将页面加载时间作为考量因素,更快的页面往往获得更靠前的排名。
传统上,图片通过 HTML 的img标签添加到页面中。对于简单场景这或许足够,但当面对大量图片时,事情很快就会变得难以管理:你需要手动处理不同设备尺寸、格式兼容、懒加载、占位图等一系列问题。
Next.js 从 v10 开始引入了内置解决方案:全新的<Image />组件与自动图片优化能力。本文后续章节将逐步讲解如何利用这一方案构建高性能应用。在本仓库中,你可以直接查看 examples/with-nextjs/package.json,其dependencies中声明了"next": "^14.2.26"、"react": "^19.1.0",这是当前仓库所验证的 Next.js 版本环境;<Image />组件在 App Router 与 Pages Router 下均可使用。
二、优化前的图片准备工作
在深入使用<Image />组件之前,先做好图片本身的准备工作,才能达到最优性能。如果处理的是动态且数量庞大的图片,可以考虑使用 CDN 托管图片。CDN 提供自动缓存、文件压缩与实时缩放等图片与应用性能优势。
以下是面向终端用户提供图片前应该考虑的非穷尽清单:
1. 选择正确的格式
Web 上最流行的三种图片格式是 JPEG、PNG 与 WebP。三者之中,WebP 因其诸多优势与性能收益而被强烈推荐。
WebP 是一种现代图片格式,在不牺牲画质的前提下为 Web 图片提供优越的有损与无损压缩,加载更快且被主流浏览器广泛支持。
2. 调整图片尺寸
按设备尺寸提供正确的图片是 Web 图片优化的关键一环。向只有 100x100 显示尺寸的用户下发一张 1080x800 的大图,会让用户下载不必要的带宽,拖慢页面加载并损害性能指标。建议针对不同屏幕尺寸生成多份图片文件。
3. 压缩图片
图片优化的经验法则是将图片控制在 1MB 以下。在不过度损失画质的前提下,将大文件压缩到合理阈值。手动优化完成后,就可以放心地使用 Next.js<Image />组件来获取最大化的图片优化收益了。
在本仓库的 examples/with-nextjs/public 目录中,可以看到示例项目仅保留了
favicon.ico这类必要静态资源,图片类资源通常放在public目录下供next/image静态导入使用——这也是官方推荐的资源组织方式。
三、认识 Next.js<Image />组件
<Image />组件是为 Next.js 应用提供图片服务的开箱即用现代方案。它与原生 HTML<img />元素类似,但有几点区别。
两者最大的区别在于:Next.js<Image />组件开箱即用地提供图片优化与性能收益,以及若干其他实用特性。<Image />组件的用法与 Next.js 中其他组件一致,可根据需求重复使用。它的核心优化能力包括:
- 自动懒加载:默认对首屏以下图片进行懒加载;
- 关键图片预加载:通过
priority属性预加载首屏关键图片; - 自动多尺寸适配:自动生成
srcSet,按视口下发合适尺寸; - 现代格式支持:自动输出 WebP 等压缩率更高的现代格式;
- 防布局偏移:自动生成/要求宽高,避免 Cumulative Layout Shift(CLS)。
四、使用<Image />组件
4.1 基本用法与静态图片导入
首先从next/image导入<Image />组件:
import Image from "next/image";然后即可像使用其他组件一样使用它:
import Image from "next/image"; import profilePic from "../public/profile.webp"; const Profile = () => { return ( <> <h1> User Profile </h1> <Image src={profilePic} alt="user profile picture" /> </> ); };值得注意的是,对于静态导入的图片,next/image会自动生成width、height与blurDataURL值。这些值被用来在图片最终加载完成前防止 Cumulative Layout Shift(CLS)。当然,也可以显式传入这些值。
4.2 远程图片:绝对与相对 URL
也可以向src属性传入远程图片字符串,支持相对或绝对 URL:
import Image from "next/image"; const Profile = () => { return ( <> <h1> User Profile </h1> <Image // Absolute URL src="https://unsplash.com/photos/XV1qykwu82c" alt="User profile picture" width={300} height={300} /> </> ); };注意:使用远程图片时必须始终为图片组件添加
width和height属性。因为 Next.js 无法在构建期确定图片的尺寸,缺少宽高会导致页面渲染时发生布局偏移。
对于相对的外部 URL 字符串(如user.png),需要在next.config.js中进行domains配置,提供允许的主机名列表,防止恶意用户滥用外部 URL。下文将详细讲解domains的配置方式。
五、<Image />组件属性全景
<Image />组件接受多种属性来增强性能。总体上可分为三类:必需属性(required)、可选属性(optional)与高级属性(advanced)。下面逐一展开。
5.1 必需属性
<Image />组件最基础的使用需要三种属性:src、width与height。
src
src属性接受两类值:静态导入的本地图片对象,或指向外部图片的绝对/相对 URL 路径字符串。前文示例中已经演示了从public目录导入本地静态图片、以及传入绝对 URL 字符串两种方式。
width与height
width与height属性决定图片在页面上占据的空间大小,或相对其容器的缩放比例。它们可以表示图片的渲染尺寸或原始尺寸,具体取决于layout属性的取值:
- 使用
layout="intrinsic"或layout="fixed"时,width与height表示图片的渲染宽高(像素),直接影响图片显示的大小; - 使用
layout="responsive"或layout="fill"时,width与height表示图片的原始像素尺寸,因此影响的是宽高比(即图片相对容器的缩放程度)。
5.2 可选属性
layout
接受一个字符串值,决定图片如何响应视口尺寸变化。默认值为intrinsic,共有四个可选值:
intrinsic——layout属性的默认值。给予图片足够的空间,按其原始宽高渲染。fixed—— 将图片尺寸固定为width与height属性的精确值。生成带 1x 与 2x 像素密度描述符的srcSet。fill—— 使图片在宽高两个方向上都扩展以填满父元素的宽高。需要确保父元素设置了position: relative。该值通常与objectFit属性搭配使用,推荐用于事先不知道尺寸的图片场景。responsive—— 将图片缩放到适配其父容器的宽度。需要确保父容器设置了display: block。
loader
一个自定义函数,用于解析外部图片 URL。可以作为属性传入,也可以在next.config.js的images部分设置。作为属性内联使用时,它会覆盖next.config.js中定义的 loader。该函数将src、width与quality参数解析为外部图片的 URL 路径字符串:
import Image from "next/image"; const customLoader = ({ src, width, quality }) => { return `https://s3.amazonaws.com/demo/image/${src}?w=${width}&q=${ quality || 75 }`; }; const MyImage = (props) => { return ( <Image src="profilePic.webp" // 将被解析为: https://s3.amazonaws.com/demo/image/profilePic.webp?width=300&q=80 width={300} height={300} alt="User profile picture" quality={80} loader={customLoader} /> ); };placeholder
定义原图完全加载前使用的占位内容。可选值为blur或empty,默认empty。
- 为
empty时,原图加载完成前显示空白空间; - 为
blur时,使用blurDataURL值作为占位图。如果src是静态导入的图片且格式为.jpg、.png、.webp、.avif之一,会自动生成一张模糊占位图作为blurDataURL的值:
import Image from "next/image"; import cat from "../public/cat.webp"; <Image src={cat} alt="A picture of white cats" width={500} height={450} placeholder="blur" />;说明:原文档中提到的格式列表为
.jpg、.png、.webp与.avf,其中.avf应为.avif——Next.js 的自动占位图生成针对的是 WebP、AVIF 等静态导入的位图格式。
priority
此属性对首屏可见(即无需滚动即可看到的页面部分)的图片特别有用。落地页等首屏图片应使用priority属性以获取性能提升:它告诉浏览器将图片视为高优先级进行预加载。使用priority的图片会自动禁用懒加载。该属性接受布尔值,默认false:
<Image src="user.webp" alt="User profile photo" width={300} height={300} priority />quality
一个整数,指定优化后图片的质量。取值范围1到100,100为最佳质量,默认75:
<Image src="user.webp" alt="User profile photo" width={300} height={300} quality={80} />sizes
显著降低 Cumulative Layout Shift 的一个有效方式是按响应式尺寸提供图片:这能让浏览器在图片完全加载前就为其分配足够的空间,避免扭曲页面布局。
next/image的一大特性是自动生成 source set:Next.js 可以在内部生成不同尺寸的图片,并为特定视口尺寸决定下载其中哪一个。
next/image使用next.config.js中的deviceSizes与imageSizes属性生成srcSet,以改进图片投递与性能指标。如有特定使用场景,也可以自行配置这两个属性。
sizes属性仅对layout="responsive"或layout="fill"的图片生效。它允许定义一组媒体条件(如视口宽度)与槽位宽度,告诉浏览器当某个媒体条件成立时,应从自动生成的 source set 中下载多大尺寸的图片。以下示例来自 next/image 官方文档:
import Image from "next/image"; const Example = () => ( <div> <Image src="/mock.png" layout="fill" sizes="(min-width: 60em) 24vw, (min-width: 28em) 45vw, 100vw" /> </div> );建议:可以在 MDN 上进一步学习 HTML 的 srcset 与 sizes 属性。
5.3 高级属性
有些使用场景需要自定义图片行为,以下是<Image />组件可用的一些高级属性。
blurDataURL
一个 base64 编码的图片 DATA URL,作为src图片完全加载前的占位图。它会被放大并模糊处理,因此推荐使用 10px 或更小的微型图片。仅在配合placeholder="blur"时生效:
<Image src="https://unsplash.com/photos/XV1qykwu82c" alt="Cover photo" width={700} height={500} blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMAAAADA..." placeholder="blur" />loading
指定图片的加载行为。接受lazy与eager两个值,默认lazy。
- 为
lazy时,图片加载被延迟到它接近视口的计算距离时才触发,适用于首屏以下的图片; - 为
eager时,页面挂载后立即加载图片。请谨慎使用eager,因为它被证实会严重损害性能。
<Image src="/background.webp" alt="Page background photo" width={800} height={750} loading="lazy" />objectFit
当使用layout="fill"时,设置图片相对其父元素的尺寸适配方式。该值会传递给src图片的 object-fit CSS 属性。可选值为fill、cover或contain:
<Image src="/user.webp" alt="User profile photo" width={300} height={300} objectFit="cover" />objectPosition
指定图片内容在图片框内的对齐方式。该值会传递给应用到图片上的 object-position CSS 属性。默认50% 50%:
<Image src="/user.webp" alt="User profile photo" width={300} height={300} objectPosition="right bottom" />onLoadingComplete
原图完全加载后触发回调函数。函数接收一个参数——包含以下属性的对象:
naturalHeightnaturalWidth
const MyProfile = (props) => { const handleImageLoad = ({ naturalWidth, naturalHeight }) => { console.log(naturalWidth, naturalHeight); }; return ( <Image src="profilePic.webp" width={300} height={300} alt="User profile picture" onLoadingComplete={handleImageLoad} /> ); };style
允许为底层图片元素添加自定义 CSS 样式。也可以通过className来针对<Image />组件做样式定制。注意layout属性应用的样式会优先于style属性;此外,如果通过style属性修改图片的宽度,必须同时设置height="auto",否则图片会被拉伸变形:
<Image src="/background.webp" alt="Waterfall photo" width={800} height={800} style={{ opacity: 0.5 }} className="user_photo" />六、next.config.js中的图片配置项
要使用外部图片,需要配置以保护应用免受恶意用户攻击。可以通过next.config.js中的domains与loader属性完成。
loader
如果希望使用云服务商来优化图片,而不是使用 Next.js 内置的图片优化 API,可以在next.config.js中配置loader与path前缀。这样即可在src属性中使用相对 URL(如"me.webp"),loader 会将相对 URL 转换为绝对 URL:
module.exports = { images: { loader: "amazon", path: "https://s3.amazonaws.com/demoapp/", }, };domains
domains配置用于提供外部图片的允许主机名列表,保护应用免受恶意用户攻击。例如,下面的配置将确保外部图片必须以s3.amazonaws.com开头。任何其他协议或不匹配的主机名都将返回 400 Bad Request:
module.exports = { images: { domains: ["s3.amazonaws.com"], }, };在本仓库示例中的落地方式
本仓库的 examples/with-nextjs/next.config.mjs 展示了 Next.js 14 环境下配置文件的写法——使用 ES Module 语法导出配置对象:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ["@refinedev/antd"], }; export default nextConfig;当你的 refine + Next.js 应用需要加载外部图片时,只需在nextConfig对象中补充images配置即可,例如:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ["@refinedev/antd"], images: { domains: ["s3.amazonaws.com"], }, }; export default nextConfig;另外,在 App Router 下,你可以在 examples/with-nextjs/src/app/layout.tsx 中看到通过metadata导出配置站点图标(icons)的实践,这与图片优化同属于 Next.js 资源投递优化的范畴,可作为组织静态资源时的参考。
七、图片优化的收益
在 Next.js 应用中优化图片能带来巨大收益:
- 提升用户留存:图片优化缩短加载时间,避免因图片加载缓慢导致跳出率上升,并让用户在同一页面上与内容有更多交互;
- SEO 增益:Google 在排名时考虑页面加载时间,更快的页面排名更靠前;
- 降低带宽与成本:减少图片带宽消耗,数据流量受限的用户也能正常加载,同时节省服务器成本;
- 性能评分:优化后的图片有助于在 Google PageSpeed Insights 等性能测量工具中获得高分。
八、常见的图片优化陷阱
开发者在优化图片时经常出错,典型问题包括:
- 使用错误的格式:BMP、TIFF 等格式的效率远低于 WebP 或经过优化的 JPEG/PNG;
- 不按目标显示尺寸调整图片:向浏览器下发大图再让浏览器缩放,会造成带宽浪费和页面渲染耗时增加。任何情况下都应让图片针对显示尺寸进行优化;
- 忽略压缩:不压缩照片会导致文件体积无谓地膨胀。需要注意的是,TinyPNG、Compressor.io 等工具在压缩时会牺牲一定质量,仅用于减小体积;
- 不使用 CDN:会导致加载时间延长,尤其是服务器地理位置相距较远的用户。
九、与其他图片优化技术对比
Next.js 内置图片优化相比其他方案的优势:
- 全自动优化:以最少的手动改动自动完成优化工作;
- 开箱即用的响应式:
<Image />组件天然响应式,图片会动态适配屏幕尺寸与分辨率; - 现代格式优先:仅支持 WebP 等现代格式,其压缩率优于 JPEG 与 PNG;
- 灵活的 loader 扩展:可以为 Cloudinary、Imgix 等服务完全灵活地实现自定义 loader。
例如,可以用自定义 loader 指定图片的加载方式:
import Image from "next/image"; const customLoader = ({ src, width, quality }) => { return `https://example.com/${src}?w=${width}&q=${quality || 75}`; }; const MyImage = () => ( <Image loader={customLoader} src="profile.jpg" alt="Profile picture" width={500} height={500} /> );十、常见问题排查
在 Next.js 中进行图片优化可能会遇到一些问题:
- 图片不加载:将外部图片加载涉及的所有域名添加到
next.config.js的images.domains配置键中; - 布局抖动:未正确设置尺寸所致。对于远程图片务必添加
width与height,避免布局偏移; - 图片模糊:检查
quality属性值是否足够高。
配置domains的典型方式:
module.exports = { images: { domains: ["example.com"], }, };十一、常见问题解答(FAQ)
- SVG 支持情况:Next.js 对 SVG 的处理表现出色,但
next/image不提供针对 SVG 的开箱即用优化。任何<img />标签都可以承载 SVG,从而允许 SVG 直接内联到 HTML 中。 - 动图(GIF)处理:动图应转换为视频格式以获得性能收益,因为
next/image不会优化它们。 - 格式兼容:Next.js 支持 WebP 等所有现代图片格式,但务必为不支持这些格式的浏览器提供回退方案。
- 布局与响应式:始终调整图片尺寸以避免布局偏移;对于响应式设计请设置
layout="responsive"。 - 适用范围:记住
next/image作用于原生图片元素,而非通过 CSS 实现的背景图片——背景图仍需按常规方式自行处理。
十二、总结
通过本文,你已掌握如何使用next/image在 Next.js 中投递优化后的图片:包括自动懒加载、关键图片预加载、跨设备自动尺寸调整、现代图片格式的自动支持,以及如何利用<Image />组件改善应用性能指标。同时,你也能对照本仓库的 with-nextjs 示例 与 next.config.mjs 完成配置落地。
借助<Image />组件的诸多自定义选项与特性,你可以构建出色的开发者与用户体验,并在性能评估中取得良好成绩。
【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考