Q28 · 通用优化策略

图片优化有哪些常见手段?如何实现懒加载?

图片优化懒加载WebP

⚡ 速记答案(30 秒)

  • 格式选择:WebP/AVIF 比 JPEG/PNG 小 30-50%
  • 尺寸适配:使用 srcset 和 sizes 响应式图片
  • 懒加载:loading="lazy" 或 Intersection Observer
  • 压缩:使用 imagemin、tinypng 等工具
  • CDN:图片上 CDN + 缓存策略

📖 详细讲解

图片优化策略


1. 格式选择


格式特点适用场景
JPEG有损压缩照片
PNG无损、透明图标、截图
WebP更小、支持动画通用
AVIF最小、新格式现代浏览器
SVG矢量图标、图形

2. 响应式图片


<img
  src="image-800.jpg"
  srcset="
    image-400.jpg 400w,
    image-800.jpg 800w,
    image-1200.jpg 1200w
  "
  sizes="(max-width: 600px) 400px, 800px"
/>

3. 懒加载


原生支持:

<img src="image.jpg" loading="lazy" />

优化效果


优化项节省
WebP 替换30-50%
合适尺寸50-80%
懒加载首屏 50%

💻 代码示例

Intersection Observer 懒加载
function LazyImage({ src, alt, ...props }: React.ImgHTMLAttributes<HTMLImageElement>) {
  const imgRef = useRef<HTMLImageElement>(null);
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    const img = imgRef.current;
    if (!img) return;

    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            // 进入视口,开始加载
            img.src = src || '';
            observer.unobserve(img);
          }
        });
      },
      { rootMargin: '50px' } // 提前 50px 开始加载
    );

    observer.observe(img);
    return () => observer.disconnect();
  }, [src]);

  return (
    <img
      ref={imgRef}
      alt={alt}
      style={{ opacity: isLoaded ? 1 : 0, transition: 'opacity 0.3s' }}
      onLoad={() => setIsLoaded(true)}
      {...props}
    />
  );
}
Next.js Image 组件
import Image from 'next/image';

// Next.js 自动优化:
// - 自动选择 WebP/AVIF
// - 自动生成多尺寸
// - 自动懒加载
// - 自动占位符

function OptimizedImage() {
  return (
    <Image
      src="/photo.jpg"
      alt="Photo"
      width={800}
      height={600}
      placeholder="blur"
      blurDataURL="data:image/jpeg;base64,..."
      priority={false} // 非首屏图片
    />
  );
}
💡
面试技巧:回答性能问题时,先说指标和标准,再讲优化手段,最后结合实际项目经验。