Рубріки: Теорія

PWA (Progressive Web App) – що це таке та в чому його особливості

Сергій Бондаренко

У цьому матеріалі ми поговоримо про відносно молоду технологію — Progressive Web App (PWA).

Що таке PWA

PWA, або прогресивний вебзастосунок — це нове покоління вебзастосунків, які поєднують у собі переваги вебсайтів та мобільних застосунків і тим самим забезпечують швидкодію та зручність використання.

Історія розвитку Progressive Web App

Історія Progressive Web Apps (PWA) розпочалася з появою у 2007 році перших HTML5 API, коли стало можливим створювати багатофункціональні інтерактивні вебпрограми. До цього вебпрограми не могли працювати в автономному режимі, не мали доступу до апаратного забезпечення пристрою і тому відставали від нативних програм.

У 2015 році компанія Google почала працювати над концепцією PWA та запропонувала нові API та інструменти для створення вебзастосунків, які могли працювати як нативні програми. Зокрема, було запропоновано використання Service Workers — спеціальних скриптів, які дозволяють створювати офлайн-сервіси та кешувати дані.

Service Worker — це проміжний шар між вебзастосунком та сервером, який може кешувати запити (а також відповіді на них), щоб програма могла швидко працювати без доступу до Інтернету. Це значно прискорює завантаження сторінок та зменшує навантаження на сервер.

Крім того, Google запропонував використовувати Web App Manifest — JSON-файл, який описує основні параметри програми, такі як назву, значок, колірну схему та інші характеристики, які зазвичай асоціюються з нативними застосунками.

Web App Manifest дозволяє встановити PWA на головний екран пристрою та створити більш реалістичний інтерфейс користувача, схожий на native.

Одним з перших PWA став застосунок Trivago, розроблений однойменною німецькою компанією. Застосунок надавав інформацію про готелі та був оптимізований для роботи в повільних мережах. Він також підтримував додавання на домашній екран пристрою та роботу в офлайн-режимі.

Але найважливішим кроком у розвитку вебтехнологій та підтримці прогресивних вебзастосунків став випуск мобільної версії соцмережі Twitter у 2017 році. Ця програма використовувала нові API та інструменти, запропоновані Google, і давала можливість учасникам мережі використовувати Twitter в автономному режимі, отримувати сповіщення. Також воно мало доступ до камери та деяких інших апаратних ресурсів пристрою.

Особливості впровадження PWA та його архітектура

Залежно від того, який підхід розробники вирішили використовувати для проєктування PWA-програми, воно може бути як SPA (Single-Page Application), так і MPA (Multi-Page Application) — це не важливо.

Архітектура PWA базується на стандартних вебтехнологіях, таких як HTML, CSS та JavaScript, і має три основні компоненти:

  • клієнтську сторону (frontend);
  • серверну сторону (backend);
  • маніфест програми (manifest).

Клієнтська сторона — це фронтенд-частина програми, яка працює на стороні клієнта (тобто у браузері). Вона написана на HTML, CSS та JavaScript і відповідає за візуальне подання програми і формує інтерфейс користувача, з певною логікою взаємодії з користувачем. Клієнтська сторона PWA може бути написана з використанням будь-яких фреймворків та бібліотек, таких як React, Vue, Angular тощо.

Щоб навчитися створювати прогресивні вебзастосунки, треба спочатку опанувати верстку та фронтенд. Отримати знання по HTML, CSS ви можете на курсі школи Hillel Front-end Basic, а потім продовжити вивчати JavaScript на курсі Front-end Pro.

Серверна сторона — це бекенд-частина програми, яка відповідає за обробку запитів та надання даних для клієнтської сторони. У PWA серверна сторона може бути створена будь-якою мовою програмування, наприклад PHP, Node.js, Python тощо. 

Ось як це працює:

  1. Під час запуску PWA спочатку завантажується HTML, CSS та JavaScript-код.
  2. Потім запускається Service Worker, фоновий процес, який працює в браузері, відповідає за кешування контенту та керування офлайн-режимом і може використовуватися для попереднього завантаження ресурсів та кешування даних. При цьому кешовані ресурси можна використовувати без підключення до Інтернету.
  3. Для зберігання даних використовується об’єктно-орієнтоване сховище IndexedDB, де можна зберігати структуровані дані, включаючи JavaScript. Процес збереження структурованих даних запускається окремим потоком, що забезпечує його відокремлення від основного потоку вебсторінки та дозволяє працювати незалежно від стану сторінки або програми.

Вивчай Python на курсах від Mate Academy, або приходь одразу на Fullstack програму, де ти опануєш і фронтенд, і бекенд за 4 місяці. Навчатися можна безкоштовно та сплатити курси вже після працевлатшування.

