Skip to content

性能优化清单

目标

系统化优化网站性能指标,使 Core Web Vitals 全部达标(LCP<2.5s、FID<100ms、CLS<0.1),提升用户体验和SEO排名。

前置条件

  • 网站已部署上线(Vercel、Cloudflare Pages 或其他平台)
  • 可访问 Google Search Console 查看 Core Web Vitals 数据
  • 有代码仓库的编辑权限
  • 了解基本前端开发(HTML/CSS/JavaScript)

操作步骤

步骤1:测量当前性能基线

目的:建立量化基准,明确优化目标,避免盲目优化。 操作

  1. 打开 PageSpeed Insights,输入你的网站URL。
  2. 分别测试 Mobile 和 Desktop 两个模式,记录以下指标:
    • LCP(Largest Contentful Paint):最大内容渲染时间
    • FID(First Input Delay):首次输入延迟
    • CLS(Cumulative Layout Shift):累积布局偏移
    • FCP(First Contentful Paint):首次内容绘制
    • TTFB(Time to First Byte):首字节时间
    • Speed Index:速度指数
  3. 打开 Google Search Console → 体验 → 核心网页指标,查看真实用户数据。
  4. 将所有指标填入性能追踪表格,标注不达标项:
    指标达标值当前值是否达标
    LCP<2.5s--
    INP<200ms--
    CLS<0.1--
  5. 使用 Chrome DevTools → Lighthouse → 生成本地报告,作为对比参考。 验证
  • 性能基线数据完整记录
  • 明确了哪些指标不达标
  • 有了量化对比基准

步骤2:优化Core Web Vitals

目的:直接针对Google排名核心指标进行优化,确保搜索排名不受性能拖累。 操作

LCP优化(目标 < 2.5s):

  1. 识别LCP元素:在 DevTools → Performance 中录制页面加载,找到LCP元素(通常是首屏大图或标题文本)。
  2. 如果LCP元素是图片:
    • 添加 fetchpriority="high" 属性。
    • 确保图片使用现代格式(WebP/AVIF),参考步骤3。
    • 使用 <link rel="preload"> 预加载图片。
  3. 如果LCP元素是文本:
    • 确保字体已优化(参考步骤6)。
    • 检查是否有CSS阻塞渲染,内联关键CSS。
  4. 减少服务器响应时间:
    • 使用 Cloudflare CDN 缓存。
    • 开启 Vercel Edge Functions 或 Static Generation。
    • TTFB 控制在 800ms 以内。

INP优化(目标 < 200ms):

  1. 使用 PageSpeed Insights 的 INP 调试信息,找出慢交互。
  2. 拆分长任务(>50ms 的任务):
    • 使用 requestIdleCallback 延迟非关键逻辑。
    • 将大任务拆分为多个小任务,用 setTimeout(fn, 0) 让出主线程。
  3. 减少事件回调中的DOM操作,使用 requestAnimationFrame 批量更新。

CLS优化(目标 < 0.1):

  1. 为所有图片和视频设置明确的 widthheight 属性(或 aspect-ratio CSS属性)。
  2. 为动态插入的内容预留空间(如广告位、推荐区域)。
  3. 避免在视口上方动态注入内容。
  4. 确保字体加载时使用 font-display: swapoptional
  5. 使用 CSS contain 属性限制布局影响范围。

验证

  • PageSpeed Insights 中 LCP、INP、CLS 均达标
  • Google Search Console 核心网页指标报告显示改善

步骤3:优化图片

