页面视觉稳定性之优化CLS
最常见的影响CLS的分数的有:
- 未指定尺寸的图片
- 未指定尺寸的广告、嵌入元素、iframe
- 动态插入内容
- 自定义字体(引发FOIT/FOUT)
- 在更新DOM之前等待网络响应的操作
未指定尺寸的图片
总而言之:在 <img>
和 <video
标签上始终加上 width
和 height
属性。或者,使用 CSS aspect ratio boxes
来占据空间。这种方法可以确保在图片加载过程中,浏览器可以分配足够的空间。
历史
在web的早期,开发者会给 <img>
标签加上 width
和 height
属性,以确保浏览器开始获取图片之前可以分配好空间,这样可以减少 reflow
和 re-layout
。
<img src="puppy.jpg" width="640" height="360" alt="Puppy with balloons">
你也许会注意到这两个属性没有带单位。这些像素尺寸会确保保留640 * 360的区域。图片最终会平铺在这个区域,不管原始尺寸是否一致。
当响应式设计来临的时候,开发者开始忽略 width
和 height
,开始使用css来调整图片大小。
img {width: 100%; /* or max-width: 100%; */height: auto;
}
这种方法的缺点是,只有图片下载的时候,浏览器才知道图片的宽高并且分配好空间。图片下载完了,每张图片出现在屏幕上的时候,页面都会 reflow
一次,会导致页面频繁的往下弹。这对于用户体验来说非常不友好。
因此而诞生了 aspect ratio
。aspect ratio
是图片的宽高比。比如,x:y的宽高比,指的是宽度x单位,高度y单位。
这也意味着只要我们知道宽高之一,就能计算出另一个属性。对于一个16:9的宽高比而言:
- 如果图片有360px的高度,则宽度为 360 x (16 / 9) = 640px
- 如果图片有640px的宽度,则高度为 640 x (9 / 16) = 360px
现代浏览器最佳体验
现代浏览器可以基于 width
和 height
属性设定默认宽高比,这样就能避免布局偏移。开发者只需要如下设置:
<!-- set a 640:360 i.e a 16:9 - aspect ratio -->
<img src="puppy.jpg" width="640" height="360" alt="Puppy with balloons">
img {aspect-ratio: attr(width) / attr(height);
}
这样一来,图片加载之前,浏览器就可以根据宽高属性分配好空间。图片加载之后,就可以根据宽度或者高度属性,按照宽高比来分配实际空间。
图片的 aspect-ratio
属性在chrome和firefox上已经可以使用了,safari也快支持了。
如果图片位于容器内,可以设置宽度为容器宽度,高度为auto,避免高度被固定位360px。
img {height: auto;width: 100%;
}
响应式图片
在使用响应式图片的时候,srcset
定义了图片可以供浏览器选择的尺寸。为了确保图片 width
和 height
可以被设置,每张图片的宽高比必须一致。
<img width="1000" height="1000"src="puppy-1000.jpg"srcset="puppy-1000.jpg 1000w,puppy-2000.jpg 2000w,puppy-3000.jpg 3000w"alt="Puppy with balloons"/>
有时候我们希望展示图片的剪切部分,比如长图的中间正方形区域,为了视觉好看。
<picture><source media="(max-width: 799px)" srcset="puppy-480w-cropped.jpg"><source media="(min-width: 800px)" srcset="puppy-800w.jpg"><img src="puppy-800w.jpg" alt="Puppy with balloons">
</picture>
这样一来图片宽高比就不一致了,浏览器可能更需要针对每一个资源设置特定宽高比。但目前还没有好的解决方案,re-layout
依然存在。
未指定尺寸的广告、嵌入元素、iframe
广告
广告是造成布局偏移的罪魁祸首之一。经常性,这些广告会有动态尺寸,这样会导致糟糕的用户体验,当你在往下浏览页面的时候,广告突然插入一些可见内容。
在广告的生命周期里,很多点可以导致布局偏移:
- 广告容器插入到dom的时候
- 本站代码调整广告容器尺寸的时候
- 广告代码库加载的时候(导致容器尺寸改变)
- 广告内容填充容器的时候(如果最终广告的尺寸不一样,导致容器尺寸变化)
好消息是网站可以采用最佳体验,来减少布局偏移。
- 为广告位静态保留空间。
- 换句话说,在广告代码库加载之前,就给容器加好样式。
- 如果要在内容流中插入广告,在插入之前确保通过保留尺寸来消除布局偏移。如果这些广告在屏幕外加载,则没有这个问题。
- 在视图顶部插入非粘性广告的时候要特别注意。
- 避免折叠预留的空间,如果广告没有返回,可以在该空间展示占位符。
- 通过预留广告所需最大尺寸,来避免布局偏移。
- 这很有效,不过如果广告很小,可能会有大片空白。
- 根据历史数据,给广告加上合适的尺寸。
如果广告不太可能填满,一些网站会发现在初始的时候折叠广告位可以减少布局偏移。很难做到每一次都能给广告位精准的尺寸,除非这个广告是你自己提供的。
为广告位静态保留空间
给广告容器设置固定的样式,避免代码库加载的时候,重新调整广告的尺寸。
要额外注意一下小尺寸的广告,如果预留很大的空间,会导致大片空白。
避免在视图顶部插入广告
根据CLS的计算规则,在顶部插入广告比在中间插入,造成的影响更大。
嵌入元素和iframe
可嵌入的挂件可以允许你在页面上嵌入web内容(例如,youtube视频、谷歌地图、社交媒体的帖子等)。这些嵌入元素可以采用多种形式。
- html fallback,然后js将该fallback转换成嵌入元素
- 内联html代码块
- iframe嵌入
这些嵌入通常不会事先知道嵌入的大小(例如,社交媒体帖子,是否包含图片?视频?或者多行文本?)。结果就是提供嵌入元素的平台经常无法保证预留足够的空间,导致布局偏移。
为了应对这种情况,你可以通过提前计算嵌入元素的足够空间,以最小化CLS。以下工作流可以参考:
- 使用开发者工具检查最终嵌入的高度
- 一旦嵌入元素加载,iframe容器根据内容重新调整尺寸。
记下尺寸,并相应设置嵌入元素占位符的样式。你可能还会用到媒体查询来考虑不同的因素。
动态内容
总而言之,避免在已存在的内容上方插入新内容,除非为了响应用户交互。这样可以保证任何布局偏移都是可预期的。
你可能经常会遇到从顶部或者底部弹出的一些内容。这经常发生在banner或者表单的地方,让页面的剩余内容产生偏移。
- “注册即可领取会员大礼包!”
- “最近发表的文章”
- “安装我们的APP”
- “我们还在接受订单”
- “GDPR提示,是否允许使用cookie”
如果你需要展示以上的UI内容,请提前预留好空间,避免产生布局偏移。
自定义字体(引发FOIT/FOUT)
下载并渲染自定义字体会引发布局偏移,通过以下两种方式:
- fallback字体切换到新字体(FOUT - flash of unstyled text)
- 从不可见变成可见,因为新字体的渲染缘故(FOIT - flash of invisible text)
以下工具可以帮你最小化影响:
font-display
属性可以让你修改自定义字体的渲染表现,通过使用可选值:auto
,swap
,block
,fallback
和optional
。不幸的是,除了optional
之外的属性都会引发re-layout
,通过以上的其中一种方式。- Font Loading API 可以减少获取必要字体的时间。
Chrome 83版本之后,可以采取以下方案:
- 针对关键字体使用
<link rel=preload>
,提高优先级,让字体下载有更高概率赶在fcp之前,这样就能避免布局偏移。 <link rel=preload>
和font-display: optional
结合使用。
动画
总而言之,优先考虑 transform
,而非会影响布局改变的属性。
在更新DOM之前等待网络响应的操作
尽可能的在网络请求时,给一个loading,或者占位符提示,避免用户在这段时间内进行操作。
开发者工具
可以使用lighthouse和performce检测CLS。
总结
- 图片的尺寸,以及其他嵌入元素的尺寸,最开始就设定好,或者预留足够空间,这样可以有效避免布局偏移。
- 利用图片宽高比的属性,可以在优化CLS的同时,做响应式布局。
- 尽可能不要往已存在内容上方添加新内容。
- web字体尽可能早的加载,避免产生FOIT和FOUT
- 与UI同事配合在交互上避免布局偏移
参考
https://web.dev/optimize-cls/
页面视觉稳定性之优化CLS相关推荐
- 喧喧发布 2.5.3 版本,主要提升系统稳定性,优化交互体验
开发四年只会写业务代码,分布式高并发都不会还做程序员? >>> 喧喧是由然之协同团队推出的一款轻量级的开源企业聊天软件.提供企业内部通讯交流.企业通讯录.协同办公通讯交流.企业I ...
- 页面加载速度优化的12个建议
1.合并Js文件和CSS 将JS代码和CSS样式分别合并到一个共享的文件,这样不仅能简化代码,而且在执行JS文件的时候,如果JS文件比较多,就需要进行多次"Get"请求,延长加载速 ...
- MemCache对PHP页面的缓存加速优化
一.MemCache 简介 Memcache 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高了网站访问的速度. ...
- html优化的基本网页布局,网站页面标题的SEO优化及布局要点
在SEO优化中,标题的优化占着举足轻重的地位,无论是从用户体验的角度出发,还是从搜索引擎的排名效果出发,title标题都是页面优化最重要的因素. 对于一个刚入行的站长或SEO来说,首先要搞明白的就是网 ...
- java加快页面加载速度方法_关于页面加载速度优化的11种方法
1.合并js和css文件 将js和css分别合并到一个共享文件,这样不仅能够简化代码,而且在执行js文件是,如果js文件较多,就需要多次向服务器请求数据,这样将会延长加载速度,将js文件合并在一起,减 ...
- web 页面加载速度优化实战-100% 的飞跃提升
前言 一个网站的加载速度有多重要? 反正我相信之前来 博主网站 的人至少有 50% 在加载完成前关闭了本站. 为啥捏? 看图 首页完整加载时间 8.18s,看来能进来看博主网站的人都是真爱呀,哈哈. ...
- 前端页面图片加载优化
前端页面图片加载优化 问题:前端页面如果图片资源过多或者过大就会导致用户加载图片时间过长,导致用户体验下降 我总结的优化思路与方法有以下几种 一.将图标换成icon字体管理 如果项目存在大量的图表用的 ...
- python网页优化_400% 的飞跃-web 页面加载速度优化实战
前言 一个网站的加载速度有多重要? 反正我相信之前来博主网站的人至少有 50% 在加载完成前关闭了本站. 为啥捏? 看图 首页完整加载时间 8.18s,看来能进来看博主网站的人都是真爱呀,哈哈. 正常 ...
- web 页面加载速度优化实战
前言 一个网站的加载速度有多重要? 反正我相信之前来博主网站的人至少有 50% 在加载完成前关闭了本站. 为啥捏? 看图 首页完整加载时间 8.18s ,看来能进来看博主网站的人都是真爱呀,哈哈. ...
- php中seo优化怎么做,专题页面怎么做SEO优化
专题页面做SEO优化的方法:1.网站页面设计优化:2.网站标签优化:3.url优化:4.其他权重标签.链接优化:5.页面更新. 关于单页面优化与专题页面优化,很多seo者都没有进行明确区分,随着更多的 ...
最新文章
- AI一分钟|阿里AI鉴黄师或将取代人类;特斯拉私有化空头潜在利润超10亿美元
- java等待欢迎界面_android welcome欢迎界面3秒后自动跳转
- 《动手学深度学习》 第二天 (线性回归)
- 一家踏实做产品,在疫情下销售增速仍达35%的公司,年报长啥样?
- 实现Android 动态载入APK(Fragment or Activity实现)
- PowerEdge r730xd 安装centos 6.7
- 浙江大学_包家立教授_计算生物学3_贝叶斯算法
- github fork自己的库,如何同步源库的更新
- Linux内核专题 - 介绍
- windows/OpenCV/VS/C++配置
- 月薪达到1万的web前端工程师,都会些什么呢?(附路线资料)
- 01_多操作系统课题研究[2011-01-21]
- orocos安装_动脑共享单车环境搭建
- Win10 清空回收站选项点不了怎么解决?
- LTE网络PCI规划
- Ubuntu 16 AX201网卡安装后无法使用WIFI解决办法
- THREE将左键改为平移右键改为旋转
- Windows10系统自带Microsoft图片发黄
- apmserv mysql5.1启动失败_apmserv启动失败的原因以及解决方法
- 画动漫人物眼睛怎么上色
热门文章
- 12家公司到手9个offer,从微软到谷歌,他都经历了什么
- Chrome源码chromium下载编译详细步骤
- c语言验证费马大定理,数论概论 第四章 高次幂之和与费马大定理 习题解答(宋二娃的BLOG)...
- C/C++ EasyX 立方体与超立方体的投影 与 伸缩和旋转变换
- [ABAP]批量查询工艺路线
- 有人痴狂,有人跑路,开源软件新一年的冰火两重天
- 短篇硬科幻小说《勾股:2.013》
- Java实现P5713 【深基3.例5】洛谷团队系统
- Rhino4.0软件安装教程
- RingBuffer