图片、字体与加载性能
图片、字体与加载性能 · 阅读后完成下方实验与检查题,再用「标记完成」记录进度。
学习目标
首屏慢、内容跳来跳去,多半是图片和字体的锅。本课用 next/image 与 next/font 把资源纳入框架管理,学会用 DevTools 测量代表页面,只修实测有影响的问题。
问题场景
课程封面图 3MB,手机上首屏要等 4 秒;图片加载完成的瞬间,下面的文字被顶下去一屏——你正读到的那行突然跑了。这两件事一个叫慢(LCP 大),一个叫跳(CLS 大)。正确的顺序是先测量、再修复,别凭感觉优化。
核心解释
图片:交给 next/image。 它自动做三件事:按视口生成合适尺寸、转现代格式、声明宽高防跳动:
import Image from "next/image";
export function CourseCover({ src, title }: { src: string; title: string }) {
return (
<Image
src={src}
alt={title}
width={640}
height={360} // 声明尺寸,布局提前占位,消除 CLS
sizes="(max-width: 768px) 100vw, 640px" // 告诉浏览器按视口选尺寸
priority={false} // 只有首屏大图才设 true
/>
);
}
首屏最大的那张图设 priority(预加载,直接改善 LCP);首屏之外的图一律默认懒加载,滚动到附近才取。
字体:交给 next/font。 构建期自托管、预加载,并消除字体交换导致的文字闪动:
// app/layout.tsx(节选)
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"], display: "swap" });
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="zh-CN" className={inter.className}>
<body>{children}</body>
</html>
);
}
测量代表页面,修实测问题。 打开 DevTools 的 Performance 或 Lighthouse 面板,跑课程首页:记录 LCP(最大内容绘制)与 CLS(累积布局偏移),再针对性下手:
- LCP 慢 → 检查首屏图是否设了 priority、原图是否压到合理体积;
- CLS 大 → 检查图片有没有宽高、字体是否走 next/font、动态内容上方有没有占位;
- 指标正常就别动了——性能优化的纪律是「数据说话,改一次测一次」。
按需加载的另一半在组件级:非首屏的重组件(代码编辑器、图表)用 next/dynamic 推迟加载,把 JS 包留给首屏。
示例拆解
本机改造前后对比:
- 打开
/courses,Lighthouse 跑一次基线,记下 LCP/CLS 数值。 - 把课程封面的原生
<img>换成 next/image(补 width/height/sizes),重新测量。 - 首屏大图加 priority;滚动区图片在 Network 面板确认是滚动到才发起请求。
- 字体从 CSS link 引入改为 next/font,观察文字不再闪动,字体请求来自本站域名。
关键点:每一步只改一处、测一次,确认指标变化与预期一致再继续——一次改五处,你永远不知道哪处起了作用。
动手任务
在本机工程里完成:
- 把至少一处原生
<img>换成 next/image,前后各测一次 CLS。 - 首屏最大图片加 priority,记录 LCP 的变化数值。
- 确认字体走 next/font(或完成切换),验证无字体闪动。
常见错误
- 图片不写宽高:布局无法预留空间,加载完把内容顶跑,CLS 直接爆炸。
- 所有图都加 priority:预加载带宽被摊薄,真正的首屏图反而慢了;只给 LCP 候选设。
- 用字体 CSS link 却不开 next/font:多一次第三方往返,闪动依旧。
- 没测就优化:花一下午压缩一张根本不在首屏的图,指标纹丝不动。
检查与复盘
自查清单:
- 代表页面有改造前后的 LCP/CLS 数值记录
- 首屏图 priority、其余图懒加载的分工明确
- 字体自托管、无闪动,字体请求不出站
参考资料
- Next.js 文档:Image 组件 —— 图片优化的全部选项
- Next.js 文档:Font 模块 —— 字体自托管与闪动消除
- Next.js 文档:懒加载 —— next/dynamic 按需加载组件
读完这一课了?
标记完成后,工作台会安排接下来的学习。