深入理解前端性能优化:从网络到渲染

1. 网络优化

减少 HTTP 请求

  • 合并资源:通过合并CSS和JavaScript文件来减少请求数量。
  • 内联资源:对于小型 CSS 和 JavaScript,将它们直接内联到 HTML 中。
  • 使用 HTTP/2

  • HTTP/2支持多路复用,减少请求阻塞,提高加载速度。
  • 启用 GZIP 压缩

    服务器端配置,压缩文本资源,减少传输量。

    缓存策略

    使用HTTP缓存头,例如Cache-Control,来设置适当的缓存策略。

    2.资源加载优化

    延迟加载

    仅在资源即将进入视口时加载,适用于图像和视频等。

    
    

    预加载和预取

    使用“ ”提前加载关键资源。

    使用“ ”来预取非关键资源。

    3. 渲染优化

    关键 CSS

    在 HTML 头中内联首屏渲染所需的 CSS,以避免阻塞渲染。

    减少 CSS 和 JavaScript 阻塞

  • 用于延迟非关键 CSS 加载。
  • 使用 async 或 defer 属性异步加载 JavaScript。
  • 避免强制同步布局

  • 使用 requestAnimationFrame 或 CSS 动画代替复杂的 JavaScript 动画来减少重排和重绘。
  • 图像优化

  • 选择正确的图像格式(例如 WebP)并使用正确的尺寸和分辨率。
  • 4. Service Worker 与离线存储

  • 使用Service Worker实现离线缓存和资源更新。
  • if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker
            .register('/sw.js')
            .then(registration => console.log('SW registered:', registration))
            .catch(error => console.error('SW registration failed:', error));
        });
    }

    5. 性能监控与分析

  • 使用 Lighthouse、WebPageTest 或 Chrome DevTools 等工具进行性能测试和分析。
  • 6. 代码分割和延迟加载

    动态导入

    使用动态导入(import()表达式)按需加载代码块,减少初始加载时间。

    button.onclick = async () => {
        const module = await import('./lazyModule.js');
        module.default();
    };

    路由级代码拆分

    在SPA应用中,使用框架提供的路由级代码拆分功能,例如Vue Router的懒加载。

    // Vue Router example
    const Foo = () => import('./Foo.vue');
    
    const routes = [
    { path: '/foo', component: Foo },
    ];

    7. 图像优化

    响应式图像

    使用``元素或srcset属性根据设备像素比或视口大小提供不同分辨率的图像。

    
    
    
    Example
    

    8. Web Workers

    将耗时的计算任务移至 Web Workers,以避免阻塞主线程并保持 UI 响应。

    // main.js
    const worker = new Worker('worker.js');
    worker.postMessage([1024, 512]);
    
    // worker.js
    self.onmessage = function(e) {
        const result = e.data[0] * e.data[1];
        self.postMessage(result);
    };

    9. 避免内存泄漏

    定期清理未使用的计时器、事件监听器和大型数据结构,以防止内存泄漏。

    window.addEventListener('resize', handleResize);
    // Cleanup
    window.removeEventListener('resize', handleResize);
    
    // For setTimeout or setInterval
    let timerId = setInterval(() => { /*...*/ }, 1000);
    clearInterval(timerId);

    10. Web 生命体征监测

    关注 Web Vitals 指标,例如 LCP(最大内容绘制)、FID(首次输入延迟)和 CLS(累积布局偏移),它们是衡量用户体验的关键指标。

    // Use the Web Vitals library for monitoring
    import { getCLS, getFID, getLCP } from 'web-vitals';
    
    getCLS(console.log);
    getFID(console.log);
    getLCP(console.log);