快速提示:如何修复 Page Speed Insights / Lighthouse 中的“图像元素没有明确的宽度和高度”问题
如果您已经通过Google Lighthouse、Page Speed Insights、web.dev 测量等运行过您的网站,您可能已经看到过“图像元素没有明确的宽度和高度”的操作点。
那么我们该如何解决这个问题呢?
简短的回答
您需要做的就是将图像的原始宽度和高度添加到图像中。
您可以使用width
和height
属性来执行此操作,以像素为单位定义大小。
然后,浏览器就可以计算纵横比(宽度与高度的比率)并在图像加载之前为其分配足够的空间。
因此,对于宽 1600 像素、高 900 像素的图像:
<img width="1600" height="900" src="your-image.jpg">
长答案
让我们举一个典型的例子。
您的 CSS 文件中有以下内容:
img{
width: 100%;
height: auto;
}
这为浏览器提供了足够的信息来计算图像的宽度,因为它可以查看其父容器的宽度并计算图像的宽度。
height: auto
然而,问题就在这里。它没有给图片指定一个明确的高度,而是指示浏览器根据图片的宽度,将图片的高度设置为它认为合适的高度。
问题在于,浏览器在解析 HTML 时并不知道原始图像的宽度或高度。它只有在开始下载时才会知道图像的大小。
因此,会发生以下情况:
- 浏览器下载你的 HTML
- 它找到一个图像元素并查找与其相关的任何样式(您应该将其作为关键 CSS 的一部分内联)
- 然后它渲染图像元素,但不知道高度,因此赋予它 0 像素高度
- 然后它请求图像并发现它是 1600 像素 x 900 像素
- 然后利用这些信息创建 16:9 的宽高比
- 然后,它重新访问之前找到的图像元素,查看计算出的宽度(假设它在屏幕上为 400 像素)并应用纵横比来计算高度(400/16 * 9 = 300px)。
这会导致所谓的“布局偏移”。然后,该偏移会被添加到网站的“累积布局偏移”(CLS)中。
由于这是Google 网络生命力指标的一部分,并且很快就会成为影响您的搜索排名的指标,因此您现在就需要修复它。
如何修复
有几种方法可以解决这个问题,但这里推荐两种方法,其中第一种是首选/最佳实践。
width
选项 1 - 使用和属性定义图像的宽度和高度height
。
height
第一个选项是使用和属性来定义图像的宽度和高度width
。
<img width="1600" height="900" src="some-image.webp">
请注意,属性不包含单位(像素),它们应该定义为整数。
在现代浏览器中,这将用于计算图像的纵横比。
如果您还记得上一节我们描述浏览器中事件的顺序,那么计算纵横比是在图像元素被渲染之后发生的,因为我们还不知道图像的高度。
通过应用width
和属性,浏览器现在可以在呈现图像元素之前height
计算纵横比,并在图像下载后为其保留足够的空间。
使用width
和height
属性是建议的最佳做法,以避免图像的布局偏移。
重要提示:需要注意的一点是,浏览器仍然会遵循您应用的 CSS 大小调整。
因此,如果您像原始 CSS 示例中那样应用它,它仍然可以正常工作并遵循您的 CSS 规则。唯一的区别是它现在可以计算width:100%
所需的大小。height:auto
height: auto
额外提示:另一个有趣的事情是,你的高度和宽度属性只需要正确的宽高比即可。因此,只要宽度和高度的比例相同,以下所有操作都会导致相同的行为:
<img width=1600 height=900>
<img width=800 height=450>
<img width=160 height=90 >
但值得注意的是,建议使用尽可能接近正确的尺寸,以防 CSS 出现问题。
选项 2 - “纵横比框”
这种技术也称为“CSS padding hack”。
我们在这里所做的不是定义图像的宽度和高度,而是将图像的高度定义为 CSS 文件中宽度的百分比。
为了实现这一点,我们赋予图像零像素的高度(记住这是它最初呈现的方式),然后使用它padding-top
在文档中分配正确的空间量以避免布局偏移。
HTML
<div class="image-div"></div>
CSS
.image-div {
overflow: hidden; /* not necessary if div is empty and other styles do not interfere */
height: 0; /* not necessary if div is empty and other styles do not interfere */
padding-top: 56.25%; /*aspect ratio of 16:9 at 100% width requires a 56.25% height*/
background: url(/my-image.webp);
}
或者,如果您不需要支持 Internet Explorer,您可以使用calc()
CSS 使用calc()
.image-div {
overflow: hidden; /* not necessary if div is empty and other styles do not interfere */
height: 0; /* not necessary if div is empty and other styles do not interfere */
padding-top: calc(900 / 1600 * 100%); /*aspect ratio of 16:9, notice how we reverse the values as we are calculating the height from the width this time*/
background: url(/my-image.webp);
}
CSS tricks 中的这篇文章更详细地解释了这种填充技术
你为什么要用这个?
显然,这有点像黑客行为,它要求您在 div 上使用背景图像。
它除了装饰图像之外没有任何用处,因为您无法为alt
使用辅助技术或关闭图像的人定义属性。
但如果你是一个纯粹主义者,它确实具有保持 HTML 清洁的优势......但我不认为这是一个使用它的充分理由!
如果您不知道图像的确切尺寸怎么办?
您可能已经发现了上述两种技术都有一个很大的缺陷。
在设计页面时,您必须知道图像的宽度和高度,以计算纵横比/添加适当的宽度和高度。
显然,解决方案是在后端处理这个问题,并使用缓存技术来存储宽度和高度属性,但这可能行不通。
如果您尝试在包含数千张图像的现有网站上修复此问题,或者您无法计算图像的宽度和高度等,则可能需要做出一些小小的妥协。
固定高度容器
假设您网站上的所有图像的宽高比都介于 1:1 和 16:9 的宽高比之间。
我们可以做的是在所有图像周围添加一个具有固定高度的容器。
这样,浏览器就可以为页面上的容器而不是图像分配空间。
缺点是,对于长宽比不同的图像,容器底部会出现空白。
下面的小提琴演示了这种技术:
我将其添加background-color: #ccc
到容器中以显示额外的空白位置。
这种技术最适合用于网站上的图像具有相似纵横比(例如,一些是 16:9,一些是 16:10)的情况,因为多余的空白不会那么明显。
结论
总而言之,为了获得良好的用户体验并尽快维持您的搜索引擎排名,需要最小化累积布局偏移。
如果您还没有修复您的网站上的这个问题,上面描述的 3 种技术应该可以帮助您修复它。
我建议找到一种方法,在 99% 的情况下自动向图像添加width
和属性。height
唯一会失效的情况是,如果你使用该srcset
属性根据屏幕尺寸(称为艺术指导)提供不同宽高比的图片。在这种情况下,你只能使用媒体查询和 padding hack,或者使用固定高度容器技术。
为了算法!
我的新签字实验!
如果您喜欢这篇文章,请给它一个❤,如果您认为它很特别,请给它一个🦄,最重要的是,不要忘记:
文章来源:https://dev.to/grahamthedev/quick-tips-how-to-fix-image-elements-do-not-have-explicit-width-and-height-in-page-speed-insights-lighthouse-3776给算法留言吧!尤其当你觉得上述技巧行不通的时候😁!