Разработка сайтов, которые будут работать быстро везде, может оказаться непростой задачей. Из-за множества возможностей устройств и качества сетей, к которым они подключаются, эта задача может показаться непреодолимой. Хотя мы можем воспользоваться функциями браузера для повышения производительности загрузки, как мы узнаем, на что способно устройство пользователя или качество его сетевого подключения? Решение — подсказки клиенту !
Клиентские подсказки — это набор дополнительных заголовков HTTP-запросов, которые дают нам представление об этих аспектах устройства пользователя и сети, к которой он подключен. Подключаясь к этой стороне информационного сервера, мы можем изменить способ доставки контента в зависимости от состояния устройства и/или сети. Это может помочь нам создать более инклюзивный пользовательский опыт.
Все дело в согласовании контента
Подсказки клиента — это еще один метод согласования контента , который означает изменение ответов контента на основе заголовков запросов браузера.
Один из примеров согласования контента включает заголовок запроса Accept
. Он описывает, какие типы контента понимает браузер и которые сервер может использовать для согласования ответа. Для запросов изображений содержимое заголовка Accept
Chrome следующее:
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Хотя все браузеры поддерживают такие форматы изображений, как JPEG, PNG и GIF, Accept сообщает в этом случае, что браузер также поддерживает WebP и APNG . Используя эту информацию, мы можем договориться о лучших типах изображений для каждого браузера:
<?php
// Check Accept for an "image/webp" substring.
$webp = stristr($_SERVER["HTTP_ACCEPT"], "image/webp") !== false ? true : false;
// Set the image URL based on the browser's WebP support status.
$imageFile = $webp ? "whats-up.webp" : "whats-up.jpg";
?>
<img src="<?php echo($imageFile); ?>" alt="I'm an image!">
Как и Accept
, подсказки клиента — это еще один способ согласования контента, но в контексте возможностей устройства и условий сети. С помощью клиентских подсказок мы можем принимать решения о производительности на стороне сервера, основываясь на индивидуальном опыте пользователя, например, решать, следует ли предоставлять некритические ресурсы пользователям с плохими условиями сети. В этом руководстве мы опишем все доступные подсказки и некоторые способы их использования, чтобы сделать доставку контента более удобной для пользователей.
Согласие
В отличие от заголовка Accept
, клиентские подсказки не появляются просто волшебным образом (за исключением Save-Data
, о котором мы поговорим позже). Чтобы свести к минимуму заголовки запросов, вам необходимо выбрать, какие клиентские подсказки вы хотите получать, отправляя заголовок Accept-CH
когда пользователь запрашивает ресурс:
Accept-CH: Viewport-Width, Downlink
Значение Accept-CH
представляет собой разделенный запятыми список запрошенных подсказок, которые сайт будет использовать при определении результатов для последующего запроса ресурсов. Когда клиент читает этот заголовок, ему сообщается: «Этому сайту нужны подсказки клиента Viewport-Width
и Downlink
». Не беспокойтесь о конкретных подсказках. Мы доберемся до них через минуту.
Вы можете установить эти заголовки на любом языке серверной части. Например, можно использовать функцию header
PHP . Вы даже можете установить эти заголовки с атрибутом http-equiv
в теге <meta>
:
<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />
Все клиентские подсказки!
Подсказки клиента описывают одну из двух вещей: устройство, которое используют ваши пользователи, и сеть, которую они используют для доступа к вашему сайту. Давайте кратко рассмотрим все доступные подсказки.
Подсказки по устройству
Некоторые клиентские подсказки описывают характеристики устройства пользователя, обычно характеристики экрана. Некоторые из них могут помочь вам выбрать оптимальный медиаресурс для экрана конкретного пользователя, но не все из них обязательно медиацентричны.
Прежде чем мы перейдем к этому списку, было бы полезно изучить несколько ключевых терминов, используемых для описания экранов и разрешения мультимедиа:
Внутренний размер: фактические размеры медиаресурса. Например, если вы открываете изображение в Photoshop, размеры, показанные в диалоговом окне размера изображения, описывают его внутренний размер .
Внутренний размер с поправкой на плотность: размеры медиаресурса после корректировки плотности пикселей. Это внутренний размер изображения, разделенный на соотношение пикселей устройства . Например, возьмем такую разметку:
<img
src="whats-up-1x.png"
srcset="whats-up-2x.png 2x, whats-up-1x.png 1x"
alt="I'm that image you wanted."
/>
Допустим, внутренний размер изображения 1x
в этом случае составляет 320x240, а внутренний размер изображения 2x
– 640x480. Если эта разметка анализируется клиентом, установленным на устройстве с соотношением пикселей экранного устройства, равным 2 (например, экран Retina), запрашивается изображение 2x
. Внутренний размер изображения 2x
с поправкой на плотность составляет 320x240, поскольку 640x480, разделенное на 2, равно 320x240.
Внешний размер: размер медиа-ресурса после применения к нему CSS и других факторов макета (таких как атрибуты width
и height
). Допустим, у вас есть элемент <img>
, который загружает изображение с внутренним размером 320x240, скорректированным по плотности, но у него также есть свойства width
и height
CSS с примененными к нему значениями 256px
и 192px
соответственно. В этом примере внешний размер элемента <img>
становится 256x192.
Освоив некоторую терминологию, давайте перейдем к списку доступных вам клиентских подсказок для конкретных устройств.
Ширина области просмотра
Viewport-Width
— это ширина области просмотра пользователя в CSS-пикселях:
Viewport-Width: 320
Эту подсказку можно использовать с другими подсказками, специфичными для экрана, для обеспечения различных обработок (т. е. обрезки) изображения, оптимальных для определенных размеров экрана (т. е. художественного направления ), или для исключения ресурсов, которые не нужны для текущей ширины экрана.
ДНР
DPR
, сокращение от соотношения пикселей устройства, сообщает соотношение физических пикселей к пикселям CSS на экране пользователя:
DPR: 2
Эта подсказка полезна при выборе источников изображения, которые соответствуют плотности пикселей экрана (как это делают дескрипторы x
в атрибуте srcset
).
Ширина
Подсказка Width
появляется при запросах ресурсов изображения, запускаемых тегами <img>
или <source>
с использованием атрибута sizes
. sizes
сообщают браузеру, каким будет внешний размер ресурса; Width
использует этот внешний размер для запроса изображения с внутренним размером, оптимальным для текущего макета.
Например, предположим, что пользователь запрашивает страницу с экраном шириной 320 пикселей CSS с DPR, равным 2. Устройство загружает документ с элементом <img>
, содержащим значение атрибута sizes
85vw
(т. е. 85 % ширины области просмотра). для всех размеров экрана). Если подсказка Width
включена, клиент отправит эту подсказку Width
на сервер с запросом src
<img>
:
Width: 544
В этом случае клиент намекает серверу, что оптимальная внутренняя ширина запрошенного изображения будет равна 85% ширины области просмотра (272 пикселя), умноженной на DPR экрана (2), что равно 544 пикселям.
Этот совет особенно эффективен, поскольку он не только учитывает ширину экрана с поправкой на плотность, но также согласовывает эту важную информацию с внешним размером изображения в макете. Это дает серверам возможность согласовывать ответы изображения, оптимальные как для экрана , так и для макета.
Контент-ДНР
Хотя вы уже знаете, что экраны имеют соотношение пикселей устройства, ресурсы также имеют собственное соотношение пикселей. В простейших случаях использования выбора ресурсов соотношение пикселей между устройствами и ресурсами может быть одинаковым. Но! В случаях, когда используются заголовки DPR
и Width
, внешний размер ресурса может привести к сценариям, в которых они различаются. Здесь в игру вступает подсказка Content-DPR
.
В отличие от других подсказок клиента, Content-DPR
не является заголовком запроса , который будет использоваться серверами, а скорее заголовком ответа , который серверы должны отправлять всякий раз, когда подсказки DPR
и Width
используются для выбора ресурса. Значение Content-DPR
должно быть результатом этого уравнения:
Content-DPR
= [Размер выбранного ресурса изображения] / ([ Width
] / [ DPR
])
Когда отправляется заголовок запроса Content-DPR
, браузер будет знать, как масштабировать данное изображение в соответствии с соотношением пикселей устройства на экране и макетом. Без этого изображения могут не масштабироваться должным образом.
Устройство-Память
Технически это часть API памяти устройства . Device-Memory
показывает приблизительный объем памяти текущего устройства в ГиБ:
Device-Memory: 2
Возможным вариантом использования этой подсказки может быть уменьшение объема JavaScript, отправляемого в браузеры на устройствах с ограниченной памятью, поскольку JavaScript является наиболее ресурсоемким типом контента, который браузеры обычно загружают . Или вы можете отправлять изображения с более низким DPR, поскольку они используют меньше памяти для декодирования.
Сетевые подсказки
API сетевой информации предоставляет еще одну категорию клиентских подсказок, которые описывают производительность сетевого подключения пользователя. На мой взгляд, это самый полезный набор подсказок. С их помощью у нас есть возможность адаптировать взаимодействие с пользователями, изменяя способ доставки ресурсов клиентам при медленных соединениях.
РТТ
Подсказка RTT
предоставляет приблизительное время прохождения туда и обратно в миллисекундах на уровне приложения. Подсказка RTT
, в отличие от RTT транспортного уровня, включает время обработки сервером.
RTT: 125
Этот совет полезен, поскольку задержка играет важную роль в производительности загрузки. Используя подсказку RTT
, мы можем принимать решения на основе реакции сети, что может помочь ускорить доставку всего опыта (например, за счет пропуска некоторых запросов).
Нисходящая линия связи
Хотя задержка важна для производительности загрузки, пропускная способность также имеет значение. Подсказка Downlink
, выраженная в мегабитах в секунду (Мбит/с), показывает приблизительную скорость нисходящего соединения пользователя:
Downlink: 2.5
В сочетании с RTT
Downlink
может быть полезен для изменения способа доставки контента пользователям в зависимости от качества сетевого соединения.
ДЭХ
Подсказка ECT
означает «Эффективный тип соединения» . Его значение представляет собой один из нумерованного списка типов соединения, каждый из которых описывает соединение в определенных диапазонах значений RTT
и Downlink
.
Этот заголовок не объясняет, какой фактический тип соединения — например, он не сообщает, является ли ваш шлюз вышкой сотовой связи или точкой доступа Wi-Fi. Скорее, он анализирует задержку и пропускную способность текущего соединения и определяет, на какой профиль сети оно больше всего похоже. Например, если вы подключаетесь через Wi-Fi к медленной сети, ECT
может быть заполнено значением 2g
, которое является ближайшим приближением к эффективному соединению:
ECT: 2g
Допустимые значения для ECT
: 4g
, 3g
, 2g
и slow-2g
. Эту подсказку можно использовать в качестве отправной точки для оценки качества соединения, а затем уточнять ее с помощью подсказок RTT
и Downlink
.
Сохранить данные
Save-Data
— это не столько подсказка, описывающая состояние сети, сколько предпочтение пользователя, утверждающее, что страницы должны отправлять меньше данных.
Я предпочитаю классифицировать Save-Data
как сетевую подсказку, потому что многие действия, которые вы можете с ней делать, аналогичны другим сетевым подсказкам. Пользователи также могут включить его в средах с высокой задержкой и низкой пропускной способностью. Эта подсказка, если она присутствует, всегда выглядит так:
Save-Data: on
Здесь, в Google, мы говорили о том, что вы можете сделать с помощью Save-Data
. Влияние, которое это может оказать на производительность, может быть глубоким. Это сигнал о том, что пользователи буквально просят вас присылать им меньше вещей! Если вы прислушаетесь к этому сигналу и будете действовать в соответствии с ним, пользователи это оценят.
Связывая все это вместе
Что вы будете делать с клиентскими подсказками, зависит от вас. Поскольку они предлагают так много информации, у вас есть много вариантов. Чтобы пролить свет на некоторые идеи, давайте посмотрим, как советы клиентов могут помочь Sconnie Timber , вымышленной лесозаготовительной компании, расположенной в сельской местности Верхнего Среднего Запада. Как это часто бывает в отдаленных районах , сетевые соединения могут быть ненадежными. Именно здесь такая технология, как клиентские подсказки, может действительно иметь значение для пользователей.
Адаптивные изображения
Все варианты использования адаптивных изображений, кроме самых простых, могут оказаться сложными. Что, если у вас есть несколько вариантов обработки и вариантов одних и тех же изображений для разных размеров экрана и разных форматов? Эта разметка очень быстро становится очень сложной . Легко ошибиться, легко забыть или неправильно понять важные понятия (например, sizes
).
Хотя <picture>
и srcset
несомненно, являются замечательными инструментами, их разработка и поддержка могут занять много времени в сложных случаях использования. Мы можем автоматизировать генерацию разметки, но сделать это также сложно, поскольку функциональность, предоставляемая <picture>
и srcset
, достаточно сложна, поэтому их автоматизацию необходимо выполнять таким образом, чтобы сохранить обеспечиваемую ими гибкость.
Клиентские подсказки могут упростить эту задачу. Согласование ответов изображения с подсказками клиента может выглядеть примерно так:
- Если это применимо к вашему рабочему процессу, сначала выберите обработку изображения (т. е. художественно-ориентированные изображения), проверив подсказку
Viewport-Width
. - Выберите разрешение изображения, проверив подсказку
Width
и подсказкуDPR
, а также выбрав источник, который соответствует размеру макета изображения и плотности экрана (аналогично тому, как дескрипторыx
иw
работают вsrcset
). - Выберите наиболее оптимальный формат файла, который поддерживает браузер (то, что
Accept
помогает нам сделать в большинстве браузеров).
Что касается моего вымышленного клиента лесной компании, я разработал на PHP наивную адаптивную процедуру выбора изображений, которая использует подсказки клиента. Это означало, что вместо отправки этой разметки всем пользователям:
<picture>
<source
srcset="
company-photo-256w.webp 256w,
company-photo-512w.webp 512w,
company-photo-768w.webp 768w,
company-photo-1024w.webp 1024w,
company-photo-1280w.webp 1280w
"
type="image/webp"
/>
<img
srcset="
company-photo-256w.jpg 256w,
company-photo-512w.jpg 512w,
company-photo-768w.jpg 768w,
company-photo-1024w.jpg 1024w,
company-photo-1280w.jpg 1280w
"
src="company-photo-256w.jpg"
sizes="(min-width: 560px) 251px, 88.43vw"
alt="The Sconnie Timber Staff!"
/>
</picture>
Мне удалось свести его к следующему, основываясь на поддержке отдельных браузеров:
<img
src="/image/sizes:true/company-photo.jpg"
sizes="(min-width: 560px) 251px, 88.43vw"
alt="SAY CHEESY PICKLES."
/>
В этом примере URL-адрес /image
представляет собой PHP-скрипт, за которым следуют параметры, переписанные mod_rewrite . Требуется имя файла изображения и дополнительные параметры, чтобы помочь внутреннему сценарию выбрать лучшее изображение в данных условиях.
Я чувствую : «Но разве это не просто переопределение <picture>
и srcset
на серверной части?» это ваш первый вопрос.
В каком-то смысле да, но с важным отличием: когда приложение использует подсказки клиента для подготовки ответов мультимедиа, большую часть (если не всю) работу гораздо проще автоматизировать, включая службу (например, CDN), которая может сделать это от вашего имени. В то время как в случае с HTML-решениями необходимо писать новую разметку для каждого варианта использования. Конечно, вы можете автоматизировать создание разметки. Однако если ваш проект или требования изменятся, есть большая вероятность, что вам придется пересмотреть свою стратегию автоматизации в будущем.
Клиентские подсказки позволяют начать с изображения с высоким разрешением без потерь, размер которого затем можно динамически изменять, чтобы он был оптимален для любой комбинации экрана и макета. В отличие от srcset
, который требует от вас перечисления фиксированного списка возможных изображений-кандидатов, из которых браузер может выбирать, этот подход может быть более гибким. Хотя srcset
заставляет вас предлагать браузерам грубый набор вариантов — скажем, 256w
, 512w
, 768w
и 1024w
— решение на основе клиентских подсказок может обслуживать любую ширину без гигантской кучи разметки.
Конечно, вам не обязательно писать логику выбора изображений самостоятельно. Cloudinary использует клиентские подсказки для создания ответов изображений при использовании параметра w_auto
и заметила, что в среднем пользователи загружали на 42 % меньше байтов при использовании браузеров, поддерживающих клиентские подсказки.
Но будьте осторожны! Изменения в настольной версии Chrome 67 убрали поддержку подсказок для клиентов из разных источников . К счастью, эти ограничения не влияют на мобильные версии Chrome, и они будут полностью сняты для всех платформ, когда работа над Feature Policy будет завершена.
Помощь пользователям в медленных сетях
Адаптивная производительность — это идея, согласно которой мы можем корректировать способ доставки ресурсов на основе информации, которую нам предоставляет клиент; в частности, информация о текущем состоянии сетевого подключения пользователя.
Что касается сайта Sconnie Timber, мы предпринимаем шаги, чтобы снизить нагрузку, когда сети работают медленно, с помощью заголовков Save-Data
, ECT
, RTT
и Downlink
, проверяемых в нашем внутреннем коде. Когда это будет сделано, мы создадим показатель качества сети, который можно использовать, чтобы определить, следует ли вмешаться для улучшения пользовательского опыта. Эта оценка сети находится в диапазоне от 0
до 1
, где 0
— наихудшее возможное качество сети, а 1
— лучшее.
Изначально проверяем наличие Save-Data
. Если да, то оценка устанавливается на 0
, поскольку мы предполагаем, что пользователь хочет, чтобы мы сделали все необходимое, чтобы сделать работу проще и быстрее.
Однако если Save-Data
отсутствует, мы двигаемся дальше и взвешиваем значения подсказок ECT
, RTT
и Downlink
, чтобы вычислить оценку, описывающую качество сетевого соединения. Исходный код генерации оценки сети доступен на Github. Вывод таков: если мы каким-то образом воспользуемся подсказками, связанными с сетью, мы сможем улучшить взаимодействие с теми, кто работает в медленных сетях.
Когда сайты адаптируются к информации, которую предоставляют клиенты, нам не нужно применять подход «все или ничего». Мы можем разумно решить, какие ресурсы отправить. Мы можем изменить нашу адаптивную логику выбора изображений, чтобы отправлять изображения более низкого качества для данного дисплея, чтобы ускорить загрузку при плохом качестве сети.
В этом примере мы можем увидеть влияние подсказок клиента на повышение производительности сайтов в медленных сетях. Ниже приведен водопад WebPagetest для сайта в медленной сети, который не адаптируется к подсказкам клиента:
А теперь водопад для того же сайта при том же медленном соединении, только на этот раз сайт использует клиентские подсказки для исключения некритичных ресурсов страницы:
Клиентские подсказки сократили время загрузки страницы с более чем 45 секунд до менее чем одной десятой этого времени . Преимущества клиентских подсказок в этом сценарии невозможно переоценить, и они могут стать серьезным подспорьем для пользователей, ищущих важную информацию в медленных сетях.
Более того, можно использовать клиентские подсказки, не нарушая работу браузеров, которые их не поддерживают. Например, если мы хотим настроить доставку ресурсов в соответствии со значением подсказки ECT
, сохраняя при этом полную функциональность для неподдерживающих браузеров, мы можем установить возврат к значению по умолчанию, например:
// Set the ECT value to "4g" by default.
$ect = isset($_SERVER["HTTP_ECT"]) ? $_SERVER["HTTP_ECT"] : "4g";
Здесь "4g"
представляет собой сетевое соединение высочайшего качества, описанное в заголовке ECT
. Если мы инициализируем $ect
как "4g"
, это не повлияет на браузеры, которые не поддерживают подсказки клиента. Подпишитесь!
Берегите эти тайники!
Всякий раз, когда вы меняете ответ на основе HTTP-заголовка, вам необходимо знать, как кэши будут обрабатывать будущие выборки этого ресурса. Заголовок Vary
здесь незаменим, поскольку он связывает записи кэша со значением предоставленных ему заголовков запроса. Проще говоря, если вы изменяете какой-либо ответ на основе заданного заголовка HTTP-запроса, вам почти всегда следует включать этот заголовок запроса в Vary
следующим образом:
Vary: DPR, Width
Однако здесь есть большое предостережение: никогда не следует Vary
кэшируемые ответы на часто меняющийся заголовок (например, Cookie
), поскольку эти ресурсы становятся фактически некэшируемыми. Зная это, вы, возможно, захотите избежать Vary
заголовков подсказок клиента, таких как RTT
или Downlink
, поскольку это факторы соединения, которые могут меняться довольно часто. Если вы хотите изменить ответы на эти заголовки, рассмотрите возможность ввода только заголовка ECT
, что сведет к минимуму промахи в кэше.
Конечно, это применимо только в том случае, если вы изначально кэшируете ответ. Например, вы не будете кэшировать ресурсы HTML, если их содержимое является динамическим, поскольку это может испортить взаимодействие с пользователем при повторных посещениях. В подобных случаях не стесняйтесь изменять такие ответы по любому основанию, которое вы считаете необходимым, и не беспокойтесь о Vary
.
Клиентские подсказки в сервис-воркерах
Согласование контента больше не только для серверов! Поскольку сервисные работники действуют как прокси между клиентами и серверами, вы можете контролировать доставку ресурсов через JavaScript. Сюда входят подсказки для клиента. В событии fetch
сервисного работника вы можете использовать метод request.headers.get
объекта event
для чтения заголовков запроса ресурса следующим образом:
self.addEventListener('fetch', (event) => {
let dpr = event.request.headers.get('DPR');
let viewportWidth = event.request.headers.get('Viewport-Width');
let width = event.request.headers.get('Width');
event.respondWith(
(async function () {
// Do what you will with these hints!
})(),
);
});
Любой заголовок клиентской подсказки, который вы выберете, можно прочитать таким образом. Хотя это не единственный способ получить некоторую информацию. Подсказки, специфичные для сети, можно прочитать в этих эквивалентных свойствах JavaScript в объекте navigator
:
Подсказка клиенту | JS-эквивалент |
---|---|
`ECT` | `navigator.connection.efficientType` |
`РТТ` | `navigator.connection.rtt` |
`Сохранить-Данные` | `navigator.connection.saveData` |
`Нисходящая линия связи` | `navigator.connection.downlink` |
`Устройство-Память` | `navigator.deviceMemory` |
Поскольку эти API доступны не везде, вам нужна проверка функций с помощью оператора in
:
if ('connection' in navigator) {
// Work with netinfo API properties in JavaScript!
}
Отсюда вы можете использовать логику, аналогичную той, которую вы использовали бы на сервере, за исключением того, что вам не нужен сервер для согласования содержимого с подсказками клиента. Только сервисные работники могут сделать взаимодействие более быстрым и устойчивым благодаря дополнительной возможности обслуживать контент, когда пользователь находится в автономном режиме.
Подведение итогов
Благодаря клиентским подсказкам у нас есть возможность сделать работу пользователей быстрее и прогрессивнее. Мы можем обслуживать мультимедиа на основе возможностей устройства пользователя таким образом, чтобы предоставление адаптивных изображений было проще, чем использование <picture>
и srcset
, особенно для сложных случаев использования. Это позволяет нам не только сократить время и усилия на стороне разработки, но и оптимизировать ресурсы — особенно изображения — таким образом, чтобы более точно ориентироваться на экраны пользователей, чем
Возможно, что еще важнее, мы можем выявлять плохие сетевые соединения и устранять проблемы для пользователей, изменяя то, что мы отправляем, и то, как мы это отправляем. Это может существенно облегчить доступ к сайтам для пользователей в нестабильных сетях. В сочетании с сервисными работниками мы можем создавать невероятно быстрые сайты, доступные в автономном режиме.
Хотя клиентские подсказки доступны только в Chrome и браузерах на основе Chromium, их можно использовать таким образом, чтобы не обременять браузеры, которые их не поддерживают. Рассмотрите возможность использования клиентских подсказок для создания по-настоящему инклюзивного и адаптируемого опыта, учитывающего возможности устройств каждого пользователя и сети, к которым они подключаются. Будем надеяться, что другие производители браузеров увидят их ценность и проявят намерение внедрить их.
Ресурсы
- Автоматически адаптивные изображения с подсказками для клиентов
- Клиентские подсказки и адаптивные изображения: что изменилось в Chrome 67
- Возьмите (клиенту) подсказку! ( Слайды )
- Создание быстрых и легких приложений с помощью
Save-Data
Благодарим Илью Григорика , Эрика Портиса , Джеффа Посника , Йоава Вайса и Эстель Вейль за их ценные отзывы и правки в этой статье.