Согласно этой статье из CNBC, к 2025 году почти три четверти населения мира будут использовать для доступа к интернету только смартфоны. Поэтому, если вы планируете создать новый веб-сайт или редизайнить старый, вам следует задуматься о создании PWA.
PWA — идеальное начало для любого проекта, не требующее большого количества усилий, а созданное приложение работает на всех платформах!
Прогрессивное веб-приложение (PWA) — это гибрид обычной веб-страницы и мобильного приложения. Оно сочетает в себе функции большинства современных браузеров с преимуществами мобильных приложений и создается с использованием стандартных веб-технологий, включая HTML, CSS и JavaScript. Функциональные возможности включают работу в автономном режиме, push-уведомления и доступ к аппаратуре, что создает аналогичный нативным приложениям опыт работы для пользователя.
На сайте pwastats.com представлена статистика самых известных компаний, использующих PWA, которые улучшили производительность своих веб-сайтов более чем на 100%.
Прогрессивное веб-приложение сокращает время загрузки, предоставляет пользователям возможность перехода в автономный режим, увеличивает проведенное на веб-сайте время, повышает доход, а также занимает намного меньше места, чем мобильное приложение.
Как видим, некоторые из крупнейших в мире компаний, такие как Twitter, Instagram, Uber, Pinterest, Forbes, Alibaba и другие, уже используют PWA.
Чтобы создать прогрессивное веб-приложение, для начала нужно разработать веб-сайт с отзывчивым дизайном. После выполнения первого пункта понадобятся только manifest.json и сервис-воркер.
Манифест веб-приложения — это простой файл JSON, который сообщает браузеру о веб-приложении и о том, как оно должно вести себя при добавлении на мобильное устройство или компьютер пользователя.
Свойства:
Это файл JavaScript, который запускается отдельно от основного потока браузера. С его помощью можно:
Пришло время реализовать прогрессивное веб-приложение!
Прежде чем начать, установим расширение Lighthouse — инструмент (от Google) для улучшения качества веб-страниц, который выдает следующий отчет:
Отчет LighthouseС его помощью можно проверить, какие проблемы нужно решить для повышения производительности, доступности, лучших практик, SEO и PWA веб-сайта или веб-приложения.
Установить расширение для Chrome можно здесь.
Структура файла в нашем примере выглядит так:
Структура файлаПолный код на Github можно найти здесь. Вы также можете переключать ветки для отображения динамического или статического кэша.
В index.html
вызываем manifest.json
:
Также нужно вызвать файл app.js
, в котором будет зарегестрирован воркер, и метатег, необходимый для оптимизации PWA:
<link rel="apple-touch-icon" href="/assets/images/logo-96x96.png">
<meta name="apple-mobile-web-app-status-bar" content="#FFE1C4">
<meta name="theme-color" content="#FFE1C4">
<script src="/assets/js/app.js"></script>
Это основные теги, но, конечно, их будет еще больше, а также у них могут быть разные пути!
Начнем с реализации статического кэша: укажем вручную, какие ресурсы помещать в кэш, например, все изображения, файлы CSS и js.
Этот метод полезный, особенно если вам нужно загрузить все ресурсы веб-сайта и кэшировать их при первом переходе на страницу.
Начнем с manifest.json
{
"name": "Name Website",
"short_name": "NameWebsite",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#F4F4F4",
"theme_color": "#F4F4F4",
"orientation": "portrait-primary",
"icons": [
{
"src": "/assets/images/logo-72x72.png",
"type": "image/png",
"sizes": "72x72"
},
{
"src": "/assets/images/logo-96x96.png",
"type": "image/png",
"sizes": "96x96"
},
{
"src": "/assets/images/logo-128x128.png",
"type": "image/png",
"sizes": "128x128"
},
{
"src": "/assets/images/logo-144x144.png",
"type": "image/png",
"sizes": "144x144"
},
{
"src": "/assets/images/logo-152x152.png",
"type": "image/png",
"sizes": "152x152"
},
{
"src": "/assets/images/logo-192x192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/assets/images/logo-384x384.png",
"type": "image/png",
"sizes": "384x384"
},
{
"src": "/assets/images/logo-512x512.png",
"type": "image/png",
"sizes": "512x512"
}
]
}
Теперь нужно проверить, допускает ли браузер работу воркера, и, если да, то регистрируем воркеры в app.js
.
if('serviceWorker' in navigator){
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('service worker registered'))
.catch(err => console.log('service worker not registered', err));
}
Теперь запишем воркер в файл sw.js
:
const staticCacheName = 'site-static-v1';
const assets = [
'/',
'/index.html',
'/assets/js/ui.js',
'/assets/css/main.css',
'/assets/images/background-home.jpg',
'https://fonts.googleapis.com/css?family=Lato:300,400,700',
];
// событие install
self.addEventListener('install', evt => {
evt.waitUntil(
caches.open(staticCacheName).then((cache) => {
console.log('caching shell assets');
cache.addAll(assets);
})
);
});
// событие activate
self.addEventListener('activate', evt => {
evt.waitUntil(
caches.keys().then(keys => {
return Promise.all(keys
.filter(key => key !== staticCacheName)
.map(key => caches.delete(key))
);
})
);
});
// событие fetch
self.addEventListener('fetch', evt => {
evt.respondWith(
caches.match(evt.request).then(cacheRes => {
return cacheRes || fetch(evt.request);
})
);
});
В массиве хранятся все ресурсы, которые нужно поместить в кэш.
Событие InstallДобавляем в кэш все статические ассеты, которые отображаются в консоли Chrome:
Скрин кэша Событие ActivateПри изменении имени кэша могут сохраниться несколько кэшей, что приводит к возникновению проблем. Чтобы избежать этого, нужно удалить старый кэш. В этой функции мы проверяем ключ (имя кэша), и, если он отличается от предыдущего, удаляем предыдущий.
Событие FetchЗдесь мы проверяем наличие кэша. Если он уже есть, то мы больше не загружаем ресурсы, а извлекаем их из кэша, который снова отображается в консоли.
Скрин сетиПримечание: при изменении файла воркера нужно изменить имя кэша. Благодаря этому воркер обновляется и создается новый кэш.
Динамический кэш автоматически кэширует все fetch-запросы во время навигации. Этот кэш следует применять осторожно, потому что, если использовать его во время вызова API, то изменения новых данных не будут отображены.
В предыдущей конфигурации необходимо изменить файл sw.js
следующим образом:
const dynamicCacheName = 'site-dynamic-v1';
// событие activate
self.addEventListener('activate', evt => {
evt.waitUntil(
caches.keys().then(keys => {
return Promise.all(keys
.filter(key => key !== dynamicCacheName)
.map(key => caches.delete(key))
);
})
);
});
// событие fetch
self.addEventListener('fetch', evt => {
evt.respondWith(
caches.match(evt.request).then(cacheRes => {
return cacheRes || fetch(evt.request).then(fetchRes => {
return caches.open(dynamicCacheName).then(cache => {
cache.put(evt.request.url, fetchRes.clone());
return fetchRes;
})
});
})
);
});
Событие Active
Здесь мы выполняем те же действия, что и для статического кэша.
Событие FetchВ событии fetch мы автоматически помещаем в кэш все fetch-запросы.
Если вы попробуете оба вида кэша, а затем запустите Lighthouse, то увидите, что сайт является PWA.
PWA LighthouseЗдесь можно найти код статических и динамических кэшей.
Все зависит от потребностей и особенностей проектов. Я использую динамический кэш при отсутствии вызовов API, а при их наличии предпочитаю самостоятельно выбирать, какие ресурсы хранить с помощью статического кэша.
Более подробно о PWA можно узнать здесь.
Перевод статьи Luca Spezzano: Turn Your Website into a PWA
Комментарии