解释下Cumulative Layout Shift (CLS)以及如何优化?


Cumulative Layout Shift (CLS) 解释与优化指南


一、什么是 Cumulative Layout Shift (CLS)?

Cumulative Layout Shift(累积布局偏移) 是衡量网页视觉稳定性的核心指标,属于 Google 的 Core Web Vitals(核心网页指标) 之一。它量化了页面在加载或交互过程中,元素意外移动的程度。CLS 值越低,用户体验越稳定。

CLS 计算方式
  • 布局偏移分数 = 影响范围(Impact Fraction) × 距离比例(Distance Fraction)
    • 影响范围:受偏移影响的视口区域比例(0~1)。
      例如,一个元素占据视口高度的 50%,则影响范围为 0.5。
    • 距离比例:元素移动的最大距离占视口高度的比例(0~1)。
      例如,元素垂直移动了视口高度的 25%,则距离比例为 0.25。
  • CLS 总分:页面生命周期内所有布局偏移分数的总和。

二、导致 CLS 的常见原因

1. 未指定尺寸的媒体元素
  • 问题:图片、视频或广告未设置 width/height,加载后挤压下方内容。
    <!-- 错误示例:未指定尺寸 -->
    <img src="banner.jpg" alt="Banner">
    
2. 动态插入内容
  • 问题:弹窗、广告、懒加载内容突然插入,导致现有内容移位。
    // 错误示例:动态插入未预留空间的元素
    document.body.appendChild(adElement); // 插入广告后页面内容下移
    
3. 字体加载导致的布局变化
  • 问题:自定义字体加载前后,文本区域尺寸不一致。
    /* 未优化字体加载 */
    @font-face {font-family: 'CustomFont';src: url('font.woff2');
    }
    
4. 异步加载的组件
  • 问题:组件渲染后修改布局(如表格展开、图表渲染)。
    // 异步加载数据后渲染表格
    fetchData().then(data => renderTable(data)); // 表格渲染后挤压下方内容
    
5. 动画或过渡效果
  • 问题:使用 top/left 等属性触发布局计算。
    /* 错误示例:使用 top 触发布局偏移 */
    .box {position: relative;top: 0;transition: top 0.3s;
    }
    .box:hover {top: 20px; /* 触发布局重排 */
    }
    

三、CLS 优化策略

1. 为媒体元素预留空间
  • 指定固定尺寸:为图片、视频设置 widthheight 属性。
    <!-- 正确示例:设置宽高 -->
    <img src="banner.jpg" width="600" height="400" alt="Banner">
    
  • 响应式图片适配:使用 aspect-ratio 或 CSS 保持宽高比。
    .responsive-img {width: 100%;height: auto;aspect-ratio: 16/9; /* 定义宽高比 */
    }
    
2. 动态内容预占位
  • 预留空间:提前为动态内容分配占位容器。
    <!-- 广告占位容器 -->
    <div class="ad-placeholder" style="height: 300px;"></div>
    
    // 动态插入内容时填充占位
    document.querySelector('.ad-placeholder').appendChild(adElement);
    
3. 优化字体加载
  • 预加载字体:使用 <link rel="preload"> 提前加载关键字体。
    <link rel="preload" href="font.woff2" as="font" crossorigin>
    
  • 控制字体显示行为:使用 font-display: swap 减少布局偏移。
    @font-face {font-family: 'CustomFont';src: url('font.woff2');font-display: swap; /* 先显示备用字体,再替换 */
    }
    
4. 异步组件加载优化
  • 骨架屏占位:数据加载前显示骨架屏,保持布局稳定。
    <!-- 骨架屏示例 -->
    <div class="skeleton" style="width: 100%; height: 200px;"></div>
    
  • 分块渲染:将大数据渲染拆分为多个任务。
    function renderLargeList(items) {items.forEach((item, index) => {requestAnimationFrame(() => {renderItem(item);});});
    }
    
5. 使用合成器友好的动画
  • 优先使用 transformopacity:避免触发布局或绘制。
    /* 正确示例:使用 transform 实现位移 */
    .box {transition: transform 0.3s;
    }
    .box:hover {transform: translateY(20px); /* 仅触发合成,无布局偏移 */
    }
    
6. 优化第三方脚本
  • 延迟加载非关键脚本:使用 asyncdefer
    <script src="analytics.js" async></script>
    
  • 稳定广告容器尺寸:与广告提供商约定固定尺寸或响应式逻辑。

