PWA: основе Progressive Web App, Service Worker и манифест

Аутор: IT Sectr Објављено: 2026-02-14 Време читања: 10 мин

PWA (Progressive Web App) — то је веб апликација која користи модерне могућности прегледача да ради као изворна апликација: брзо се учитава, ради офлајн, шаље push обавештења и инсталира се на почетни екран. У основи PWA леже три технологије: Service Worker, манифест и HTTPS. Service Worker — то је скрипт који прегледач покреће у позадини, одвојено од веб странице, отварајући могућности недоступне обичним сајтовима: пресретање мрежних захтева, кеширање ресурса, позадинска синхронизација и push обавештења. Манифест — JSON фајл који обавештава прегледач како апликација треба да изгледа приликом инсталације на уређај: име, иконе, боја теме, оријентација екрана. Без HTTPS-а Service Worker не ради — то је обавезан безбедносни захтев. PWA је компатибилан са сваким савременим прегледачем и не захтева објављивање у продавници апликација. Корисник отвара сајт, види предлог да инсталира апликацију, притиска «Додај на почетни екран» — и апликација је готова. За бизнис, PWA значи покривеност сваке публике без трошкова развоја посебно за iOS и Android, велику брзину учитавања чак и на спорим мрежама и ангажовање кроз push обавештења. У чланку ћемо размотрити како је уређен Service Worker, како саставити манифест, које стратегије кеширања користити и како обезбедити офлајн приступ.

Главно

  • PWA — веб апликација која ради као изворна: инсталира се на почетни екран, ради офлајн, шаље push обавештења
  • Service Worker — позадински JS скрипт са животним циклусом: регистрација, инсталација, активација, пресретање мрежних захтева
  • Стратегије кеширања — Cache First, Network First, Stale While Revalidate за различите типове ресурса
  • Web App Manifest — JSON фајл са подешавањима имена, икона, боје теме и режима приказа
  • Push обавештења — раде кроз Push API и Notification API чак и када је апликација затворена
  • Lighthouse — алат за ревизију PWA са минималним пролазним резултатом 80 од 100
  • Workbox — Google библиотека за поједностављење креирања и управљања Service Worker-ом

Главно

  • PWA — веб апликација која ради као изворна: инсталира се на почетни екран, ради офлајн, шаље push обавештења
  • Service Worker — позадински JS скрипт са животним циклусом: регистрација, инсталација, активација, пресретање мрежних захтева
  • Стратегије кеширања — Cache First, Network First, Stale While Revalidate за различите типове ресурса
  • Web App Manifest — JSON фајл са подешавањима имена, икона, боје теме и режима приказа
  • Push обавештења — раде кроз Push API и Notification API чак и када је апликација затворена
  • Lighthouse — алат за ревизију PWA са минималним пролазним резултатом 80 од 100
  • Workbox — Google библиотека за поједностављење креирања и управљања Service Worker-ом

Шта је Progressive Web App

Progressive Web App (PWA) — то је приступ развоју веб апликација који комбинује најбоље квалитете веба и изворних апликација. Термин је увео Франческо Бериман (Francesco Berriman) 2015. године, а Google активно промовише PWA као замену за једноставне мобилне апликације. Основна идеја: веб сајт се постепено побољшава у зависности од могућности прегледача и уређаја. Ако прегледач подржава Service Worker — повезује се офлајн режим. Ако подржава манифест — појављује се дугме «Инсталирај». Ако постоји API за обавештења — апликација може слати push. Корисник на слабом уређају са спорим интернетом добиће основну верзију сајта, а на модерном паметном телефону — потпуну апликацију са иконом на радној површини.

PWA не треба инсталирати преко продавнице апликација. Довољан је линк. То решава главни проблем мобилних апликација — висок праг уласка. Корисник не иде у Google Play или App Store, не чека преузимање од 100 MB, не даје десетак дозвола. Он једноставно отвара сајт, и прегледач предлаже инсталацију апликације. Ако корисник одбије — он и даље користи сајт. А ако пристане — икона се појављује на почетном екрану, и апликација се отвара као изворна: без адресне траке прегледача, са режимом преко целог екрана и брзим покретањем.

Технички, PWA мора да испуњава три критеријума: да ради преко HTTPS (безбедна веза), да има Service Worker (скрипт за позадинску обраду) и да садржи манифест (Web App Manifest). Ове три компоненте претварају обичан сајт у инсталабилну апликацију.

Service Worker: срце PWA

