img srcset, браузер выбирает слишком большие изображения
Это изображение srcset, сгенерированное Gatsby:
<source type="image/webp" srcset="
/static/be21c7dd0d11c74c18530fc39aefa922/10917/mailboxes.webp 200w,
/static/be21c7dd0d11c74c18530fc39aefa922/21f2d/mailboxes.webp 400w,
/static/be21c7dd0d11c74c18530fc39aefa922/fdc6a/mailboxes.webp 800w,
/static/be21c7dd0d11c74c18530fc39aefa922/e7f3d/mailboxes.webp 1200w,
/static/be21c7dd0d11c74c18530fc39aefa922/faacb/mailboxes.webp 1600w,
/static/be21c7dd0d11c74c18530fc39aefa922/acdd2/mailboxes.webp 1800w"
sizes="(max-width: 800px) 100vw, 800px">
Мое изображение отображается в контейнере шириной не более 800 пикселей, поэтому я бы предпочел браузеру выбрать:
if screenWidth > 400 then choose 800w
if screenWidth > 200 then choose 400w
else choose 200w
Тем не менее, браузер фактически всегда выбирает максимально возможное изображение (даже если я изменю размер браузера до 200 по ширине).
Я считаю, что проблема здесь:
sizes="(max-width: 800px) 100vw, 800px"
Там должно быть примерно 3 условия, верно? Вместо этого есть только 1 условие. Я не уверен, что могу даже интерпретировать, что это условие пытается попросить браузер.
Ниже мой код GraphQL:
edges {
node {
excerpt
fields {
slug
prefix
}
frontmatter {
title
tags
cover {
children {
... on ImageSharp {
fluid(maxWidth: 800, maxHeight: 360, traceSVG: { color: "#f9ebd2" }) {
...GatsbyImageSharpFluid_withWebp_tracedSVG
}
}
}
}
}
}
}
Фрагмент ...GatsbyImageSharpFluid_withWebp_tracedSVG
генерирует srcset
а также sizes
, В документации нет ничего, что я мог бы сделать, чтобы повлиять на то, как они генерируются. Тем не менее, я мог бы потенциально манипулировать ими на более позднем этапе:
<Picture fluid={fluid} />
Должен ли я манипулировать fluid.sizes
на данный момент, или есть менее грязный способ исправить srcset?
2 ответа
Оказывается, изображение с высоким разрешением было загружено, потому что я использовал устройство с высоким DPI. Так что это работало как задумано.
Веб-браузер применяется devicePixelRatio
к его расчетам при выборе изображения для показа. Например, если devicePixelRatio == 2, то устройство имеет в 2 раза больше типичных пикселей (относительно физической ширины устройства и физического расстояния до пользователя). Когда браузер хочет визуализировать на этом устройстве изображение шириной 800 пикселей, ему действительно нужно изображение шириной 1600 пикселей, чтобы оно хорошо выглядело на этом дисплее с высоким DPI.
Браузер фактически следовал sizes
править. Адаптировано из ответа Дерека:
(max-width: 800px) 100vw -> If viewport < 800px, use (100vw * devicePixelRatio)
800px -> By default use (800px * devicePixelRatio)
Вам не нужно вручную изменять сгенерированный объект флюида, вы можете передать опцию при запросе изображений следующим образом:
{
file(ext: {
eq: ".png"
}) {
childImageSharp {
fluid(maxWidth: 800, sizes: "(min-width: 400px) 800px ,(min-width: 200px) 400px, 200px") {
srcSet
sizes
}
}
}
}
размеры ="(максимальная ширина: 800px) 100vw, 800px"
Это размеры по умолчанию, созданные gatsby-plugin-sharp
для плавного изображения. Есть 2 правила:
(max-width: 800px) 100vw -> If viewport < 800px, use 100vw
800px -> By default use 800px
Так что браузер должен... всегда использовать 800px? Возможно, ваше правило должно быть таким:
(min-width: 400px) 800px, <-- if > 400, use 800px
(min-width: 200px) 400px, <-- if > 200, use 400px
200px <-- else use 200px
Некоторые ресурсы:
Адаптивные изображения сделаны правильно: руководство и руководство