Маніфест програми — це JSON-файл, який включає метадані програми (ім’я, іконку, опис, колірну схему та інші налаштування). Файл manifest містить посилання та інші ресурси, такі як файли скриптів, які також завантажуються під час запуску PWA. Вміст цього файлу аналізується браузером у процесі встановлення програми PWA.

Маніфест програми дозволяє встановити PWA на головний екран пристрою та дає йому можливість працювати як нативний застосунок.

Ще одна вимога до архітектури progressive-застосунків — підтримка HTTPS. PWA має працювати за протоколом HTTPS, щоб забезпечити безпечну передачу даних між клієнтом та сервером. HTTPS також потрібний для використання Service Worker та доступу до деяких API браузера, таких як, наприклад, API геолокації.

PWA в ecommerce та переваги архітектури

PWA набули широкого поширення, і багато великих компаній (Uber, Pinterest, Starbucks та інші) почали створювати свої PWA-застосунки. Особливо популярними стали PWA серед компаній, які бажають надати користувачам легкий та швидкий доступ до своїх сервісів без необхідності встановлювати програми з AppStore.

Для вирішення завдань, пов’язаних із веденням онлайн бізнесу, progressive-застосунок — відмінний вибір.

Можна знайти чимало аргументів на користь цієї архітектури: 

  • PWA може підвищити конверсію сайту. Оскільки користувачі швидко отримують доступ до функцій, наприклад магазину, це збільшує ймовірність того, що клієнт виконає бажану дію — здійснить покупку, зробить замовлення послуги тощо.
  • Використання PWA означає зниження витрат за розробку. PWA використовують однаковий код для роботи на різних платформах, тому їх створення може бути більш економічним, ніж мобільна розробка для кожної платформи окремо.
  • Спрощується процедура внесення оновлень користувач не повинен постійно оновлювати програму через магазин програм. Крім того, у прогресивних програм швидкий відгук та швидкість роботи за рахунок кешування.
  • Завдяки своїй незалежності від платформи, PWA може працювати на будь-яких пристроях, включаючи iOS та Android. Це допомагає досягти максимального охоплення аудиторії, що особливо важливо для магазинів, які хочуть розширити свій бізнес на нові ринки.

Недоліки PWA та як з ними боротися

Як і у будь-якої іншої технології, у PWA є недоліки, які потрібно брати до уваги, розробляючи мобільну версію сайту:

  1. Технологія не є універсальною — вона може не підтримуватися деякими браузерами. Хоча у більшості сучасних браузерів із сумісністю проблем не спостерігається, окремі застарілі версії можуть опинитися за бортом. Вирішення проблеми: використовувати нові версії браузерів.
  2. PWA постійно записує дані у кеш та звертається до нього у офлайн-режимі. Це зручна фіча, але з цієї ж причини технологія додатково витрачає пам’ять. Ця проблема вирішується комплексним підходом та постійною оптимізацією:
    (1) Застосовуйте «ліниве завантаження ресурсів». Це означає, що ресурси (зображення, скрипти та стилі) завантажуються лише тоді, коли вони дійсно потрібні.
    (2) Використовуйте компрессію для скорочення трафіка. Обов’язково проводить оптимізацію зображень.
    (3) Зведіть до мінімуму кількість сторонніх фреймворків та бібліотек, а сам застосунок ретельно тестуйте на предмет витоку пам’яті. Програма повинна регулярно видаляти об’єкти та дані, які не використовуються, для звільнення пам’яті.
  3. Знову ж таки, через кешування файлів і даних для офлайн-режиму, PWA-програма може займати більше місця у пристрої порівняно зі звичайним вебзастосунком. Тут залишається лише робити вибір на користь економії пам’яті/розробки PWA.
  4. Якщо PWA-програми налаштовані некоректно, вони можуть викликати проблеми з SEO-оптимізацією. Справа в тому, що PWA-програми можуть використовувати динамічний вміст, який генерується на стороні клієнта, і цей контент може бути складним для індексації пошуковими роботами.
    Для боротьби з цією проблемою є ряд хитрощів:
    (1) застосовувати попередній рендеринг (prerendering) для створення статичних HTML-сторінок, які пошукові роботи зможуть легко проіндексувати;
    (2) використовувати тег meta для вказівки правильних метаданих, таких як title, description та keywords, які дозволять пошуковим роботам правильно індексувати сторінки програми.
    Крім того, PWA-програми можуть мати свою власну URL-адресу — це також допомагає індексувати сторінки в пошукових системах. Для цього потрібно налаштувати відповідні маршрутизатори, які підкажуть пошуковим роботам, як правильно індексувати сторінки програми.

