PWA (Progressive Web App) — är en webbapplikation som använder moderna webbläsarfunktioner för att fungera som en inbyggd app: laddas snabbt, fungerar offline, skickar push-notiser och installeras på hemskärmen. I grunden för PWA ligger tre tekniker: Service Worker, manifest och HTTPS. Service Worker — är ett skript som webbläsaren kör i bakgrunden, separat från webbsidan, och öppnar möjligheter som inte är tillgängliga för vanliga webbplatser: avlyssning av nätverksförfrågningar, cachning av resurser, bakgrundssynkronisering och push-notiser. Manifestet — är en JSON-fil som talar om för webbläsaren hur appen ska se ut när den installeras på enheten: namn, ikoner, temafärg, skärmorientering. Utan HTTPS fungerar inte Service Worker — detta är ett obligatoriskt säkerhetskrav. PWA är kompatibelt med alla moderna webbläsare och kräver inte publicering i appbutiken. Användaren öppnar webbplatsen, ser ett förslag om att installera appen, klickar på «Lägg till på hemskärmen» — och appen är klar. För företag innebär PWA att nå alla målgrupper utan kostnader för separat utveckling för iOS och Android, hög laddningshastighet även på långsamma nätverk och engagemang via push-notiser. I artikeln kommer vi att gå igenom hur Service Worker fungerar, hur man skapar ett manifest, vilka cachningsstrategier man ska använda och hur man tillhandahåller offlineåtkomst.
Huvudpunkter
Huvudpunkter
Progressive Web App (PWA) — är ett tillvägagångssätt för webbapplikationsutveckling som kombinerar de bästa egenskaperna från webben och inbyggda appar. Termen introducerades av Francesco Berriman 2015 och Google främjar aktivt PWA som ersättning för enkla mobilappar. Grundtanken: en webbplats förbättras gradvis beroende på webbläsarens och enhetens kapacitet. Om webbläsaren stöder Service Worker — aktiveras offline-läget. Om den stöder manifest — visas knappen «Installera». Om det finns ett API för notiser — kan appen skicka push. En användare på en svag enhet med långsamt internet får grundversionen av webbplatsen, medan en användare på en modern smartphone får en fullfjädrad app med ikon på skrivbordet.
PWA behöver inte installeras via en appbutik. En länk räcker. Detta löser det största problemet med mobilappar — den höga tröskeln. Användaren går inte till Google Play eller App Store, väntar inte på en nedladdning på 100 MB, ger inte tiotals behörigheter. Han öppnar bara webbplatsen och webbläsaren föreslår att installera appen. Om användaren avböjer — använder han ändå webbplatsen. Och om han accepterar — visas ikonen på hemskärmen och appen öppnas som en inbyggd: utan webbläsarens adressfält, i fullskärmsläge och med snabb start.
Tekniskt måste PWA uppfylla tre kriterier: fungera via HTTPS (säker anslutning), ha en Service Worker (bakgrundsbearbetningsskript) och innehålla ett manifest (Web App Manifest). Dessa tre komponenter förvandlar en vanlig webbplats till en installerbar app.
Service Worker — är ett JavaScript-skript som webbläsaren kör i en separat tråd, oberoende av webbsidan. Det har inte åtkomst till DOM, kan inte direkt interagera med gränssnittet, men kan avlyssna och modifiera nätverksförfrågningar, hantera cache, bearbeta push-notiser och utföra bakgrundssynkronisering. Service Worker fungerar som en proxyserver mellan webbläsaren och nätverket: varje förfrågan från sidan går genom Service Worker, som bestämmer — returnera data från cachen, begära från servern eller göra båda.
Service Worker lever enligt sin egen livscykel, oberoende av den öppna sidan. Den installeras, aktiveras och fungerar i bakgrunden även efter att alla flikar på webbplatsen har stängts. Detta gör att PWA kan ta emot push-notiser och uppdatera cachen i bakgrunden, utan användarens medverkan.
Service Worker går igenom fyra stadier: registrering, installation, aktivering och inaktivitet/avslutning.
Registrering. Webbläsaren får en länk till Service Worker JS-filen och börjar ladda ner. Registrering utförs från vanlig JavaScript på sidan:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
console.log('SW registrerad:', registration.scope);
})
.catch(error => {
console.log('SW-registrering misslyckades:', error);
});
}Installation. Efter framgångsrik nedladdning utlöser webbläsaren händelsen install. I detta skede är det vanligt att cachelagra viktiga resurser (HTML-skelett, CSS, huvudbilder) så att appen kan fungera offline. Om installationen lyckas går Service Worker vidare till nästa steg. Om skriptet ger ett fel — avbryts installationen och den gamla Service Worker fortsätter att fungera.
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'
]);
})
);
});Aktivering. När alla flikar på webbplatsen är stängda avslutas den gamla Service Worker och den nya aktiveras. Händelsen activate används för att rensa gamla cacheminnen och migrera data:
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);
}
})
);
})
);
});Inaktivitet. Den aktiverade Service Worker avlyssnar förfrågningar och bearbetar händelser. Den kan stoppas av webbläsaren för att spara resurser och startas om vid nästa förfrågan. Service Worker är händelsestyrd: den lever bara medan den bearbetar händelser.
Service Worker stöder flera cachningsstrategier. Valet beror på resurstypen och kraven på dataaktualitet.
Cache First (cache först). Cachen kontrolleras först. Om resursen hittas — returneras från cachen. Om inte — går förfrågan till servern, svaret sparas i cachen. Strategin är lämplig för statiska resurser: bilder, typsnitt, CSS, JS. Ger maximal hastighet och full offline-funktion.
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 (nätverk först). Förfrågan går först till servern. Om servern svarar — returneras data till användaren och sparas i cachen. Om servern inte är tillgänglig — returneras den cachade kopian. Strategin är lämplig för API-förfrågningar, nyheter, innehåll som måste vara aktuellt men som också kan fungera offline.
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 (föråldrad med uppdatering). Svaret returneras omedelbart från cachen, medan en förfrågan skickas till servern i bakgrunden för att uppdatera cachen. Användaren ser innehållet omedelbart och nästa förfrågan får redan färsk data. Idealisk för innehåll som förändras, men det är inte kritiskt om användaren ser en version som är några minuter äldre.
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;
})
);
});Manifestet — är en JSON-fil, vanligtvis manifest.json, som ansluts via <link>-taggen i head på HTML-sidan. Det talar om för webbläsaren hur appen ska visas när den installeras på enheten: namn, ikoner i olika storlekar, bakgrundsfärg, temafärg, orientering och visningsläge (webbläsare, minimalt UI, fullskärm).
{
"name": "PWA Demo App",
"short_name": "PWA Demo",
"description": "Demo PWA-applikation",
"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"
}
]
}Parametern display bestämmer hur appen ser ut efter installationen. standalone döljer webbläsarens adressfält och navigeringspanel — appen ser ut som inbyggd. fullscreen använder hela skärmen utan några webbläsarelement. minimal-ui lämnar minimala webbläsarelement (bakåt- och uppdateringsknappar).
Ikoner bör förberedas i minst två storlekar: 192x192 och 512x512 pixlar. PNG-format med stöd för parametern purpose (till exempel maskable) gör det möjligt för webbläsaren att anpassa ikonen efter enhetens skalform — på Android kan ikonen beskäras till en rundad kvadrat. Efter att manifestet anslutits börjar Chrome på Android visa banderollen «Lägg till på hemskärmen» när villkoren är uppfyllda: HTTPS, registrerad Service Worker, korrekt manifest och minst två besök med 5 minuters intervall.
PWA kan skicka push-notiser som en inbyggd app. För detta används två API: Push API (serverleverans) och Notification API (visning på enheten). Service Worker tar emot push-händelsen även om appen inte är öppen och kan visa en notis med rubrik, text och ikon.
För att ta emot push-notiser måste användaren ge tillstånd:
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
console.log('Push tillåten');
}
});Service Worker prenumererar på push-händelsen och visar notisen:
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: 'Öppna' },
{ action: 'close', title: 'Stäng' }
]
});
});
self.addEventListener('notificationclick', event => {
event.notification.close();
if (event.action === 'open') {
clients.openWindow('/');
}
});För att skicka push från servern används Web Push (VAPID)-protokollet. Servern krypterar meddelandet och skickar det via webbläsarens push-tjänst (Firebase Cloud Messaging för Chrome, Mozilla Autopush för Firefox). Användarens prenumeration (PushSubscription-objekt) måste sparas på servern vid registrering.
PWA måste vara snabbt. Google Lighthouse — är ett revisionsverktyg som kontrollerar PWA enligt en checklista: Service Worker-registrering, svar 200 vid offlineåtkomst, korrekt manifest, HTTPS, korrekt ikonstorlek, snabb laddning på långsamma nätverk. Minsta godkända poäng för PWA — 80 av 100 på Lighthouse-skalan. Appar med poäng under 80 får ingen installationsbanderoll i Chrome.
Viktiga prestandamått för PWA — First Contentful Paint (FCP) upp till 1,8 sekunder, Largest Contentful Paint (LCP) upp till 2,5 sekunder, Time to Interactive (TTI) upp till 3,5 sekunder. Service Worker kan avsevärt förbättra FCP och LCP om den cachar kritisk HTML och CSS vid installation. Strategin Cache First för statiskt innehåll och Stale While Revalidate för API ger bästa användarupplevelse.
En av PWA:s främsta förmågor — att fungera utan internet. Service Worker avlyssnar förfrågningar och returnerar cachade versioner av sidor. Om användaren försöker öppna en sida som inte finns i cachen kan en anpassad reservsida visas:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
}).catch(() => {
return caches.match('/offline.html');
})
);
});Bakgrundssynkronisering (Background Sync) gör det möjligt att skjuta upp sändning av data till servern om enheten är offline. Service Worker sparar förfrågan och skickar den automatiskt när anslutningen återställs:
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));
}));
});
});
}Chrome DevTools tillhandahåller panelen Application, där du kan felsöka Service Worker (registrering, status, cache, push), kontrollera manifestet, rensa cachen och skapa egna push-notiser för testning. Fliken Network med emulering av offline-läge hjälper till att kontrollera cache-funktionen. Lighthouse i panelen Audits ger en fullständig PWA-revision med rekommendationer.
Workbox — ett bibliotek från Google som förenklar skapandet av Service Worker. Istället för att manuellt skriva cachningsstrategier erbjuder Workbox färdiga moduler:
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 integreras med byggverktyg (Webpack, Vite) och genererar automatiskt föracchmanifestet. PWA Builder (pwabuilder.com) från Microsoft genererar alla PWA-filer online: Service Worker, manifest, ikoner, HTML-mall.
FAQ
PWA — är en webbplats som efter installation på telefonen fungerar som en vanlig app: ikon på skrivbordet, offlineåtkomst, push-notiser, fullskärmsläge utan webbläsarens adressfält. Dessutom behöver du inte gå till App Store eller Google Play — installation sker med ett klick från webbläsaren.
En inbyggd app skrivs för en specifik plattform (Swift för iOS, Kotlin för Android), kräver publicering i en butik och manuell installation. PWA — är en webbplats skriven i HTML, CSS och JavaScript, som kan installeras på enheten via webbläsaren. PWA tar inte mycket plats (endast cache), uppdateras automatiskt och stöds av alla moderna webbläsare.
Chrome, Firefox, Safari (från och med iOS 11.3), Edge, Samsung Internet, Opera. Service Worker stöds av alla moderna webbläsare utom Internet Explorer. Safari har begränsat stöd för push-notiser, men PWA:s grundläggande funktioner (installation på hemskärmen, offlineåtkomst) fungerar.
Ja. För detta behöver du lägga till ett manifest (manifest.json), skapa och registrera en Service Worker (sw.js), överföra webbplatsen till HTTPS, lägga till meta-taggar och ikoner. Själva webbplatsen behöver inte skrivas om om den fungerar på JavaScript och returnerar HTML. Om webbplatsen är helt serverbaserad (MPA) kan Service Worker läggas till som ett cachningslager utan att arkitekturen ändras.
När användaren öppnar PWA kontrollerar webbläsaren om Service Worker-filen på servern har ändrats. Om filen skiljer sig med minst en byte laddar webbläsaren ner den nya Service Worker och startar installationen. Den gamla Service Worker fortsätter att fungera tills alla flikar i appen är stängda. Efter att flikarna stängts aktiveras den nya Service Worker och ersätter den gamla. Användaren kan tvinga fram en uppdatering av appen genom att ladda om sidan.
PWA är motiverat om målet är att nå maximal publik utan kostnader för utveckling på två plattformar, om appen inte kräver djup åtkomst till hårdvara (Bluetooth, NFC, kamera i bakgrunden), om innehållet ändras ofta. För komplexa appar (spel, videoredigerare) är en inbyggd app fortfarande att föredra. PWA används ofta som en extra kanal eller som MVP innan en fullfjädrad app.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också