Как оптимизировать прогрессивные веб-приложения: выходя за рамки основ
Опубликовано: 2022-03-10Прогрессивные веб-приложения (PWA) по-прежнему набирают популярность в 2020 году. Это неудивительно, учитывая преимущества более высоких коэффициентов конверсии, вовлеченности клиентов, снижения скорости загрузки страниц и снижения затрат на разработку и накладных расходов.
Мы видим, что уважаемые компании также пользуются успехом со своими PWA, такими как Twitter, Uber, Tinder, Pinterest и Forbes. И все они хвастаются огромными преимуществами внедрения прогрессивных приложений.
Хорошая новость заключается в том, что разработка PWA — это не то, что могут себе позволить только компании с большим бюджетом. Эти приложения в равной степени служат малому и среднему бизнесу, и их не так сложно создать.
Вы можете найти исчерпывающее руководство для начинающих по прогрессивным веб-приложениям в журнале Smashing Magazine, в котором основное внимание уделяется созданию ядра PWA.
Однако давайте сделаем шаг вперед и узнаем, как реализовать современные качества PWA, такие как автономная функциональность, сетевая оптимизация, взаимодействие с пользователем на нескольких устройствах, возможности SEO и ненавязчивые уведомления и запросы. Вы также найдете пример кода или ссылки на более конкретные руководства, чтобы реализовать эти советы в своем PWA.
Краткий обзор прогрессивных веб-приложений (PWA)
Давайте не будем пропускать основы и быстро перейдем к сути PWA.
Что такое PWA?
«Прогрессивные веб-приложения (PWA) создаются и улучшаются с помощью современных API-интерфейсов, чтобы обеспечить расширенные возможности, надежность и простоту установки, а также охватывать всех, в любом месте и на любом устройстве с помощью единой кодовой базы».
— разработчики Google
Другими словами, PWA — это веб-сайты, которые пользователи могут использовать как автономные приложения. Они отличаются от нативных приложений главным образом тем, что PWA не требуют установки и могут использоваться с различными устройствами — нативные приложения в основном создаются для мобильных устройств.
Как работают PWA?
Ядро PWA состоит из трех компонентов: манифеста веб-приложения, рабочих процессов и оболочки приложения. Вы можете найти подробные инструкции по их созданию в упомянутом выше руководстве для начинающих.
Вот что делают эти компоненты.
Манифест веб-приложения
Манифест веб-приложения — это основа для запуска веб-сайта как автономного приложения в полноэкранном режиме. Вы можете определить внешний вид PWA, оптимизировать его для разных устройств и назначить значок, который будет отображаться после установки приложения.
Сервисные работники
Сервисные работники позволяют использовать PWA в автономном режиме, извлекая кэшированные данные или информируя пользователя об отсутствии подключения к Интернету. Сервисные работники также получают последние данные после восстановления соединения с сервером.
Архитектура оболочки приложения
Оболочка приложения — это то, что видят пользователи при доступе к PWA. Это минимум HTML, CSS и JavaScript, необходимый для работы пользовательского интерфейса. При разработке PWA вы можете кэшировать ресурсы и активы оболочки приложения в браузере.
Развертывание современных характеристик в PWA
Помимо основных функций, современные PWA включают в себя дополнительные черты, которые еще больше подталкивают их пользователей к более необычному пользовательскому опыту.
Давайте рассмотрим некоторые конкретные современные характеристики PWA и узнаем, как добавить их в ваше PWA. Следующие качества считаются отличными дополнениями к базовому PWA разработчиками Google.
Приложение работает в автономном режиме так же, как и в Интернете
При создании PWA вы также можете разработать собственную автономную страницу как часть ядра. Однако гораздо удобнее, если ваше PWA продолжает работать даже без подключения к Интернету — до определенного момента, когда подключение становится необходимым. В противном случае пользовательский опыт может быть таким же разочаровывающим, как испытание Анкиты Масанд с заказом торта, как она описывает в своей статье о болевых точках PWA.
Вы можете добиться более значительного взаимодействия с пользователем, используя кешированный контент, фоновую синхронизацию и каркасные экраны. Давайте посмотрим на каждый из них.
Кэшированный контент с IndexedDB
IndexedDB
— это встроенная в браузер система хранения NoSQL, которую вы можете использовать для кэширования и извлечения необходимых данных, чтобы ваше PWA работало в автономном режиме.
Однако не все браузеры поддерживают IndexedDB
, поэтому первое, что вам нужно сделать, это проверить, поддерживает ли его браузер пользователя.
if (!('indexedDB' in window)) { console.log('This browser doesn\'t support IndexedDB'); return; }
После этого вы можете создавать кешированный контент с помощью IndexedDB API. Вот пример от разработчиков Google по открытию базы данных, добавлению хранилища объектов и добавлению элемента в это хранилище.
var db; var openRequest = indexedDB.open('test_db', 1); openRequest.onupgradeneeded = function(e) { var db = e.target.result; console.log('running onupgradeneeded'); if (!db.objectStoreNames.contains('store')) { var storeOS = db.createObjectStore('store', {keyPath: 'name'}); } }; openRequest.onsuccess = function(e) { console.log('running onsuccess'); db = e.target.result; addItem(); }; openRequest.onerror = function(e) { console.log('onerror!'); console.dir(e); }; function addItem() { var transaction = db.transaction(['store'], 'readwrite'); var store = transaction.objectStore('store'); var item = { name: 'banana', price: '$2.99', description: 'It is a purple banana!', created: new Date().getTime() }; var request = store.add(item); request.onerror = function(e) { console.log('Error', e.target.error.name); }; request.onsuccess = function(e) { console.log('Woot! Did it'); }; }
Фоновая синхронизация
Если ваше PWA синхронизирует данные в фоновом режиме, пользователь может выполнять действия в автономном режиме, которые затем выполняются при восстановлении подключения к Интернету. Простой пример — приложение для обмена сообщениями. Пользователь может отправить сообщение в автономном режиме, не дожидаясь его отправки — фоновая синхронизация автоматически отправляет сообщение при восстановлении соединения.
Вот пример того, как Джейк Арчибальд разработал функцию фоновой синхронизации.
// Register your service worker: navigator.serviceWorker.register('/sw.js'); // Then later, request a one-off sync: navigator.serviceWorker.ready.then(function(swRegistration) { return swRegistration.sync.register('myFirstSync'); });
Затем прослушайте событие в /sw.js
:
self.addEventListener('sync', function(event) { if (event.tag == 'myFirstSync') { event.waitUntil(doSomeStuff()); } });
Каркасные экраны
Одним из основных преимуществ использования каркасных экранов является то, что пользователи воспринимают приложение как работающее, а не бездействующее. Пока у пользователя нет соединения, скелетный экран отображает интерфейс без содержимого, которое затем заполняется после восстановления соединения.
В Code My UI есть несколько отличных фрагментов кода, которые вы можете использовать для создания скелетного экрана для вашего PWA.
Оптимизация на основе использования сети
Основное преимущество PWA заключается в том, что оно обеспечивает более быструю работу пользователей. Вы можете дополнительно оптимизировать скорость загрузки, заставив PWA использовать сеть с приоритетом кеша, расставив приоритеты ресурсов и используя адаптивную загрузку в зависимости от качества сети.
Давайте посмотрим, как вы можете разработать их для своего PWA.
Сначала кеш, потом сеть
Использование кэшированного контента в первую очередь позволяет вашему PWA работать в автономном режиме и открывает пользователям доступ к контенту даже в зонах с низким уровнем покрытия сети. Вы можете сделать это, создав сервис-воркер для кэширования контента, а затем извлекая его.
Вот пример от Джеффа Посника о кэшировании статического HTML с помощью сервис-воркеров.
self.addEventListener('fetch', event => { if (event.request.mode === 'navigate') { // See /web/fundamentals/getting-started/primers/async-functions // for an async/await primer. event.respondWith(async function() { // Optional: Normalize the incoming URL by removing query parameters. // Instead of https://example.com/page?key=value, // use https://example.com/page when reading and writing to the cache. // For static HTML documents, it's unlikely your query parameters will // affect the HTML returned. But if you do use query parameters that // uniquely determine your HTML, modify this code to retain them. const normalizedUrl = new URL(event.request.url); normalizedUrl.search = ''; // Create promises for both the network response, // and a copy of the response that can be used in the cache. const fetchResponseP = fetch(normalizedUrl); const fetchResponseCloneP = fetchResponseP.then(r => r.clone()); // event.waitUntil() ensures that the service worker is kept alive // long enough to complete the cache update. event.waitUntil(async function() { const cache = await caches.open('my-cache-name'); await cache.put(normalizedUrl, await fetchResponseCloneP); }()); // Prefer the cached response, falling back to the fetch response. return (await caches.match(normalizedUrl)) || fetchResponseP; }()); } });
Приоритизация ресурсов
По умолчанию PWA имеют более высокую производительность по сравнению с аналогичными нативными приложениями из-за их облегченной природы. Кроме того, поскольку PWA используют кеш браузера, можно указать, какие ресурсы имеют приоритет и должны быть обработаны еще до того, как они будут использованы. В основном это работает со статическими элементами, так как динамический контент требует обновления перед его получением.
Вы можете указать приоритет элементов, используя строку <link>
в HTML. Вы также можете указать файлы сторонних серверов, используя rel=”preconnect”
и rel=”dns-prefetch.”
Максимилиано Фиртман приводит простой пример этого, расставляя приоритеты веб-шрифтов в движке браузера:
<link rel=”preload” as=”font” href=”font.woff” crossorigin>
Внедрение адаптивной загрузки
Интернет-скорости Wi-Fi и 4G доступны не везде, и пользователи по-прежнему выходят в Интернет с соединениями 2G и 3G. Поскольку вы хотите, чтобы ваше PWA было доступно как можно большему количеству людей, вы можете оптимизировать его для работы и при более низких скоростях Интернета.
Этого можно добиться, внедрив адаптивную загрузку, которая загружает элементы PWA в зависимости от типа подключения пользователя.
Самый простой способ — использовать инструмент Google Workbox, который включает в себя множество готовых плагинов для стратегий кэширования.
Предположим, вы хотите определить пользовательскую стратегию кэширования. Вот как это можно сделать на примере Демиана Рензулли и Джеффа Посника:
const adaptiveLoadingPlugin = { requestWillFetch: async ({request}) => { const urlParts = request.url.split('/'); let imageQuality; switch ( navigator && navigator.connection ? navigator.connection.effectiveType : '' ) { //... case '3g': imageQuality = 'q_30'; break; //... } const newUrl = urlParts .splice(urlParts.length - 1, 0, imageQuality) .join('/') .replace('.jpg', '.png'); const newRequest = new Request(newUrl.href, {headers: request.headers}); return newRequest; }, };
Затем передайте плагин стратегии cacheFirst
, содержащей регулярное выражение для сопоставления URL-адресов изображений (например, /img/
):
workbox.routing.registerRoute( new RegExp('/img/'), workbox.strategies.cacheFirst({ cacheName: 'images', plugins: [ adaptiveLoadingPlugin, workbox.expiration.Plugin({ maxEntries: 50, purgeOnQuotaError: true, }), ], }), );
Отличный пользовательский опыт на всех платформах
Превосходный PWA без проблем работает в браузерах, мобильных устройствах и планшетах. Хотя использование устройства Android является наиболее популярным способом (с долей рынка 38,9%) доступа в Интернет, оптимизация вашего приложения для всех платформ является частью разработки основных функций PWA.
Вы можете предпринять дополнительные шаги, чтобы повысить удобство использования и предложить отличный пользовательский интерфейс, например, уменьшить дрожание при загрузке вашего PWA и убедиться, что ваше PWA работает с любым методом ввода.
Вот как вы можете подойти к каждому из этих аспектов.
Уменьшение «прыгающей» загрузки контента
Даже при высокоскоростном Интернете содержимое сайта может смещаться при загрузке, потому что элементы сайта загружаются по порядку. Этот эффект усугубляется при низкой скорости соединения и сильно ухудшает работу пользователя.
Наиболее распространенными элементами, вызывающими смещение содержимого при загрузке, являются изображения, поскольку они обычно больше по размеру и не являются приоритетными при загрузке содержимого. Вы можете решить эту проблему с помощью «ленивой загрузки», используя изображения-заполнители меньшего размера, которым вы можете расставить приоритеты после рендеринга структуры HTML.
Вот пример от разработчиков Mozilla о том, как вы можете добавить облегченное изображение, которое загружается первым перед реальным изображением в JavaScript:
<img src='data/img/placeholder.png' data-src='data/img/SLUG.jpg' alt='NAME'>
Файл app.js
обрабатывает атрибуты data-src следующим образом:
let imagesToLoad = document.querySelectorAll('img[data-src]'); const loadImages = (image) => { image.setAttribute('src', image.getAttribute('data-src')); image.onload = () => { image.removeAttribute('data-src'); }; };
А затем создайте цикл:
imagesToLoad.forEach((img) => { loadImages(img); });
Вы также можете ознакомиться с подробным руководством на Smashing Magazine о том, как уменьшить скачки контента с помощью других элементов.
PWA работает с любым методом ввода
Мы рассмотрели, как PWA должны работать с различными устройствами. Чтобы сделать еще один шаг, вам также необходимо учитывать другие методы ввода, которые пользователи могут использовать на этих устройствах, такие как сенсорный ввод, мышь и стилус.
Добавление Pointer Events API к вашему PWA в основном решает этот вопрос. Вот как вы можете подойти к этому, по словам разработчиков Google.
Сначала проверьте, поддерживает ли браузер события указателя:
if (window.PointerEvent) { // Yay, we can use pointer events! } else { // Back to mouse and touch events, I guess. }
Затем вы можете определить действия, которые могут выполнять различные методы ввода:
switch(ev.pointerType) { case 'mouse': // Do nothing. break; case 'touch': // Allow drag gesture. break; case 'pen': // Also allow drag gesture. break; default: // Getting an empty string means the browser doesn't know // what device type it is. Let's assume mouse and do nothing. break; }
Поскольку в большинстве браузеров уже есть сенсорные функции, вам не нужно ничего добавлять.
Обнаружение через поиск
Одним из ключевых преимуществ PWA по сравнению с родным приложением является то, что PWA по своей природе является веб-сайтом, и поисковые системы могут их индексировать. Это позволяет вам развертывать стратегии SEO, чтобы сделать ваш контент PWA более доступным для обнаружения.
Вы можете начать с обеспечения того, чтобы каждый URL-адрес в вашем PWA имел уникальный описательный заголовок и метаописание, которые являются основой любой деятельности по оптимизации SEO.
Давайте рассмотрим некоторые другие шаги, которые вы можете предпринять, чтобы сделать ваше PWA доступным для поиска.
Проанализируйте возможность поиска вашего PWA
В Google Search Console есть отличный инструмент, который анализирует ваш сайт (PWA) и сообщает о результатах. Вы можете использовать его для выполнения базового сканирования вашего сайта и выявления любых слабых мест, которые вы затем можете начать исправлять.
Кроме того, вы можете использовать Lighthouse в браузере Chrome для проведения SEO-аудита.
Сначала перейдите к целевому URL. Затем нажмите Control+Shift+J
(или Command+Option+J
на Mac), чтобы открыть меню инструментов разработчика. Выберите вкладку Lighthouse, отметьте поле категории SEO и создайте отчет.
Используйте структурированные данные
Поисковая система Google использует структурированные данные, чтобы понять назначение контента на вашей веб-странице.
Структурированные данные — это стандартизированный формат для предоставления информации о странице и классификации содержимого страницы; например, на странице рецептов укажите ингредиенты, время и температуру приготовления, калорийность и т. д.
Прежде чем вы начнете программировать, Google также составил полезный список распространенных ошибок структурированных данных и соответствующие рекомендации по их устранению. Изучение этого материала должно дать вам хорошее представление о том, чего следует избегать.
Фредерик О'Брайен написал отличное руководство для журнала Smashing Magazine « Включение структурированных данных в процесс проектирования» , в котором описывается, как создавать структурированные данные с самого начала.
Удобные уведомления и запросы разрешений
И последнее, но не менее важное: вы можете улучшить взаимодействие с пользователем, оптимизировав уведомления и запросы разрешений, чтобы они служили вашим пользователям, а не просто сбивали с толку и раздражали.
Хотя в целом вы можете полагаться на здравый смысл, есть и практические советы, которые вы также можете реализовать, например, создавать ненавязчивые push-уведомления и давать пользователю возможность отписаться от сообщений.
Тонкие запросы разрешения на общение
Есть два современных способа автоматизировать общение между сайтом и пользователем — чат-боты и уведомления.
В контексте PWA основным преимуществом чат-бота является то, что ему не требуется разрешение пользователя для взаимодействия с пользователем. Однако в зависимости от того, какое приложение чат-бота вы используете, пользователь может пропустить тонкое сообщение. Уведомления, с другой стороны, требуют разрешения пользователя, но они гораздо более заметны.
Поскольку вы можете добавить чат-бота как отдельное стороннее приложение, давайте сосредоточимся на создании удобного для пользователя push-уведомления. Если вам нужно руководство о том, как создать push-уведомление, вот отличное руководство от Indrek Lasn.
Самый простой способ создать ненавязчивый запрос разрешения — использовать двойной запрос. Это означает, что вы включаете пользовательское взаимодействие на свой сайт поверх стандартного взаимодействия с ОС пользователя.
Мэтт Гонт предлагает отличные иллюстрации для этого эффекта со следующими изображениями.
Вот запрос разрешения на уведомление по умолчанию, который не предоставляет контекста:
А вот пользовательское взаимодействие, добавленное перед разрешением уведомления по умолчанию, описанным выше:
Добавляя настраиваемое оповещение перед оповещением ОС по умолчанию, вы можете более четко описать пользователю цель оповещения. Это увеличивает вероятность того, что пользователь подпишется на уведомления вашего сайта.
Разрешить пользователю отказаться от уведомлений
Для пользователя отключение push-уведомлений сайта довольно раздражает, независимо от используемого устройства. Таким образом, предоставление пользователю возможности отказаться от сообщений имеет большое значение с точки зрения пользовательского опыта.
Вот пример от Мэтта Гонта о том, как реализовать функцию отказа от подписки в вашем коде и пользовательском интерфейсе:
Во-первых, определите pushButton
:
pushButton.addEventListener('click', function() { pushButton.disabled = true; if (isSubscribed) { unsubscribeUser(); } else { subscribeUser(); } });
Затем добавьте новую функцию:
function unsubscribeUser() { swRegistration.pushManager.getSubscription() .then(function(subscription) { if (subscription) { // TODO: Tell application server to delete subscription return subscription.unsubscribe(); } }) .catch(function(error) { console.log('Error unsubscribing', error); }) .then(function() { updateSubscriptionOnServer(null); console.log('User is unsubscribed.'); isSubscribed = false; updateBtn(); }); }
Вот как это выглядит в консоли после успешной реализации кнопки подписки для отключения уведомлений, если пользователь выберет.
Заключение
PWA могут быть очень мощными для увеличения трафика вашего сайта и расширения пользовательского опыта. Чтобы еще больше оптимизировать PWA, вы можете использовать эти современные решения, описанные в этой статье, для повышения производительности и функциональности.
Вам также не нужно реализовывать все сразу. Не стесняйтесь выбирать наиболее подходящие варианты, поскольку каждое из этих предложений поможет вам улучшить ваше PWA.
Дополнительные ресурсы
- Обучение прогрессивным веб-приложениям от Google
- Прогрессивные веб-приложения от web.dev
- Прогрессивные веб-приложения (PWA) от Mozilla