mcpField
W
web-performance-optimization

web-performance-optimization

github.com/secondsky开发240567 次安装5 周前更新
代码仓库

关于 web-performance-optimization

面向 Web 开发者的性能优化技能,提供加载、缓存、压缩与监控策略,帮助改善 Core Web Vitals 和用户体验。

主要功能

  1. 01路由代码拆分与延迟加载
  2. 02图片优化与缓存
  3. 03gzip 和 Brotli 压缩
  4. 04监控 Core Web Vitals
  5. 05提供性能指标目标

适用场景

  1. 01排查页面加载缓慢
  2. 02减小大型前端包体积
  3. 03改善移动端性能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/secondsky/claude-skills --skill web-performance-optimization

安装后在 Claude Code 中输入/web-performance-optimization确认已加载。

附带文件references/compression-monitoring.mdreferences/typescript-advanced.md

详细介绍

Web 性能优化

概述

实施包括延迟加载、代码分割、缓存、压缩和监控在内的性能优化策略,以改善 Core Web Vitals 和用户体验。

适用场景

  • 页面加载缓慢
  • 最大内容绘制(LCP)耗时较长
  • 包体积较大
  • 累积布局偏移(CLS)频繁发生
  • 移动设备性能问题

代码分割(React)

import { lazy, Suspense } from 'react';
import { Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./pages/Home'));
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/dashboard" element={<Dashboard />} />
        <Route path="/settings" element={<Settings />} />
      </Routes>
    </Suspense>
  );
}

Webpack 包优化

// webpack.config.js
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};

图片优化

<picture>
  <source srcset="image.webp" type="image/webp">
  <source srcset="image.jpg" type="image/jpeg">
  <img
    src="image.jpg"
    srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
    sizes="(max-width: 600px) 100vw, 50vw"
    loading="lazy"
    decoding="async"
    alt="Description"
  >
</picture>

Service Worker 缓存

// sw.js
const CACHE_NAME = 'app-v1';
const ASSETS = ['/', '/index.html', '/main.js', '/styles.css'];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then(cached => {
      return cached || fetch(event.request).then(response => {
        return caches.open(CACHE_NAME).then(cache => {
          cache.put(event.request, response.clone());
          return response;
        });
      });
    })
  );
});

Core Web Vitals 监控

// Track LCP, CLS, INP (Note: INP replaced FID as of March 2024)
// sendToAnalytics is a placeholder function that sends metrics to your analytics endpoint
// Expected signature: sendToAnalytics({ metric: string, value: number }) => void
// Example implementation:
function sendToAnalytics({ metric, value }) {
  // Replace with your analytics implementation (e.g., Google Analytics, Segment)
  fetch('/api/analytics', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ metric, value, timestamp: Date.now() })
  });
}

// Largest Contentful Paint (LCP)
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(`LCP: ${entry.startTime}ms`);
    sendToAnalytics({ metric: 'LCP', value: entry.startTime });
  }
}).observe({ type: 'largest-contentful-paint', buffered: true });

// Cumulative Layout Shift (CLS)
new PerformanceObserver((list) => {
  let cls = 0;
  for (const entry of list.getEntries()) {
    if (!entry.hadRecentInput) cls += entry.value;
  }
  sendToAnalytics({ metric: 'CLS', value: cls });
}).observe({ type: 'layout-shift', buffered: true });

// Interaction to Next Paint (INP) - replaces FID
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    // INP measures responsiveness - duration of slowest interaction
    const inp = entry.processingEnd - entry.processingStart;
    console.log(`INP: ${inp}ms`);
    sendToAnalytics({ metric: 'INP', value: inp });
  }
}).observe({ type: 'event', buffered: true }); // 'event' captures interaction events

性能目标

指标良好需要改进
LCP<2.5s2.5-4s
INP<200ms200-500ms
CLS<0.10.1-0.25
TTI<3.8s3.8-7.3s

注意: INP(Interaction to Next Paint,交互到下次绘制)于 2024 年 3 月取代 FID(First Input Delay,首次输入延迟),成为 Core Web Vital。INP 通过捕获交互的完整持续时间,而不只是输入延迟,提供了对页面响应能力更全面的衡量。

压缩(Nginx)

gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1000;
gzip_comp_level 6;

最佳实践

  • 通过代码分割尽量减小包体积
  • 使用适当的格式优化图片
  • 有策略地实施延迟加载
  • 使用 HTTP 缓存标头
  • 启用 gzip/brotli 压缩
  • 持续监控 Core Web Vitals
  • 实施 Service Worker
  • 延迟加载非关键 JavaScript
  • 优化关键渲染路径
  • 在真实设备和网络环境下测试

优化检查清单

  • 为路由启用代码分割
  • 延迟加载首屏以下的组件
  • 优化并压缩图片
  • 实施 Service Worker 缓存
  • 启用 gzip/brotli 压缩
  • 监控 Core Web Vitals
  • 尽量减少阻塞渲染的资源

其他配置

有关以下内容,请参阅 references/compression-monitoring.md:

  • Webpack 压缩插件设置
  • Apache .htaccess 压缩配置
  • TTFB 监控实现
  • 用于测量的 Puppeteer 自动化

有关以下内容,请参阅 references/typescript-advanced.md:

  • TypeScript lazyLoad 工具函数
  • TypeScript 图片组件
  • 带离线回退功能的高级 service worker
  • TerserPlugin 配置
  • 完整的 PerformanceMetrics 接口

工具

  • Lighthouse / PageSpeed Insights
  • WebPageTest
  • Chrome DevTools Performance 选项卡
  • web-vitals npm 包

资源

评论

支持 Markdown