Service Worker — то је JavaScript скрипт који прегледач покреће у посебној нити, независно од веб странице. Он нема приступ DOM-у, не може директно да интерагује са интерфејсом, али може да пресреће и мења мрежне захтеве, управља кешом, обрађује push обавештења и обавља позадинску синхронизацију. Service Worker ради као прокси сервер између прегледача и мреже: сваки захтев са странице пролази кроз Service Worker, који одлучује — да врати податке из кеша, затражи са сервера или уради обоје.

Service Worker живи по сопственом животном циклусу, невезаном за отворену страницу. Он се инсталира, активира и ради у позадини чак и након затварања свих картица сајта. То омогућава PWA да прима push обавештења и ажурира кеш у позадини, без учешћа корисника.

Животни циклус Service Worker-а

Service Worker пролази кроз четири фазе: регистрација, инсталација, активација и мировање/завршетак.

Регистрација. Прегледач добија линк до JS фајла Service Worker-а и почиње преузимање. Регистрација се извршава из обичног JavaScript-а на страници:

javascript
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(registration => {
      console.log('SW регистрован:', registration.scope);
    })
    .catch(error => {
      console.log('SW регистрација није успела:', error);
    });
}

Инсталација. Након успешног преузимања, прегледач покреће догађај install. У овој фази је уобичајено да се кеширају кључни ресурси (HTML оквир, CSS, главне слике) како би апликација могла да ради офлајн. Ако је инсталација успешна, Service Worker прелази у следећу фазу. Ако скрипт баци грешку — инсталација се отказује, и стари Service Worker наставља да ради.

javascript
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('pwa-cache-v1').then(cache => {
      return cache.addAll([
        '/',
        '/index.html',
        '/styles/main.css',
        '/scripts/app.js',
        '/images/logo.png'
      ]);
    })
  );
});

Активација. Када су све картице сајта затворене, стари Service Worker се завршава, а нови се активира. Догађај activate се користи за чишћење старих кешева и миграцију података:

javascript
self.addEventListener('activate', event => {
  const cacheWhitelist = ['pwa-cache-v2'];
  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          if (!cacheWhitelist.includes(cacheName)) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Мировање. Активирани Service Worker пресреће захтеве и обрађује догађаје. Може бити заустављен од стране прегледача ради уштеде ресурса и поново покренут при следећем захтеву. Service Worker је догађајно оријентисан: живи само док обрађује догађаје.

Стратегије кеширања

Service Worker подржава неколико стратегија кеширања. Избор зависи од типа ресурса и захтева за актуелношћу података.

Cache First (прво кеш). Прво се проверава кеш. Ако је ресурс пронађен — враћа се из кеша. Ако није — захтев иде на сервер, одговор се чува у кешу. Стратегија је погодна за статичке ресурсе: слике, фонтови, CSS, JS. Обезбеђује максималну брзину и потпуни рад офлајн.

javascript
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      return response || fetch(event.request).then(fetchResponse => {
        return caches.open('pwa-cache-v1').then(cache => {
          cache.put(event.request, fetchResponse.clone());
          return fetchResponse;
        });
      });
    })
  );
});

Network First (прво мрежа). Захтев прво иде на сервер. Ако сервер одговори — подаци се враћају кориснику и чувају у кешу. Ако сервер није доступан — враћа се кеширана копија. Стратегија је погодна за API захтеве, вести, садржај који треба да буде актуелан, али може да ради и офлајн.

javascript
self.addEventListener('fetch', event => {
  event.respondWith(
    fetch(event.request).then(response => {
      return caches.open('pwa-dynamic-v1').then(cache => {
        cache.put(event.request, response.clone());
        return response;
      });
    }).catch(() => {
      return caches.match(event.request);
    })
  );
});

Stale While Revalidate (застарело са освежавањем). Одговор се одмах враћа из кеша, а у позадини се шаље захтев на сервер за ажурирање кеша. Корисник види садржај тренутно, а следећи захтев ће добити свеже податке. Идеално за садржај који се мења, али није критично ако корисник види верзију стару пар минута.

javascript
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cached => {
      const fetchPromise = fetch(event.request).then(response => {
        return caches.open('pwa-dynamic-v1').then(cache => {
          cache.put(event.request, response.clone());
          return response;
        });
      });
      return cached || fetchPromise;
    })
  );
});

Web App Manifest: како апликација изгледа на уређају

Манифест — то је JSON фајл, обично manifest.json, који се повезује преко <link> тага у head HTML странице. Он обавештава прегледач како апликација треба да се приказује приликом инсталације на уређај: назив, иконе различитих величина, боја позадине, боја теме, оријентација и режим приказа (прегледач, минимални UI, преко целог екрана).

