Skip to content

累积布局偏移

问题概述

网站存在 CLS 问题,主要来源:

  • body > main.main > section.homepage-section > ::before 元素导致的布局偏移
  • Web 字体加载时的字体切换导致的文本重排
  • Hero section 海浪动画 SVG 初始化时的尺寸计算
  • 滑块组件的 visibility 切换

解决方案

1. ::before 伪元素优化

问题::before 伪元素没有明确的尺寸定义,导致浏览器在布局计算时出现偏移。

解决方案

  • 为所有 ::before 元素添加明确的 width: 100%height: 100%
  • 添加 contain: layout style 属性,限制元素的布局影响范围

修改文件assets/scss/templates/_homepage.scss

&::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;        // 新增明确宽度
  height: 100%;       // 新增明确高度
  background: /* 渐变 */;
  pointer-events: none;
  z-index: 0;
  contain: layout style;  // 新增限制布局影响
}

2. 字体加载优化

问题:Inter 和 Noto Sans SC 字体加载时从 fallback 字体切换导致文本重排。

解决方案

  • 添加关键字体的 preload 链接
  • @font-face 添加 size-adjust: 100% 属性
  • 简化字体定义,移除冗余注释

修改文件

  • layouts/partials/head.html - 添加字体预加载
  • assets/scss/_typography.scss - 优化字体定义
<!-- Font Preloading for CLS Optimization -->
<link rel="preload" href="{{ `fonts/inter-v18-latin-regular.woff2` | relURL }}" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ `fonts/inter-v18-latin-600.woff2` | relURL }}" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ `fonts/noto-sans-sc-v37-latin-regular.woff2` | relURL }}" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ `fonts/noto-sans-sc-v37-latin-600.woff2` | relURL }}" as="font" type="font/woff2" crossorigin>

3. SVG 动画容器优化

问题:Hero section 的海浪动画 SVG 在初始化时没有固定尺寸。

解决方案

  • 为 SVG 添加 min-height 和绝对定位样式
  • 在 CSS 中添加 contain: layout 属性
  • 确保 SVG 容器有稳定的尺寸

修改文件

  • layouts/index.html - SVG 添加内联样式
  • assets/scss/templates/_slider.scss - 容器优化

4. 滑块初始化优化

问题:滑块使用 visibility: hidden/visible 切换导致布局跳跃。

解决方案

  • 改用 opacitytransform 实现平滑过渡
  • 预设滑块最小高度
  • 优化 JavaScript 初始化逻辑

修改文件

  • assets/scss/templates/_slider.scss - CSS 优化
  • assets/js/main.js - JavaScript 优化

5. 新增 CLS 优化组件

创建文件assets/scss/components/_cls-optimization.scss

主要功能

  • 为 homepage sections 设置最小高度
  • 优化图片加载占位
  • 稳定化卡片组件高度
  • 添加动画的 contain: layout 属性

验证方法

1. Chrome DevTools 检查

  1. 打开 Chrome DevTools
  2. 进入 Performance 标签
  3. 勾选 "Web Vitals" 选项
  4. 录制页面加载过程
  5. 查看 CLS 指标

2. Lighthouse 测试

  1. 在 DevTools 中打开 Lighthouse
  2. 运行 Performance 测试
  3. 检查 CLS 分数(目标:< 0.1)

3. Layout Shift Regions

  1. DevTools → Rendering
  2. 勾选 "Layout Shift Regions"
  3. 刷新页面观察布局偏移区域

性能目标

  • CLS 分数:< 0.1(Good)
  • 首页加载:减少视觉跳跃
  • 字体加载:平滑过渡
  • 动画效果:不影响布局稳定性

浏览器兼容性

  • 现代浏览器:Chrome 76+, Firefox 72+, Safari 14+
  • contain 属性:Chrome 52+, Firefox 69+
  • font-display: swap:所有现代浏览器
  • size-adjust:Chrome 92+, Firefox 89+

监控建议

  1. 定期使用 Lighthouse 检查 CLS 分数
  2. 在不同设备和网络条件下测试
  3. 监控 Core Web Vitals 数据
  4. 关注用户反馈中的视觉体验问题

注意事项

  1. 渐进增强:确保在不支持新特性的浏览器中降级良好
  2. 性能平衡:CLS 优化不应影响其他性能指标
  3. 测试覆盖:在移动端和桌面端都进行充分测试
  4. 内容更新:新增内容时要考虑 CLS 影响