四、检测与监控工具

  1. Chrome DevTools

    • Performance 面板:录制页面加载过程,查看布局偏移事件。
    • Layout Shift Regions:在 Rendering 面板中高亮布局偏移区域。
  2. Lighthouse

    • 运行性能测试,获取 CLS 分数及具体优化建议。
  3. Web Vitals 库

    • 通过代码实时监控 CLS。
    import { getCLS } from 'web-vitals';
    getCLS(console.log); // 输出 CLS 数据
    
  4. Google Search Console

    • 查看 Core Web Vitals 报告,定位高 CLS 页面。

五、总结

优化目标关键策略
稳定媒体元素固定尺寸、aspect-ratio、懒加载占位
预加载关键资源字体预加载、动态内容占位
优化字体加载font-display: swappreload
动画与交互优化使用 transform/opacity 替代布局属性
第三方内容控制固定容器尺寸、延迟加载脚本

通过以上策略,可显著降低 CLS 值,提升用户体验和 SEO 排名。建议结合工具定期监控,确保优化效果持续有效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37594.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用户说 | 零基础用通义灵码 AI 程序员开发个人笔记网站

作者&#xff1a;宋镇江&#xff0c;安阳幼儿师范高等专科学校数字媒体技术专业教师 通义灵码是一款基于通义大模型的智能编码辅助工具&#xff0c;支持自然语言生成代码、单元测试生成、代码注释生成等功能&#xff0c;兼容多种主流IDE和编程语言。对于零基础用户&#xff0c…

试验一 mybatis 入门操作

试验一 mybatis 入门操作 一 实验目的 1.掌握mybatis基础操作&#xff0c;包括如何在maven工程中引入依赖&#xff0c;创建mapper文件&#xff0c;核心配置文件&#xff0c;映射文件&#xff0c;并测试对数据库表基本的的CRUD操作&#xff1b; 2.掌握核心配置文件中几个重要标…

使用Gitee Go流水线部署个人项目到服务器指南

使用Gitee Go流水线部署个人项目到服务器指南 前言&#xff01;&#xff01;&#xff01; 本文解决的问题&#xff1a; 你有一台ECS服务器&#xff0c;你在上面部署了一个Java服务也就是一个jar&#xff0c;你觉着你每次手动本地打包&#xff0c;上传&#xff0c;在通过命令去…

LCCI ESG 中英联合认证国际分析师适合的岗位

LCCI ESG中英联合认证国际分析师领域热门岗位大揭秘&#xff01;&#x1f30d; 大家好&#xff01;今天我们来探讨LCCI ESG中英联合认证国际分析师领域的热门岗位&#xff0c;看看是否有适合你的选择。 1️⃣ LCCI ESG中英联合认证国际分析师报告专员&#xff1a;主要负责编制…

Compose 实践与探索十五 —— 自定义触摸

1、自定义触摸与一维滑动监测 之前我们在讲 Modifier 时讲过如下与手势检测相关的 Modifier&#xff1a; Modifier.clickable { } Modifier.combinedClickable { } Modifier.pointerInput {detectTapGestures { } }这里对以上内容就不再赘述了&#xff0c;直接去讲解更复杂的…

【Linux】Makefile秘籍

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有问题&#xff0c;还请多多包涵&a…

LDAP从入门到实战:环境部署与配置指南(上)

#作者&#xff1a;朱雷 文章目录 一、LDAP 简介1.1. 什么是目录服务1.2. 什么是 LDAP1.3. LDAP的基本模型 二、Ldap环境部署2.1.下载软件包2.2.安装软件2.3.编辑配置文件2.4.启动服务 一、LDAP 简介 1.1. 什么是目录服务 目录是专门为搜索和浏览而设计的专用数据库&#xff…

《C++智能指针:建议使用 make_shared 代替 shared_ptr》

《C 智能指针&#xff1a;长达数十年的血泪史&#xff0c;一步步征服内存泄漏》-CSDN博客 shared_ptr<int> sp1(new int(10)); 这句代码实际存在两个内存开辟&#xff0c;一是开辟我们要托管的内存资源 &#xff0c;二是开辟引用计数的资源&#xff0c;引用技术也是new出…

代码随想录刷题day50|(回溯算法篇)131.分割回文串▲

目录 一、回溯算法基础知识 二、分割回文串思路 2.1 如何切割 2.2 判断回文 2.3 回溯三部曲 2.4 其他问题 三、相关算法题目 四、总结 一、回溯算法基础知识 详见&#xff1a;代码随想录刷题day46|&#xff08;回溯算法篇&#xff09;77.组合-CSDN博客 二、分割回文…

