正在加载,请稍候…

Web 性能:核心网页指标优化指南

优化核心网页指标(LCP、CLS、FID/INP)。学习图片优化、关键渲染路径、代码拆分和监控技术,提升用户体验。

Web 性能:核心网页指标优化指南

Web 性能:核心网页指标优化

理解核心网页指标

LCP (Largest Contentful Paint) - 加载性能
  良好: < 2.5s, 需要改进: 2.5-4s, 较差: > 4s

CLS (Cumulative Layout Shift) - 视觉稳定性
  良好: < 0.1, 需要改进: 0.1-0.25, 较差: > 0.25

INP (Interaction to Next Paint) - 响应性(取代 FID)
  良好: < 200ms, 需要改进: 200-500ms, 较差: > 500ms

Web 性能:核心网页指标优化指南 插图

LCP 优化

<!-- 预加载 LCP 图片 -->
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high">

<!-- 使用现代图片格式 -->
<picture>
  <source srcset="/hero.avif" type="image/avif">
  <source srcset="/hero.webp" type="image/webp">
  <img src="/hero.jpg" alt="Hero" width="1200" height="630" loading="eager">
</picture>
// Next.js: 为 LCP 图片设置优先级
import Image from 'next/image';

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={630}
  priority  // 预加载,相当于 fetchpriority="high"
  sizes="100vw"
/>

图片优化

// 使用 srcset 实现响应式图片
function ResponsiveImage({ src, alt }: { src: string; alt: string }) {
  return (
    <img
      src={`${src}?w=800`}
      srcSet={`${src}?w=400 400w, ${src}?w=800 800w, ${src}?w=1200 1200w`}
      sizes="(max-width: 640px) 400px, (max-width: 1024px) 800px, 1200px"
      alt={alt}
      loading="lazy"
      decoding="async"
    />
  );
}

// 使用 sharp 转换为 WebP/AVIF
import sharp from 'sharp';

async function optimizeImage(inputPath: string, outputDir: string): Promise<void> {
  const base = path.basename(inputPath, path.extname(inputPath));

  await sharp(inputPath)
    .resize(1200, null, { withoutEnlargement: true })
    .webp({ quality: 80 })
    .toFile(`${outputDir}/${base}.webp`);

  await sharp(inputPath)
    .avif({ quality: 65 })
    .toFile(`${outputDir}/${base}.avif`);
}

Web 性能:核心网页指标优化指南 插图

CLS 预防

/* 在图片加载前预留空间 */
img {
  aspect-ratio: 16/9;
  width: 100%;
  height: auto;
}

/* 为动态内容预留空间 */
.ad-container {
  min-height: 250px; /* 预期广告高度 */
}

/* 避免字体引起的布局偏移 */
@font-face {
  font-family: 'Inter';
  font-display: swap; /* 加载时使用后备字体 */
}

JavaScript 性能

// 延迟非关键 JavaScript
// 不好:阻塞渲染
<script src="/analytics.js"></script>

// 好:页面可交互后加载
<script src="/analytics.js" defer></script>
// 或对独立脚本使用 async
<script src="/analytics.js" async></script>

// 测量 INP
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === 'event') {
      const inp = entry.duration;
      if (inp > 200) {
        console.warn(`慢交互: ${entry.name} 耗时 ${inp}ms`);
        // 上报到分析系统
      }
    }
  }
});
observer.observe({ type: 'event', buffered: true });

Web 性能:核心网页指标优化指南 插图

性能监控

// 将 Web Vitals 上报到分析系统
import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';

function sendToAnalytics({ name, value, id }: Metric) {
  navigator.sendBeacon('/analytics', JSON.stringify({
    metric: name,
    value: Math.round(name === 'CLS' ? value * 1000 : value),
    id,
    url: window.location.href,
    userAgent: navigator.userAgent,
  }));
}

onLCP(sendToAnalytics);
onCLS(sendToAnalytics);
onINP(sendToAnalytics);
onFCP(sendToAnalytics);
onTTFB(sendToAnalytics);

资源提示

<!-- 预连接到关键的第三方 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://api.myapp.com">

<!-- 对非关键资源进行 DNS 预取 -->
<link rel="dns-prefetch" href="https://cdn.example.com">

<!-- 预取下一页资源 -->
<link rel="prefetch" href="/next-page.js">

首先使用 Lighthouse 或 WebPageTest 进行测量,然后优化最大的收益点。