json
{
  "name": "PWA Demo App",
  "short_name": "PWA Demo",
  "description": "Демонстрациона PWA апликација",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#3f51b5",
  "orientation": "portrait",
  "icons": [
    {
      "src": "/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ]
}

Параметар display одређује како ће апликација изгледати након инсталације. standalone скрива адресну траку прегледача и навигациони панел — апликација изгледа као изворна. fullscreen користи цео екран без икаквих елемената прегледача. minimal-ui оставља минималне елементе прегледача (дугмад за назад и освежавање).

Иконе треба припремити у најмање две величине: 192x192 и 512x512 пиксела. PNG формат са подршком за параметар purpose (на пример, maskable) омогућава прегледачу да прилагоди икону облику кућишта уређаја — на Android-у икона може бити исечена у заобљени квадрат. Након повезивања манифеста, Chrome прегледач на Android-у почиње да приказује банер «Додај на почетни екран» када су испуњени услови: HTTPS, регистрован Service Worker, исправан манифест и најмање две посете са интервалом од 5 минута.

Push обавештења у PWA

PWA може слати push обавештења као изворна апликација. За то се користе два API-ја: Push API (серверско слање) и Notification API (приказ на уређају). Service Worker прима push догађај чак и ако апликација није отворена, и може приказати обавештење са насловом, текстом и иконом.

Да би примао push обавештења, корисник мора дати дозволу:

javascript
Notification.requestPermission().then(permission => {
  if (permission === 'granted') {
    console.log('Push дозвољен');
  }
});

Service Worker се претплаћује на push догађај и приказује обавештење:

javascript
self.addEventListener('push', event => {
  const data = event.data.json();
  self.registration.showNotification(data.title, {
    body: data.body,
    icon: '/icons/icon-192x192.png',
    badge: '/icons/badge-72x72.png',
    actions: [
      { action: 'open', title: 'Отвори' },
      { action: 'close', title: 'Затвори' }
    ]
  });
});

self.addEventListener('notificationclick', event => {
  event.notification.close();
  if (event.action === 'open') {
    clients.openWindow('/');
  }
});

За слање push-а са сервера користи се протокол Web Push (VAPID). Сервер шифрује поруку и шаље је кроз прегледачки push сервис (Firebase Cloud Messaging за Chrome, Mozilla Autopush за Firefox). Претплату корисника (објекат PushSubscription) потребно је сачувати на серверу приликом регистрације.

Перформансе и Lighthouse

PWA морају бити брзи. Google Lighthouse — алат за ревизију који проверава PWA по контролној листи: регистрација Service Worker-а, одговор 200 при офлајн приступу, исправан манифест, HTTPS, исправна величина икона, брзо учитавање на спорим мрежама. Минимални пролазни резултат за PWA — 80 од 100 на Lighthouse скали. Апликације са резултатом испод 80 не добијају банер за инсталацију у Chrome-у.

Кључне метрике перформанси за PWA — First Contentful Paint (FCP) до 1.8 секунди, Largest Contentful Paint (LCP) до 2.5 секунди, Time to Interactive (TTI) до 3.5 секунди. Service Worker може значајно побољшати FCP и LCP ако кешира критични HTML и CSS при инсталацији. Стратегија Cache First за статику и Stale While Revalidate за API даје најбоље корисничко искуство.

Офлајн приступ и позадинска синхронизација

Једна од главних могућности PWA — рад без интернета. Service Worker пресреће захтеве и враћа кеширане верзије страница. Ако корисник покуша да отвори страницу која није у кешу, може се приказати прилагођена страница-резерва:

javascript
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      return response || fetch(event.request);
    }).catch(() => {
      return caches.match('/offline.html');
    })
  );
});

Позадинска синхронизација (Background Sync) омогућава одлагање слања података на сервер ако је уређај офлајн. Service Worker чува захтев и аутоматски га шаље када се веза успостави:

javascript
self.addEventListener('sync', event => {
  if (event.tag === 'sync-messages') {
    event.waitUntil(sendMessages());
  }
});

function sendMessages() {
  return caches.open('pwa-pending-v1').then(cache => {
    return cache.keys().then(requests => {
      return Promise.all(requests.map(request => {
        return fetch(request).then(() => cache.delete(request));
      }));
    });
  });
}

Алати за развој PWA

