Создание быстрых и легких приложений с помощью данных сохранения

Дэйв Гаш
Dave Gash
Илья Григорик
Ilya Grigorik

Заголовок запроса подсказки клиента Save-Data доступный в браузерах Chrome, Opera и Yandex, позволяет разработчикам предоставлять более легкие и быстрые приложения пользователям, которые включили режим сохранения данных в своем браузере.

Необходимость в облегченных страницах

Статистика Weblight

Все согласны с тем, что более быстрые и легкие веб-страницы обеспечивают более удовлетворительный пользовательский опыт, позволяют лучше понимать и сохранять контент, а также обеспечивают увеличение конверсий и доходов. Исследования Google показали, что «…оптимизированные страницы загружаются в четыре раза быстрее исходной страницы и используют на 80% меньше байтов. Поскольку эти страницы загружаются намного быстрее, мы также увидели 50%-ное увеличение трафика на эти страницы».

И хотя количество подключений 2G наконец-то снижается , 2G по-прежнему оставалась доминирующей сетевой технологией в 2015 году. Проникновение и доступность сетей 3G и 4G быстро растут, но связанные с этим расходы на владение и сетевые ограничения по-прежнему остаются существенным фактором для сотен миллионов пользователей.

Это веские аргументы в пользу оптимизации страницы.

Существуют альтернативные методы повышения скорости сайта без прямого участия разработчика, такие как прокси-браузеры и службы перекодирования. Хотя такие службы довольно популярны, у них есть существенные недостатки — простое (а иногда и неприемлемое) сжатие изображений и текста, невозможность обработки защищенных (HTTPS) страниц, оптимизация только страниц, посещаемых через результаты поиска, и многое другое. Сама популярность этих служб является показателем того, что веб-разработчики не удовлетворяют должным образом высокий спрос пользователей на быстрые и легкие приложения и страницы. Но достижение этой цели — сложный и иногда трудный путь.

Заголовок запроса Save-Data

Один довольно простой метод — позволить браузеру помочь, используя заголовок запроса Save-Data . Определив этот заголовок, веб-страница может настроить и предоставить оптимизированный пользовательский опыт для пользователей с ограничениями по стоимости и производительности.

Поддерживаемые браузеры (ниже) позволяют пользователю включить *режим сохранения данных, который дает браузеру разрешение применять набор оптимизаций для уменьшения объема данных, необходимых для отображения страницы. Когда эта функция представлена ​​или объявлена, браузер может запрашивать изображения с более низким разрешением, откладывать загрузку некоторых ресурсов или направлять запросы через службу, которая применяет другие оптимизации, специфичные для контента, такие как сжатие ресурсов изображений и текста.

Поддержка браузера

Обнаружение настройки Save-Data

Чтобы определить, когда предоставлять пользователям "легкий" опыт, ваше приложение может проверить наличие заголовка запроса клиентской подсказки Save-Data . Этот заголовок запроса указывает на предпочтение клиента в отношении сокращенного использования данных из-за высоких затрат на передачу, низкой скорости соединения или других причин.

When the user enables the data saving mode in their browser, the browser appends the Save-Data request header to all outgoing requests (both HTTP and HTTPS). As of this writing, the browser only advertises one * on - token in the header ( Save-Data: on ), but this may be extended in the future to indicate other user preferences.

Кроме того, можно определить, включено ли Save-Data в JavaScript:

if ('connection' in navigator) {
  if (navigator.connection.saveData === true) {
    // Implement data saving operations here.
  }
}

Проверка наличия объекта connection в объекте navigator имеет жизненно важное значение, поскольку он представляет API сетевой информации, который реализован только в браузерах Chrome, Chrome для Android и Samsung Internet. Оттуда вам нужно только проверить, равен ли navigator.connection.saveData значению true , и вы можете реализовать любые операции по сохранению данных в этом состоянии.

Заголовок Save-Data, показанный в инструментах разработчика Chrome, изображен вместе с расширением Data Saver.
Включение расширения Data Saver в Chrome для ПК.

Если ваше приложение использует service worker , оно может проверять заголовки запросов и применять соответствующую логику для оптимизации опыта. В качестве альтернативы сервер может искать объявленные предпочтения в заголовке запроса Save-Data и возвращать альтернативный ответ — другую разметку, меньшие изображения и видео и т. д.