Проблем у вашому PWA буде значно менше, якщо ви будете писати не тільки функціонуючий, але й чистий код. Прокачати ці навички можна на курсі проєктування та рефакторингу від robot_dreams.

Приклад найпростішої PWA-програми

Давайте напишемо найпростіший PWA-застосунок, на прикладі якого стане зрозуміло, як функціонує ця архітектура.

Нам знадобляться чотири файли:

  • index.html — у ньому буде прописана структура Web App Shell, основа PWA. У контексті PWA index.html працює як точка входу в програму, яку відкриває користувач при запуску програми або при переході на неї зі списку програм на пристрої. Тут ми визначаємо навігаційну панель, основний контент та інші елементи інтерфейсу користувача.
  • script.js — тут може бути будь-який код, пов’язаний із функціональністю вашої програми. Наприклад, це може бути код для отримання та обробки даних, код для роботи з інтерфейсом користувача, обробка подій тощо. Код, який ви напишете, залежатиме від того, що саме має робити ваша програма.
  • style.css — файл зі стилями для HTML-сторінки.
  • sw.js — файл JavaScript, який містить код Service Worker для вашої вебпрограми. Код працюватиме у фоновому режимі та може перехоплювати запити до серверної частини, кешувати ресурси, обробляти push-сповіщення та багато іншого. У файлі sw.js можна визначити, які запити кешувати, як обробляти події життєвого циклу тощо. Зазвичай код реєстрації Service Worker розміщується в обробнику події load, щоб гарантувати, що всі ресурси сторінки завантажилися до запуску реєстрації Service Worker.

Файл sw.js не потрібно підключати до HTML-файлу. Він підключається до Java Script-файлу, який обробляє реєстрацію Service Worker, наприклад, всередині файлу script.js.

Код нашого макету вебпрограми буде виглядати дуже просто:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>My PWA</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <h1>My PWA</h1>
    <p>This is a simple PWA example for Highload.today.</p>
    <button class="btn">Click me!</button>
    <script src="script.js"></script>
  </body>
</html>

Файл зі стилями:

body {
    margin: 0;
    padding: 0;
    font-family: sans-serif;
  }
  header {
    background-color: #333;
    color: #fff;
    padding: 20px;
  }
  h1 {
    margin: 0;
  }
  main {
    padding: 20px;
  }
  .btn {
    background-color: #4CAF50;
    color: white;
    padding: 12px 24px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 16px;
  }
  .btn:hover {
    background-color: #3e8e41;
  }

Файл script.js :

const button = document.querySelector('.btn');
button.addEventListener('click', () => {
  button.disabled = true;
  button.textContent = 'Loading...';
  console.log('Button clicked');
  fetch('https://jsonplaceholder.typicode.com/posts')
    .then(response => response.json())
    .then(data => {
      console.log('Data loaded', data);
      setTimeout(() => {
        button.disabled = false;
        button.textContent = 'Click me!';
      }, 2000); // затримка в 2 секунди
    })
    .catch(error => {
      console.error('Error:', error);
      setTimeout(() => {
        button.disabled = false;
        button.textContent = 'Click me!';
      }, 2000); // затримка в 2 секунди
    });
});

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw.js').then(function(registration) {
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }, function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}

Тепер напишемо код для файлу sw.js — він реєструє сервісний робочий скрипт та кешує необхідні ресурси.

Також код обробляє події fetch, що дає змогу використовувати кешовані ресурси під час виконання запитів. Але під час роботи з кешем може виникнути несподівана поведінка, тому важливо тестувати та налагоджувати цей функціонал:

var CACHE_NAME = 'my-pwa-cache-v1';
// Проводимо кешування необхідних ресурсів в момент установки Service Worker
self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        return cache.addAll([
          '/',
          '/index.html',
          '/style.css',
          '/script.js'
        ]);
      })
  );
});

// Кешування запитів
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Якщо ресурс знайдений у кеші, повертаємо його з кешу
        if (response) {
          return response;
        }
        // Якщо ресурс відсутній в кеші, запитуємо з сервера і зберігаємо відповідь в кеші
        return fetch(event.request)
          .then(function(response) {
            // Перевіряємо, що відповідь коректна, інакше повертаємо не кешуючи
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }
            // кешуємо успішну відповідь і повертаємо його
            var responseToCache = response.clone();
            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });
            return response;
          });
      })
  );
});