Chrome DevTools пружа панел Application, где се може отклањати грешака Service Worker-а (регистрација, статус, кеш, push), проверавати манифест, чистити кеш и креирати сопствена push обавештења за тестирање. Картица Network са емулацијом офлајн режима помаже да се провери рад кеша. Lighthouse у панелу Audits даје потпуну PWA ревизију са препорукама.

Workbox — Google библиотека која поједностављује креирање Service Worker-а. Уместо ручног писања стратегија кеширања, Workbox нуди готове модуле:

javascript
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { StaleWhileRevalidate } from 'workbox-strategies';

precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  /\.(?:png|jpg|jpeg|svg|gif)$/,
  new StaleWhileRevalidate()
);

Workbox се интегрише са пакерима (Webpack, Vite) и аутоматски генерише манифест за претходно кеширање. PWA Builder (pwabuilder.com) од Microsoft-а генерише све PWA фајлове онлајн: Service Worker, манифест, иконе, HTML шаблон.

FAQ

Шта је PWA једноставним речима?

PWA — то је сајт који након инсталације на телефон ради као обична апликација: има икону на радној површини, офлајн приступ, push обавештења, режим преко целог екрана без адресне траке прегледача. При томе не треба ићи у App Store или Google Play — инсталација се врши једним кликом из прегледача.

Која је разлика између PWA и изворне апликације?

Изворна апликација се пише за одређену платформу (Swift за iOS, Kotlin за Android), захтева објављивање у продавници и ручну инсталацију. PWA — то је веб сајт написан у HTML, CSS и JavaScript-у, који може бити инсталиран на уређај преко прегледача. PWA не заузима много простора (само кеш), ажурира се аутоматски и подржан је од стране свих савремених прегледача.

Који прегледачи подржавају PWA?

Chrome, Firefox, Safari (почев од iOS 11.3), Edge, Samsung Internet, Opera. Service Worker је подржан од стране свих савремених прегледача, осим Internet Explorer-а. Safari има ограничену подршку за push обавештења, али основне могућности PWA (инсталација на почетни екран, офлајн приступ) раде.

Може ли се постојећи сајт претворити у PWA?

Да. За то је потребно додати манифест (manifest.json), креирати и регистровати Service Worker (sw.js), пребацити сајт на HTTPS, додати мета тагове и иконе. Сам сајт не захтева преписивање ако ради на JavaScript-у и враћа HTML. Ако је сајт потпуно серверски (MPA), може се додати Service Worker као слој кеширања без промене архитектуре.

Како се PWA ажурира?

Када корисник отвори PWA, прегледач проверава да ли се фајл Service Worker-а на серверу променио. Ако се фајл разликује макар за бајт, прегледач преузима нови Service Worker и покреће његову инсталацију. Стари Service Worker наставља да ради док све картице апликације не буду затворене. Након затварања картица, нови Service Worker се активира и замењује стари. Корисник може принудно да ажурира апликацију поновним учитавањем странице.

Да ли вреди развијати PWA уместо мобилне апликације?

PWA је оправдано ако је циљ покрити максималну публику без трошкова развоја за две платформе, ако апликација не захтева дубок приступ хардверу (Bluetooth, NFC, камера у позадини), ако се садржај често мења. За сложене апликације (игре, видео едитори) изворна апликација остаје пожељнија. PWA се често користи као додатни канал или као MVP пре пуне апликације.

Резиме

  • PWA (Progressive Web App) — веб апликација која ради као изворна: инсталира се на почетни екран, ради офлајн, шаље push обавештења.
  • Три обавезна компонента PWA: HTTPS, Service Worker и манифест (manifest.json). Без било ког од ових елемената прегледач неће понудити инсталацију.
  • Service Worker — позадински JavaScript скрипт који пресреће мрежне захтеве. Имплементира стратегије кеширања: Cache First (статика), Network First (API), Stale While Revalidate (садржај са освежавањем).
  • Web App Manifest — JSON фајл са подешавањима приказа: име, иконе, боја теме, display (standalone, fullscreen, minimal-ui). Иконе су потребне у величинама 192x192 и 512x512.
  • Push обавештења у PWA раде кроз Push API и Notification API. Service Worker прима push догађај чак и када је апликација затворена.
  • Lighthouse проверава PWA по контролној листи. Минимални резултат за инсталацију — 80 од 100. Кључне метрике: FCP до 1.8 с, LCP до 2.5 с.
  • Workbox од Google-а поједностављује развој Service Worker-а: готове стратегије, аутоматско кеширање, интеграција са пакерима.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође