Skip to content
On this page

HTML性能优化

HTML性能优化是提升网页加载速度和用户体验的重要环节。通过优化HTML结构和内容,可以显著提高网站性能。

性能指标

关键性能指标

  • FCP (First Contentful Paint):首次内容绘制时间
  • LCP (Largest Contentful Paint):最大内容绘制时间
  • FID (First Input Delay):首次输入延迟
  • CLS (Cumulative Layout Shift):累积布局偏移

HTML结构优化

1. 精简HTML代码

html
<!-- 不好的做法 -->
<div class="container">
  <div class="row">
    <div class="col-md-12">
      <div class="content-wrapper">
        <div class="inner-content">
          <p>这里是实际内容</p>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- 更好的做法 -->
<section>
  <p>这里是实际内容</p>
</section>

2. 优化标签使用

html
<!-- 语义化且简洁的结构 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>页面标题</title>
  
  <!-- 预加载关键资源 -->
  <link rel="preload" href="critical.css" as="style">
  <link rel="preload" href="hero-image.jpg" as="image">
  
  <!-- 关键CSS内联 -->
  <style>
    /* 关键渲染路径CSS */
    body { font-family: Arial, sans-serif; }
    .hero { height: 400px; background: #f0f0f0; }
  </style>
</head>
<body>
  <header>
    <nav>
      <!-- 导航内容 -->
    </nav>
  </header>
  
  <main>
    <section class="hero">
      <h1>主要内容</h1>
    </section>
  </main>
  
  <!-- 非关键CSS延迟加载 -->
  <link rel="stylesheet" href="non-critical.css">
  
  <!-- JavaScript放在底部 -->
  <script src="app.js"></script>
</body>
</html>

资源加载优化

1. 资源预加载策略

html
<head>
  <!-- 预加载关键资源 -->
  <link rel="preload" href="hero-font.woff2" as="font" type="font/woff2" crossorigin>
  <link rel="preload" href="hero-image.jpg" as="image">
  <link rel="preload" href="critical.js" as="script">
  
  <!-- 预获取可能需要的资源 -->
  <link rel="prefetch" href="next-page.html">
  <link rel="dns-prefetch" href="//fonts.googleapis.com">
  
  <!-- 预连接到外部域 -->
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>

2. 图像优化

html
<!-- 响应式图像 -->
<picture>
  <source media="(min-width: 800px)" srcset="large.webp" type="image/webp">
  <source media="(min-width: 800px)" srcset="large.jpg" type="image/jpeg">
  <source srcset="small.webp" type="image/webp">
  <img src="small.jpg" 
       alt="图像描述" 
       loading="lazy" 
       width="800" 
       height="600"
       decoding="async">
</picture>

<!-- 使用现代格式 -->
<img src="image.webp" 
     onerror="this.onerror=null;this.src='image.jpg'" 
     alt="备选方案">

3. 字体优化

html
<head>
  <!-- 字体预加载 -->
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  
  <!-- 优化字体加载 -->
  <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
  
  <style>
    /* 字体显示优化 */
    @font-face {
      font-family: 'CustomFont';
      src: url('font.woff2') format('woff2');
      font-display: swap; /* 防止字体加载时的文本不可见 */
    }
  </style>
</head>

关键渲染路径优化

1. CSS优化

html
<head>
  <!-- 内联关键CSS -->
  <style>
    /* 首屏关键CSS */
    .header { height: 60px; background: #333; }
    .hero { height: 400px; display: flex; align-items: center; }
  </style>
  
  <!-- 非关键CSS异步加载 -->
  <link rel="preload" href="non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
  <noscript><link rel="stylesheet" href="non-critical.css"></noscript>
</head>

2. JavaScript优化

html
<body>
  <!-- 内容 -->
  
  <!-- 底部加载JavaScript -->
  <script src="app.js" defer></script>
  
  <!-- 或者使用模块化 -->
  <script type="module" src="app.mjs"></script>
  <script nomodule src="app-legacy.js"></script>
  
  <!-- 延迟非关键脚本 -->
  <script>
    // 延迟加载非关键脚本
    function loadScript(src) {
      const script = document.createElement('script');
      script.src = src;
      document.head.appendChild(script);
    }
    
    // 页面加载完成后加载分析脚本
    window.addEventListener('load', function() {
      loadScript('analytics.js');
    });
  </script>
</body>

内容分层和懒加载

1. 图像懒加载

html
<!-- 原生懒加载 -->
<img src="image.jpg" alt="描述" loading="lazy">

<!-- 带占位符的懒加载 -->
<div class="image-container">
  <img src="placeholder.jpg" 
       data-src="real-image.jpg" 
       alt="描述" 
       class="lazy-load">
  <div class="loading-spinner"></div>
</div>

<script>
  // 懒加载实现
  const imageObserver = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        img.classList.remove('lazy-load');
        imageObserver.unobserve(img);
      }
    });
  });
  
  document.querySelectorAll('.lazy-load').forEach(img => {
    imageObserver.observe(img);
  });
</script>

2. 内容懒加载

html
<!-- 使用Intersection Observer懒加载内容 -->
<div class="lazy-content" data-src="content-to-load.html">
  <div class="placeholder">加载中...</div>
</div>

<script>
  const contentObserver = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const container = entry.target;
        fetch(container.dataset.src)
          .then(response => response.text())
          .then(html => {
            container.innerHTML = html;
          });
        contentObserver.unobserve(container);
      }
    });
  });
  
  document.querySelectorAll('.lazy-content').forEach(el => {
    contentObserver.observe(el);
  });
</script>

减少重排和重绘

1. 优化DOM操作

html
<script>
  // 批量DOM操作
  function updateList(items) {
    // 使用文档片段减少重排
    const fragment = document.createDocumentFragment();
    
    items.forEach(item => {
      const li = document.createElement('li');
      li.textContent = item;
      fragment.appendChild(li);
    });
    
    const list = document.getElementById('list');
    list.appendChild(fragment); // 只触发一次重排
  }
  
  // 使用CSS类而不是直接修改样式
  function toggleTheme() {
    document.body.classList.toggle('dark-theme');
  }
</script>

2. 避免布局抖动

html
<script>
  // 不好的做法 - 导致重排重绘循环
  /*
  for (let i = 0; i < items.length; i++) {
    items[i].style.left = items[i].offsetLeft + 10 + 'px';
  }
  */
  
  // 好的做法 - 批量操作
  const positions = [];
  for (let i = 0; i < items.length; i++) {
    positions.push(items[i].offsetLeft + 10);
  }
  
  for (let i = 0; i < items.length; i++) {
    items[i].style.left = positions[i] + 'px';
  }
</script>

资源优化

1. 代码分割

html
<!-- 动态导入 -->
<script type="module">
  document.getElementById('advanced-btn').addEventListener('click', async () => {
    const { advancedFeature } = await import('./advanced-feature.js');
    advancedFeature();
  });
</script>

2. 缓存优化

html
<head>
  <!-- 设置适当的缓存策略 -->
  <meta http-equiv="Cache-Control" content="public, max-age=31536000">
</head>

网络优化

1. HTTP/2 服务端推送

html
<!-- 通过服务器配置实现,HTML中体现为 -->
<!-- 服务器推送关键资源,无需HTML标签 -->

2. 资源压缩

html
<!-- 虽然在HTML中不直接体现,但服务器应配置 -->
<!-- 启用Gzip/Brotli压缩 -->

性能监控

1. 性能API使用

html
<script>
  // 监控页面加载性能
  window.addEventListener('load', function() {
    const perfData = performance.getEntriesByType('navigation')[0];
    
    console.log('DNS查询时间:', perfData.domainLookupEnd - perfData.domainLookupStart);
    console.log('TCP连接时间:', perfData.connectEnd - perfData.connectStart);
    console.log('请求响应时间:', perfData.responseEnd - perfData.requestStart);
    console.log('DOM解析时间:', perfData.domContentLoadedEventEnd - perfData.domContentLoadedEventStart);
  });
  
  // 监控资源加载
  const observer = new PerformanceObserver((list) => {
    list.getEntries().forEach((entry) => {
      if (entry.duration > 100) {
        console.warn(`${entry.name} 加载缓慢: ${entry.duration}ms`);
      }
    });
  });
  observer.observe({entryTypes: ['resource']});
</script>

2. 用户体验监控

html
<script>
  // 监控布局偏移
  let clsValue = 0;
  let clsEntries = [];
  
  new PerformanceObserver((entryList) => {
    for (const entry of entryList.getEntries()) {
      if (!entry.hadRecentInput) {
        clsValue += entry.value;
        clsEntries.push(entry);
      }
    }
  }).observe({type: 'layout-shift', buffered: true});
  
  // 上报性能数据
  window.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'hidden') {
      // 发送性能数据到分析服务
      navigator.sendBeacon('/analytics', JSON.stringify({
        cls: clsValue,
        // 其他性能指标
      }));
    }
  });
</script>

最佳实践总结

1. 构建时优化

  • 压缩HTML、CSS、JavaScript
  • 移除未使用的CSS
  • 优化图像大小和格式
  • 启用Gzip/Brotli压缩

2. 运行时优化

  • 使用适当的加载策略
  • 实现懒加载
  • 优化关键渲染路径
  • 监控性能指标

3. 持续优化

  • 定期进行性能审计
  • 使用工具如Lighthouse、WebPageTest
  • 监控真实用户性能数据
  • A/B测试性能优化效果

通过实施这些HTML性能优化策略,可以显著提升网页的加载速度和用户体验,同时改善搜索引擎排名。