PWA Progressive Web Apps своими руками. Продолжаем ускорять сайт

PWA — это своего рода приложение, устанавливаемое из браузера, которое может предоставить дополнительные функции, основанные на возможностях используемого устройства: сайт может работать автономно оффлайн, делать push-уведомления и выглядеть и работать почти так же быстро, как и отдельное приложение.

Разработчики имеют возможность создавать практически первоклассные приложения с использованием веб-технологий, что всегда значительно проще и дешевле в обслуживании, чем создание собственных приложений. Особенное преимущество PWA — кроссплатформенность. Также одним из преимуществ можно выделить отсутвие необходимости готовое приложение регистрировать в маркетах приложений (таких как Google Play Маркет и App Store), так как приложение устанавливается на телефоне прямо из браузера).

Таким образом PWA — это веб-сайт, который разработан с использованием технологий, что делают опыт взаимодействия с контентом сайта на мобильных устройствах намного приятнее, чем с обычным сайтом, оптимизированном под мобильные устройства. В то же время PWA работает почти как нативное приложение, так как обладает следующими функциями:

— Работа в оффлайне
— Быстрая загрузка
— Работа по защищенному протоколу
— Умеет в push-уведомления
-Может выглядеть как полноценное приложение без строки адреса в браузере

Если это Вордпресс, не морочим голову ставим плагин https://wordpress.org/plugins/super-progressive-web-apps/
В исхоДном коде WP подсматриваем как выглядит идеальный manifest

  • Иначе по инструкции:
    — Переносим в корень проекта sw.js (берем тут https://github.com/nofikoff/progressive_web_app)
    — Режем иконки с помощью сервиса https://www.favicon-generator.org/ подключаем их в head проекта. (не забудь 512х512)
    — Создаем манифест, подключаем его в head проекта <link rel=»manifest» href=»/manifest.json»>
    — В head проекта указываем
<script>
if (navigator.serviceWorker.controller) {
console.log('[PWA Builder] active service worker found, no need to register')
} else {
navigator.serviceWorker.register('sw.js', {
scope: './'
}).then(function(reg) {
console.log('Service worker has been registered for scope:'+ reg.scope);
});
}
</script>

Тестируем PWA через

— Хром / аудит
— https://www.pwabuilder.com/ здесь тюнинг и дополнительные фичи

SEO оптимизация картинок ресайз автоматом по User-agent посетителя

Данный скрипт повышает на несколько процентов оценку скорости для мобильной версии сайта по https://developers.google.com/speed/pagespeed/insights/

  1.  От CMS не зависит, т.к. сам выбирает из всех запросов на сервер только картинки
  2. PHP ресайзит картинок шире 375px до указанного размера на основании заголовка мобильной версии браузера.

php файл берем здесь: https://github.com/nofikoff/image_optimyze

.htaccess добавить строки:

## РЕСАЙЗИМ КАРТИНКИ С КЭШЕМ by Novikov
RewriteEngine On 
RewriteCond %{HTTP_USER_AGENT} ^.*(Android|BlackBerry|Phone).*$ [NC]
RewriteCond %{REQUEST_URI} ^(.*\.png|.*\.jpg|.*\.jpeg|.*\.gif)$
# Если хочешь чтобы был реджирект на новый размер картинки то ставь [L,R] иначе [L] без редиректа
RewriteRule ^(.*)$ /thumb.php?width=375&image=%1 [L]

Установка

  • php файл thumb.php положить в корень проекта
  • в корне добавить в существующий .htaccess соедержимое блока что выше. если .htaccess не существует — создать

Описание

  1. .httaccess фильтр для картинок. Влияет ТОЛЬКО на запрашиваемые файлы типа картинка И ТОЛЬКО С МОБИЛЬНЫХ по USER Agent
  2. если мобильный посетитель пытается скачать картинку — вызывается скрипт thumb.php и вместо картинки выдается его содержимое
  3. алгоритм работы thumb.php скрипта:
    • если ширина картинки меньше заданной 375 — ничего не делаем, выдаем оригинал картинки
    • если ширина картинки больше заданного порога 375, пропорционально ресайзим ее по ширине до 375
    • сохраняем полученый ресайз в кэш сайта,  чтобы не ресайзить повторно одну и туже картинку

CLOUDFLARE ПРОБЛЕМА

  1. CDN клаудфлар обнуляет этот скрипт оптимизации картинок, т.к. запоминает первый попавшийся вариант картинки. В зависимости от того, какой размер картингки скачали ПК юзверь или Мобильный пользователь
  2. Варианты с редиректом на новый адрес картинки для мобильных пользователей — не работает
  3. Максимум чем данный скрипт может быть полезен (для проектов закрытых Cloudflare), это автоматически оптимизировать все картинки в проекте без учета типа пользователя, например на максимальную ширину картинок не более 800 пикселей. И сохранить их  в кэше сайта, не трогая оригиналы.

UPDATED CLOUDFLARE

  1. Если сайт закрыт клаудфларом — .htaccess для нашей задачи бесполезен (см. выше обоснование)
  2. На стороне клаудфрара есть нужный нам механизм (до 100.000 запросов в сутки бесплатно) Workers https://developers.cloudflare.com/workers/ 
  3. Добавляем новый скрипт Wokers и прикрепляем его к роутеру вида (для вордпресса например так) MYSITE.com/wp-content/uploads/*
  4. Скрипт на стороне клаудфлара повторяет тот же механизм с редиректом на ресайзнутую картинку
  5. TODO: переписать скрипт ниже чтобы вместо редиректа на ресайз — выдавалась сама картинка нового размера.
/**
 * sets up routes and redirects them to a location based on a map
 * @param {Request} request
 */

async function handleRequest(request) {

let requestURL = new URL(request.url)

let location = "https://" + requestURL.hostname + "/thumb.php?width=375&image="+requestURL.pathname

let neededExtRegExp = new RegExp(/\.(jpeg|jpg|png|gif)$/)

let device = request.headers.get('CF-Device-Type')

let userAgent = request.headers.get('User-Agent') || ''

if (neededExtRegExp.test(requestURL.pathname)) {

   //if (device === 'mobile') {

  if (userAgent.includes('Phone') || userAgent.includes('Android') || userAgent.includes('BlackBerry')  ) {

      if (location) {

        return Response.redirect(location, 301)

      }    
   }
}

  //return the original request
  return fetch(request)

}

addEventListener('fetch', async event => {
  event.respondWith(handleRequest(event.request))
})