public 目录:静态文件

public/ 下的文件直接通过 URL 访问:

public/
├── avatar.jpg              →  /avatar.jpg
├── docs/
│   └── resume.pdf          →  /docs/resume.pdf
└── favicon.ico             →  /favicon.ico
<img src="/avatar.jpg" alt="me" />
<a href="/docs/resume.pdf">Resume</a>

next/image:图片优化

import Image from 'next/image';

<Image
    src="/avatar.jpg"
    alt="Avatar"
    width={200}
    height={200}
/>

Next.js 自动:

  • 转 WebP / AVIF(现代格式)
  • 生成多种尺寸(srcset
  • 懒加载(视口外不下载)
  • 预留空间(防 layout shift)

远程图片

<Image
    src="https://example.com/photo.jpg"
    alt="..."
    width={800}
    height={600}
/>

next.config.ts 加白名单:

const config = {
    images: {
        remotePatterns: [
            { protocol: 'https', hostname: 'example.com' },
            { protocol: 'https', hostname: '*.cloudfront.net' },
        ],
    },
};

自动填充容器(fill 模式)

不知道具体宽高时:

<div className="relative w-full h-64">
    <Image
        src="/photo.jpg"
        alt="..."
        fill
        style={{ objectFit: 'cover' }}
    />
</div>

父容器必须 position: relative

响应式图片

<Image
    src="/photo.jpg"
    alt="..."
    width={1200}
    height={800}
    sizes="(max-width: 768px) 100vw, 50vw"
/>

sizes 告诉浏览器"这张图在 mobile 占 100%,desktop 占 50%"——浏览器据此选最佳尺寸。

priority:关键图片预加载

首屏看到的图(hero 图、头像)加 priority

<Image
    src="/hero.jpg"
    alt="Hero"
    width={1200}
    height={600}
    priority           // ★ 立刻加载
/>

其他图默认懒加载——视口接近才加载。

占位符(loading skeleton)

<Image
    src="/big.jpg"
    alt="..."
    width={1200}
    height={800}
    placeholder="blur"
    blurDataURL="data:image/jpeg;base64,..."     // 极小的预览图 base64
/>

或用 placeholder="empty"(默认,无占位)。

icon / favicon

app/icon.pngapp/favicon.ico——Next 自动设置:

src/app/
├── favicon.ico        ←  /favicon.ico
├── icon.png           ←  自动设为 favicon
├── apple-icon.png     ←  iOS 主屏图标
└── opengraph-image.png ← OG 分享图

字体(next/font)

import { Inter, Noto_Serif_SC } from 'next/font/google';

const inter = Inter({ subsets: ['latin'] });
const noto = Noto_Serif_SC({ subsets: ['chinese-simplified'], weight: ['400', '700'] });

export default function Layout({ children }) {
    return <html className={`${inter.className} ${noto.className}`}>...</html>;
}

Next 自动:

  • 下载字体到自己服务器
  • 子集化(只装用到的字符)
  • 防 FOUT(无字体闪烁)

视频

<video> 直接放 public/

<video controls className="w-full">
    <source src="/intro.mp4" type="video/mp4" />
</video>

大视频考虑放 CDN / 对象存储——别打包进 deployment。

SVG

直接 <img> 或作为 React 组件:

// 1. 当图片用
<img src="/logo.svg" alt="Logo" />

// 2. 内联 JSX
export default function Page() {
    return (
        <svg width="100" height="100" viewBox="0 0 100 100">
            <circle cx="50" cy="50" r="40" fill="blue" />
        </svg>
    );
}

要把 SVG 文件转成组件:装 @svgr/webpack,配置后能 import Logo from './logo.svg'

  • 远程图片不加白名单会报错——next.config.ts 里加
  • 大图直接放 git 仓库 → 仓库膨胀——大资源放 CDN / 对象存储
  • 自定义图片处理:Vercel 自动 / 自托管要装 sharp(next 会提示)
  • 一定要写 alt——无障碍 + SEO

下一篇:MDX 写博客。