// Позбавлення від застарілих кешів при активуванні нового Service Worker
self.addEventListener('activate', function(event) {
  var cacheWhitelist = ['my-pwa-cache-v1'];
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Перша частина коду, яка запускається при встановленні Service Worker, ініціалізує кеш та кешує основні ресурси програми (index.html, style.css, script.js).

Друга частина коду, яка запускається при виконанні запиту, перевіряє наявність ресурсу, що запитується в кеші:

  • якщо ресурс знайдено, він повертається з кешу;
  • якщо ресурс не знайдено, відбувається запит на сервер і результат кешується.

У разі некоректної серверної відповіді (не 200 або не тип basic), відповідь повертається без кешування.

Нарешті, третя частина коду відповідає за видалення застарілих кешів під час активації нового Service Worker.

Запустимо нашу програму і подивимося, що відбувається.

Щоб запустити програму, потрібно запустити локальний вебсервер. Найпростіший спосіб зробити це — за допомогою розширення для браузера, наприклад, Web Server for Chrome из Chrome Web Store.

Якщо ви не хочете використовувати розширення для браузера, ви можете запустити локальний сервер з командного рядка, використовуючи такі інструменти, як Node.js, PHP, Python або будь-яку іншу серверну мову програмування. Недостатньо знаєте Python? Спробуйте курс від Powercode Academy.

А ось як запустити локальний вебсервер за допомогою Node.js:

  • встановлюєте Node.js;
  • потім відкриваєте термінал та пишете npm install -g http-server;
  • переходите до каталогу з проєктом cd/path/to/project та виконуєте команду http-server;
  • післе цього запускаєте браузер та йдете за адресою http://localhost:8080 (порт може бути інший, якщо він був вказаний у команді запуску).

Якщо все зроблено правильно, ви побачите вміст вашого проєкту у браузері.

Наш застосунок — це просте PWA (Progressive Web App), яке дозволяє завантажити список постів (posts) за допомогою API, що надається сервісом JSONPlaceholder.

Для цього в програмі є кнопка Click me!, яка завантажує список постів, використовуючи JavaScript Fetch API:

  • при натисканні на кнопку вона стає неактивною та змінює свій текст на “Loading…” (стоїть двосекундна затримка), щоб користувач знав, що відбувається завантаження даних;
  • далі запускається функція fetch(), яка надсилає GET-запит на сервер за вказаною адресою “https://jsonplaceholder.typicode.com/posts“;
  • коли сервер повертає відповідь, його вміст перетворюється з формату JSON на JavaScript-об’єкт за допомогою методу .json(), який викликається на об’єкті Response, отриманому із сервера;
  • отримані дані виводяться в консоль для перевірки.

Після отримання даних кнопка стає активною та повертається її початковий текст “Click me!”:

У цьому прикладі ми не писали код для маніфесту. Але зазвичай файл маніфесту має бути створений у кореневому каталозі програми та називатися manifest.json. У цьому файлі має бути визначена інформація про програму, така як назва, опис, іконки, кольори та інші параметри.

Простежити за процесом кешування та функціонуванням програми можна через інструменти розробника:

Висновок

Тепер ви знаєте, що таке прогресивні програми, як вони працюють, в чому їх переваги та недоліки.

Якщо підсумувати коротко, то PWA — потужна та цікава технологія, яка потребує комплексного підходу до управління пам’яттю та SEO-оптимізації.

Попереднє завантаження сторінок та кешування дозволяють зменшити час завантаження та покращити швидкість роботи програми, що особливо актуально для мобільних пристроїв з повільним інтернетом.

Хочеш створювати прогресівні вебзастосунки сам? Твій вибір — Fullstack курси від Mate Academy. Можеш навчатися повний день та платити після працевлатшування або обрати вечірні курси з гнучким графіком.

Останні статті

Brave1 збільшив гранти для оборонних розробок: можна отримати до 2 млн гривень

Кластер Brave1 збільшує гранти для оборонних розробок — тепер можна отримати від 500 тис до…

10.05.2024

Softserve, Luxoft та Infopulse. З’явився рейтинг найбільших платників податків серед IT-компаній

За 2023 рік IT-компанії сплатили сплатили в державний бюджет 20,8 мільярда гривень податків. Це 7,4%…

10.05.2024

«За заслуги перед компанією»: Microsoft розморозить підвищення зарплат співробітникам

Корпорація Microsoft планує відновити підвищення зарплат для найбільш ефективних співробітників. Про це повідомив Insider. Вірогідне…

10.05.2024

Мінекономіки запустило пільгові гранти для виробників дронів

Міністерство економіки запропонувало виробникам дронів пільгові гранти від держави за програмою «Переробка». Про це йдеться…

09.05.2024

Дочекалися. В квітні попит на айтівців без досвіду був вищий, ніж на досвідчених фахівців

В квітні попит на недосвідчених айтівців був вищий, аніж на тих, хто має 3-4 роки…

09.05.2024

Dell буде відстежувати переміщення та присвоювати рейтинг «прогульникам» офісу

Американська компанія Dell після зміни політики щодо ремоуту посилює контроль за працівниками. Зокрема, відстежує фізичне…

09.05.2024