vivo 湖仓架构的性能提升之旅

作者&#xff1a;郭小龙 vivo互联网 大数据高级研发工程师 导读&#xff1a;本文整理自 vivo互联网 大数据高级研发工程师 郭小龙 在 StarRocks 年度峰会上的分享&#xff0c;聚焦 vivo 大数据多维分析面临的挑战、StarRocks 落地方案及应用收益。 在 即席分析 场景&#xff0c…

Springboot的jak安装与配置教程

目录 Windows系统 macOS系统 Linux系统 Windows系统 下载JDK&#xff1a; 访问Oracle官网或其他JDK提供商网站&#xff0c;下载适合Windows系统的JDK版本。网站地址&#xff1a;Oracle 甲骨文中国 | 云应用和云平台点击进入下滑&#xff0c;点击进入下载根据自己的系统选择&…

力扣算法Hot100——128. 最长连续序列

题目要求时间复杂度为O(n)&#xff0c;因此不能使用两次循环匹配。 首先使用 HashSet 去重&#xff0c;并且 HashSet 查找一个数的复杂度为O(1)外循环还是遍历set集合&#xff0c;里面一重循环需要添加判断&#xff0c;这样才不会达到O( n 2 n^2 n2)判断是否进入最长序列查找循…

BlockChain.java

BlockChain 区块链&#xff0c;举个栗子 注意啦&#xff0c;列子里面的hashcode相等&#xff0c;但是字符串是不一样的哦&#xff0c;之前有记录这个问题 String.hashCode()-CSDN博客

visual studio 中导入 benchmark

法一 1.visual studio 中导入 benchmark.lib Shlwapi.lib这两个库 2.预处理宏 BENCHMARK_STATIC_DEFINE vs导入参考 错误提示 没有加入 BENCHMARK STATIC_DEFINE error LNK2001: 无法解析的外部符号 “__declspec(dllimport) int __cdecl benchmark::internal::InitializeS…

java基础之windows电脑基础命令

windows电脑基础命令 windows电脑基础命令快捷键和功能键键盘功能键B:键盘快捷键 DOS命令行的进入方式xp下如何打开DOS控制台&#xff1f;win7下如何打开DOS控制台&#xff1f;win8下如何打开DOS控制台 DOS命令讲解 黑窗口编译文件使用黑窗口运行java程序 windows电脑基础命令 …

Java 第十一章 GUI编程(3)

目录 内部类 内部类定义 内部类的特点 匿名内部类 格式&#xff1a; 内部类的意义 实例 内部类 ● 把类定义在另一个类的内部&#xff0c;该类就被称为内部类。 ● 如果在类 Outer 的内部再定义一个类 Inner&#xff0c;此时类 Inner 就称为内部类 &#xff08;或称为嵌…

uniapp 实现的下拉菜单组件

采用 uniapp 实现, 是一款具备丝滑折叠、展开动画的下拉菜单&#xff0c;支持 vue2、vue3&#xff1b;适配 web、H5、微信小程序&#xff08;其他平台小程序未测试过&#xff0c;可自行尝试&#xff09; 可到插件市场下载尝试&#xff1a; https://ext.dcloud.net.cn/plugin?i…

【一维前缀和与二维前缀和(简单版dp)】

1.前缀和模板 一维前缀和模板 1.暴力解法 要求哪段区间&#xff0c;我就直接遍历那段区间求和。 时间复杂度O(n*q) 2.前缀和 ------ 快速求出数组中某一个连续区间的和。 1&#xff09;预处理一个前缀和数组 这个前缀和数组设定为dp&#xff0c;dp[i]表示&#xff1a;表示…

ubuntu部署运行xinference全精度对话deepseek本地部署图文教程

前置环境搭建劳请移步往期 source activate 自己环境名启动python3.12环境安装xinference&#xff0c; 按教程敲命令&#xff0c;wheel包与wsl的通用&#xff0c;pip install 包名。 vllm引擎&#xff0c;transform引擎也会顺带自动装上了。 后续操作请参照往期教程。本地部署模…

Python 面向对象三大特性深度解析

一、封装&#xff08;Encapsulation&#xff09; 1. 私有化实现 class BankAccount:def __init__(self, account_holder, balance0):self.__holder account_holder # 双下划线私有属性self.__balance balance# 公有方法访问私有属性def deposit(self, amount):if amount &…