目的:图片通常占页面总重量的50%以上,优化图片是提升加载速度最直接的手段。 操作

  1. 格式转换
    • 使用 WebP 格式(兼容性 >97%)。
    • 对支持 AVIF 的浏览器优先提供 AVIF(压缩率比WebP再高20-30%)。
    • 使用 <picture> 标签实现格式回退:
      html
      <picture>
        <source srcset="image.avif" type="image/avif">
        <source srcset="image.webp" type="image/webp">
        <img src="image.jpg" alt="描述" width="800" height="600">
      </picture>
  2. 响应式图片
    • 使用 srcsetsizes 提供不同分辨率版本:
      html
      <img srcset="img-480w.webp 480w, img-800w.webp 800w, img-1200w.webp 1200w"
           sizes="(max-width: 600px) 480px, 800px"
           src="img-800w.webp" alt="描述">
  3. 懒加载
    • 为非首屏图片添加 loading="lazy"
    • 首屏图片不要懒加载,应使用 loading="eager" + fetchpriority="high"
  4. 压缩
    • 使用工具批量压缩:Squoosh(手动)、Sharp(Node.js脚本)、或构建工具插件。
    • 质量设置:WebP 质量 75-85 通常视觉无损。
  5. CDN图片优化(如使用 Cloudflare):
    • 开启 Cloudflare Polish(自动压缩和WebP转换)。
    • 开启 Cloudflare Mirage(自动响应式图片适配)。 验证
  • Lighthouse 图片审计无红色警告
  • 图片总传输量减少 >40%
  • 首屏图片在 LCP 前完成加载

步骤4:优化JavaScript代码

目的:减少JavaScript体积和执行时间,消除渲染阻塞资源。 操作

  1. 代码分割(Code Splitting)
    • 使用动态 import() 按路由或功能拆分代码:
      javascript
      // 路由级别分割
      const AboutPage = React.lazy(() => import('./AboutPage'));
      // 功能级别分割
      const loadChart = () => import('chart.js');
    • Next.js 用户:使用 dynamic() 组件自动代码分割。
  2. Tree Shaking
    • 确保构建工具(Webpack/Vite/Rollup)开启 Tree Shaking(生产模式默认开启)。
    • 使用具名导入替代全量导入:
      javascript
      // 错误:导入整个库
      import _ from 'lodash';
      // 正确:只导入需要的函数
      import debounce from 'lodash/debounce';
  3. 移除未使用的代码
    • 检查 bundle 分析报告(webpack-bundle-analyzer@next/bundle-analyzer)。
    • 移除未使用的依赖包。
    • 用更轻量的替代库(如用 date-fns 替代 moment.js)。
  4. 延迟非关键脚本
    • 第三方分析脚本添加 asyncdefer
    • 非关键功能使用动态 import() 延迟到空闲时加载。
  5. 避免客户端重型计算
    • 将数据处理、Markdown渲染等移到构建时(SSG)或服务端(SSR)。 验证
  • 主 JavaScript bundle < 200KB(gzip后)
  • Lighthouse "Reduce JavaScript execution time" 无红色警告
  • 首屏不需要的代码全部延迟加载

步骤5:配置缓存策略

目的:通过多层缓存减少重复请求,实现秒开体验。 操作

  1. 浏览器缓存
    • 静态资源(JS/CSS/图片/字体)设置长期缓存:
      Cache-Control: public, max-age=31536000, immutable
    • HTML页面设置短期缓存或不缓存:
      Cache-Control: public, max-age=0, must-revalidate
    • 使用内容哈希文件名实现长期缓存(如 app-3f2a1b.js)。
  2. CDN缓存(Cloudflare):
    • 参考 Cloudflare全套配置 中的缓存规则设置。
    • 静态资源 Edge Cache TTL 设为 1 month。
    • HTML 页面 Edge Cache TTL 设为 4 hours。
  3. SWR(Stale-While-Revalidate)策略
    • 数据请求使用 SWR 模式:先返回缓存数据,同时后台更新。
    • Next.js 用户可直接使用 next revalidate@tanstack/query
    • 自定义实现:
      javascript
      // 缓存优先,后台更新
      async function fetchWithSWR(url) {
        const cached = localStorage.getItem(`swr:${url}`);
        if (cached) {
          fetch(url).then(data => localStorage.setItem(`swr:${url}`, JSON.stringify(data)));
          return JSON.parse(cached);
        }
        const data = await fetch(url);
        localStorage.setItem(`swr:${url}`, JSON.stringify(data));
        return data;
      }
  4. Service Worker缓存(可选,PWA场景):
    • 使用 Workbox 库配置缓存策略。
    • App Shell 模式:缓存应用框架,动态加载内容。 验证
  • 二次访问页面加载时间 < 1s
  • DevTools Network 中静态资源状态码为 304 或从缓存加载
  • CDN 命中率 > 80%