Советы по внедрению и передовой опыт

  1. При использовании Save-Data предоставьте некоторые устройства пользовательского интерфейса, которые поддерживают его и позволяют пользователям легко переключаться между вариантами. Например:
    • Сообщите пользователям о поддержке функции Save-Data и порекомендуйте им ее использовать.
    • Позвольте пользователям определять и выбирать режим с помощью соответствующих подсказок и интуитивно понятных кнопок включения/выключения или флажков.
    • При выборе режима экономии данных сообщите об этом и предоставьте простой и очевидный способ его отключения и возврата к полному функционалу при желании.
  2. Помните, что легкие приложения не являются менее важными приложениями. Они не упускают важные функции или данные, они просто более осведомлены о связанных с этим расходах и пользовательском опыте. Например:
    • Приложение фотогалереи может предоставлять предварительный просмотр с более низким разрешением или использовать менее обременительный по коду механизм карусели.
    • Поисковое приложение может возвращать меньше результатов за раз, ограничивать количество результатов с большим объемом мультимедийной информации или уменьшать количество зависимостей, необходимых для отображения страницы.
    • Сайт, ориентированный на новости, может показывать меньше историй, исключать менее популярные категории или предоставлять меньшие по объему анонсы медиаматериалов.
  3. Предоставьте серверную логику для проверки заголовка запроса Save-Data и рассмотрите возможность предоставления альтернативного, более легкого ответа страницы, если он включен, — например, сократите количество требуемых ресурсов и зависимостей, примените более агрессивное сжатие ресурсов и т. д.
    • Если вы обслуживаете альтернативный ответ на основе заголовка Save-Data , не забудьте добавить его в список Vary — Vary: Save-Data — чтобы сообщить кэшам вышестоящего уровня, что они должны кэшировать и обслуживать эту версию только при наличии заголовка запроса Save-Data . Для получения более подробной информации см. рекомендации по взаимодействию с кэшами .
  4. Если вы используете service worker, ваше приложение может определить, когда опция сохранения данных включена, проверив наличие заголовка запроса Save-Data или проверив значение свойства navigator.connection.saveData . Если включено, рассмотрите, можно ли переписать запрос, чтобы получить меньше байтов, или использовать уже полученный ответ.
  5. Рассмотрите возможность дополнения Save-Data другими сигналами, такими как информация о типе и технологии подключения пользователя (см. NetInfo API ). Например, вы можете захотеть предоставить облегченный опыт любому пользователю с подключением 2G, даже если Save-Data не включен. И наоборот, то, что пользователь находится на «быстром» подключении 4G, не означает, что он не заинтересован в сохранении данных — например, в роуминге. Кроме того, вы можете дополнить наличие Save-Data клиентской подсказкой Device-Memory для дальнейшей адаптации к пользователям на устройствах с ограниченной памятью. Память пользовательского устройства также объявляется в клиентской подсказке navigator.deviceMemory .

Рецепты

То, чего вы можете достичь с помощью Save-Data , ограничено только тем, что вы можете придумать. Чтобы дать вам представление о том, что возможно, давайте рассмотрим несколько вариантов использования. Вы можете придумать другие варианты использования, пока читаете это, так что не стесняйтесь экспериментировать и смотреть, что возможно!

Проверка наличия Save-Data в коде на стороне сервера

Хотя состояние Save-Data можно обнаружить в JavaScript с помощью свойства navigator.connection.saveData , иногда предпочтительнее обнаружить его на стороне сервера. В некоторых случаях JavaScript может не выполняться. Кроме того, обнаружение на стороне сервера — единственный способ изменить разметку перед ее отправкой клиенту, что задействовано в некоторых наиболее полезных случаях использования Save-Data .

Конкретный синтаксис для обнаружения заголовка Save-Data в коде на стороне сервера зависит от используемого языка, но основная идея должна быть одинаковой для любого бэкенда приложения. Например, в PHP заголовки запросов хранятся в суперглобальном массиве $_SERVER в индексах, начинающихся с HTTP_ . Это означает, что вы можете обнаружить заголовок Save-Data , проверив существование и значение переменной $_SERVER["HTTP_SAVE_DATA"] следующим образом:

// false by default.
$saveData = false;

// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
  // `Save-Data` detected!
  $saveData = true;
}

Если вы установите эту проверку до того, как какая-либо разметка будет отправлена ​​клиенту, переменная $saveData будет содержать состояние Save-Data и будет доступна для использования в любом месте страницы. Проиллюстрировав этот механизм, давайте рассмотрим несколько примеров того, как мы можем использовать его для ограничения объема данных, отправляемых пользователю.

Показывать изображения с низким разрешением для экранов с высоким разрешением

Распространенный вариант использования изображений в Интернете подразумевает обслуживание изображений в наборах по два: одно изображение для «стандартных» экранов (1x) и другое изображение, которое в два раза больше (2x) для экранов с высоким разрешением (например, Retina Display ). Этот класс экранов с высоким разрешением не обязательно ограничивается высокопроизводительными устройствами и становится все более распространенным. В случаях, когда предпочтительнее более легкий опыт использования приложения, может быть разумным отправлять на эти экраны изображения с более низким разрешением (1x), а не с более крупными (2x) вариантами. Чтобы добиться этого при наличии заголовка Save-Data , мы просто изменяем разметку, которую отправляем клиенту:

if ($saveData === true) {
  // Send a low-resolution version of the image for clients specifying `Save-Data`.
  ?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
  // Send the usual assets for everyone else.
  ?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}

Этот вариант использования — прекрасный пример того, как мало усилий требуется, чтобы удовлетворить кого-то, кто специально просит вас отправлять им меньше данных. Если вам не нравится изменять разметку на бэкенде, вы также можете достичь того же результата, используя модуль перезаписи URL, такой как mod_rewrite от Apache . Есть примеры того, как добиться этого с относительно небольшой настройкой.

Эту концепцию можно также распространить на свойства background-image CSS, просто добавив класс к элементу <html> :

<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">

Отсюда вы можете указать класс save-data на элементе <html> в вашем CSS, чтобы изменить способ доставки изображений. Вы можете отправлять фоновые изображения с низким разрешением на экраны с высоким разрешением, как показано в приведенном выше примере HTML, или вообще опустить определенные ресурсы.

Исключите ненужные изображения

Некоторый контент изображений в Интернете просто необязателен. Хотя такие изображения могут быть приятным дополнением к контенту, они могут быть нежелательны для тех, кто пытается выжать все, что можно из тарифных планов. В том, что, возможно, является самым простым вариантом использования Save-Data , мы можем использовать код обнаружения PHP из более раннего примера и вообще опустить необязательную разметку изображений:

<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
  // Only send this image if `Save-Data` hasn't been detected.
  ?><img src="meme.jpg" alt="One does not simply consume data."><?php
}

Этот метод, безусловно, может иметь выраженный эффект, как вы можете видеть на рисунке ниже:

Сравнение некритических изображений, загружаемых при отсутствии Save-Data, с теми же изображениями, которые пропускаются при наличии Save-Data.
Сравнение загрузки некритических изображений при отсутствии Save-Data и пропуска тех же изображений при наличии Save-Data.

Конечно, пропуск изображений — не единственная возможность. Вы также можете использовать Save-Data , чтобы отказаться от отправки других некритических ресурсов, таких как определенные шрифты.

Исключите ненужные веб-шрифты

Хотя веб-шрифты обычно не составляют почти столько же полезной нагрузки страницы, сколько изображения, они все еще довольно популярны. Они также не потребляют незначительное количество данных . Более того, способ, которым браузеры извлекают и отображают шрифты, сложнее, чем вы могли бы подумать, с такими концепциями, как FOIT , FOUT и эвристика браузера, делающими отображение тонкой операцией.

Тогда может быть разумно, что вы захотите убрать ненужные веб-шрифты для пользователей, которые хотят более компактного пользовательского опыта. Save-Data делает это достаточно безболезненным.

Например, предположим, что вы включили Fira Sans из Google Fonts на свой сайт. Fira Sans — отличный шрифт для основного текста, но, возможно, он не так уж важен для пользователей, пытающихся сохранить данные. Добавив класс save-data к элементу <html> при наличии заголовка Save-Data , мы можем написать стили, которые сначала вызывают необязательный шрифт, но затем отказываются от него при наличии заголовка Save-Data :

/* Opt into web fonts by default. */
p,
li {
  font-family: 'Fira Sans', 'Arial', sans-serif;
}

/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
  font-family: 'Arial', sans-serif;
}

Используя этот подход, вы можете оставить фрагмент <link> из Google Fonts на месте, потому что браузер спекулятивно загружает ресурсы CSS (включая веб-шрифты), сначала применяя стили к DOM, а затем проверяя, вызывают ли какие-либо элементы HTML какие-либо ресурсы в таблице стилей. Если кто-то пройдет мимо с включенным Save-Data , Fira Sans никогда не загрузится, потому что стилизованный DOM никогда его не вызывает. Вместо этого включится Arial. Он не такой хороший, как Fira Sans, но может быть предпочтительнее для тех пользователей, которые пытаются растянуть свои тарифные планы.

Краткое содержание

Заголовок Save-Data не имеет особых нюансов: он либо включен, либо выключен, и приложение несет бремя предоставления соответствующих возможностей на основе его настроек, независимо от причины.

Например, некоторые пользователи могут не разрешать режим сохранения данных, если они подозревают, что будет потеря контента или функций приложения, даже в ситуации с плохим подключением. И наоборот, некоторые пользователи могут включить его как нечто само собой разумеющееся, чтобы сделать страницы как можно более маленькими и простыми, даже в ситуации с хорошим подключением. Лучше всего, чтобы ваше приложение предполагало, что пользователь хочет полный и неограниченный опыт, пока вы не получите четкого указания на иное посредством явного действия пользователя.

Как владельцы сайтов и веб-разработчики, давайте возьмем на себя ответственность за управление нашим контентом, чтобы улучшить пользовательский опыт для пользователей, ограниченных в данных и расходах.

Более подробную информацию о Save-Data и прекрасные практические примеры см. в статье Помогите своим пользователям Save Data .