步骤6:优化字体加载

目的:字体加载不当会导致文字闪烁(FOIT/FOUT)和布局偏移(CLS)。 操作

  1. 使用 font-display
    • @font-face 中添加 font-display: swap(推荐)或 font-display: optional
    • swap:优先显示备用字体,加载完成后切换。
    • optional:浏览器根据网络情况决定是否下载字体。
  2. 预加载关键字体
    html
    <link rel="preload" href="/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
  3. 子集化字体
    • 只包含网站实际使用的字符,大幅减小字体文件体积。
    • 出海英文站:使用 latin 子集即可。
    • 使用 glyphhangerfonttools 进行子集化。
  4. 减少字体变体数量
    • 只加载实际使用的字重(Regular 400 + Bold 700 通常足够)。
    • 避免加载 100-900 全部字重。
  5. 考虑系统字体栈
    • 对于非品牌字体(正文内容),使用系统字体栈可完全避免字体加载:
      css
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

验证

  • Lighthouse "Ensure text remains visible during webfont load" 通过
  • CLS 不因字体加载而偏移
  • 字体文件总大小 < 100KB

步骤7:优化第三方脚本

目的:第三方脚本(分析、客服、广告)是性能杀手,需要严格控制。 操作

  1. 审计第三方脚本
    • 在 DevTools → Network 中筛选第三方域名请求。
    • 列出所有第三方脚本及其用途。
  2. 延迟加载非关键脚本
    • 分析脚本(Google Analytics、Mixpanel)→ 使用 async 加载,或延迟到用户交互后加载。
    • 客服组件(Intercom、Crisp)→ 延迟5秒或用户滚动后加载。
    • 社交分享按钮 → 延迟到视口内时加载。
  3. 使用 facade 模式
    • 对于视频嵌入(YouTube)、地图(Google Maps),先显示静态占位图,用户点击后才加载实际组件。
  4. 替代重型方案
    • Google Analytics → 考虑 Vercel Analytics 或 Plausible(脚本 < 1KB)。
    • Intercom → 考虑轻量级聊天方案如 Crisp 或 Tawk.to。
  5. 设置 Resource Hints
    • 对必须使用的第三方域名添加 preconnect
      html
      <link rel="preconnect" href="https://www.googletagmanager.com">

验证

  • 第三方脚本总执行时间 < 200ms
  • 主线程阻塞时间 < 150ms
  • 不必要的第三方脚本已移除或延迟

检查清单

  • [ ] 性能基线已测量并记录
  • [ ] LCP < 2.5s
  • [ ] INP < 200ms
  • [ ] CLS < 0.1
  • [ ] 所有图片使用 WebP/AVIF 格式
  • [ ] 非首屏图片使用懒加载
  • [ ] JavaScript 已代码分割,主 bundle < 200KB
  • [ ] 浏览器缓存和CDN缓存已配置
  • [ ] 字体使用 font-display: swap
  • [ ] 第三方脚本已延迟或替换
  • [ ] PageSpeed Insights 移动端评分 > 90

常见问题

问题原因解决方案
LCP 始终 > 2.5s服务器响应慢或LCP元素加载延迟检查TTFB,优化服务端渲染;preload LCP图片;内联关键CSS
CLS 值偏高图片无尺寸、字体闪烁、动态内容给图片设width/height;font-display: swap;预留动态内容空间
JS执行时间过长Bundle过大或未做代码分割检查bundle分析报告;拆分路由级代码;Tree Shaking
字体闪烁明显字体文件大且无预加载preload关键字体;子集化;减少字重变体
第三方脚本拖慢速度同步加载、执行时间长全部改为async/defer;延迟到交互后加载;考虑轻量替代
缓存命中率低缓存头设置不当检查Cache-Control头;静态资源加内容哈希;配置CDN规则
移动端评分远低于桌面端移动端CPU/网络受限优先针对移动端优化;减少JS执行;更激进的代码分割

参考文章

  • Cloudflare全套配置:CDN缓存和加速配置
  • Vercel:自带性能分析和Edge优化
  • Cloudflare:CDN缓存、Polish图片优化、Mirage响应式图片
  • API调试指南:接口性能排查