Gå direkt till sidans huvudinnehåll

När webben upphör att existera... att gå offline

När någon tappat uppkopplingen är det ur personens perspektiv detsamma som att webben inte existerar över huvud taget. Dock med skillnaden att innan webben existerade fanns det andra sätt att lösa saker på samt en vetskap om hur det gick till att få veta saker som vilka filmer som spelades på den närmsta biografen.

Detta inlägg är en sammanfattning av boken Going Offline av Jeremy Keith.

Webbens natur

Webben är allomslutande och ständigt närvarande. Eller snarare, det är vad vi förväntar oss idag. Dock har webben en allvarlig akilleshäl i form av att den är extremt beroende av att alla dess användare och tjänster har en stabil uppkoppling till internet. Webben är bara en av många applikationer som använder internet som sin infrastruktur. En annan applikation är e-posten som dock inte lider lika mycket om ett mejl kommer fram fem minuter efter att det skickats.

När uppkopplingen svajar leder det till att innehåll på webben inte visas som det ska, bilder saknas, video hackar eller stannar av, och frustration i största allmänhet. När man hamnat i radioskugga eller helt tappat uppkopplingen så slutar webben helt att existera, som att den aldrig funnits.

Detta är inte helt ovanligt i tågtunnlar, ute i glesbygd, på tillfälligt populära platser som festivaler eller krisledningscentraler.

Spara filer på nätverk och i besökarens pryl

Det totala beroendet av internet har man försökt lösa genom webbens knappt trettioåriga levnad. Man har byggt diverse cachelösningar vilket går ut på att man sparar delar av webbens innehåll på fler ställen är den ursprungliga webbservern. Ett sådant ställe var att stora arbetsgivare sparade kopior av kända webbplatser i sitt eget nätverk, en annan att de som bygger webbläsare har sett till att filer som inte antas uppdateras så ofta ligger kvar i webbläsarens cache så bara det som har förändrats är något man använder internetuppkopplingen till. Genom att hämta färre saker från nätet ökar chansen att det hela inte misslyckas.

Ett problem var dock att man hade svårt att detaljstyra hur en webbplats skulle hanteras lokalt i användarens pryl/cache. Man kunde egentligen bara ge filer en förväntad livslängd.

Service workers kommer in på sin vita häst

Service workers är en dold process i din webbläsare och de kan kontrollera hur webbläsaren beter sig i relationen mellan en webbplats och uppkopplingen från din pryl. Det här med att något funkar utan uppkoppling har tidigare varit det främsta säljargumentet för att bygga mobilappar, men med service workers kan vilken webbplats som helst även detta.

En service worker är ett skript som skrivs i språket Javascript. Du som likt mig jobbat med webben sedan Javascript hette Livescript kanske drar öronen åt dig och misstänker att det här är att öppna pandoras box. Som tur är har en service worker begränsade superkrafter, bland annat att styra när nytt material hämtas över nätet.

Prestandavinster

När du hämtar en sida från webben skickas materialet via internets infrastruktur. Det kan handla om att ta sig över några kontinenter, genom kablar under haven och, kanske inte så ofta, över en satellit i omlopp runt jorden. Sånt tar tid och för många webbplatser är tid pengar.

Att då skicka, och vänta på, filer som lika gärna kan ligga kvar i användarens pryl mellan besöken är verkligen onödigt. Eller att den produkt som ligger överst i en produktlista inte kan visas för att användaren duttade på skärmen samtidigt som hen åkte in i en tunnel utan uppkoppling.

Med service workers kan webbplatsen i detalj spara undan filer som gör sig bäst lokalt på en användares pryl och kan proaktivt ladda ner material som man kan förutspå kommer att komma till användning. Då gör man sig mindre beroende av uppkopplingen genom att webbläsarens service worker serverar innehåll den redan hämtat ner.

För att lyckas övertrumfa att en fil redan laddats ner men att man ändå vill skicka ett nytt innehåll direkt från webbservern så ger man den nya filen ett nytt namn. Inte helt ovanligt att man har versionsnummer i filnamnet. Så vill man byta ut loggan får man helt enkelt i koden anropa logotyp-v2.png istället för logotyp.png, då spelar det ingen roll att den första loggan redan finns hos en massa användare och att dess tilltänkta livstid var fram till domedagen. Men det här med cachestrategier får vi gå in på en annan gång, det blir lätt jäkligt komplicerat.

Skapa en offline-sida

Den mest uppenbara exemplet på när en service worker briljerar är när den håller koll på om webbläsaren är ansluten till nätet. Om uppkopplingen försvann kan den avbryta hämtningen från nätet och istället visa en felsida den förberett som värsta tv-kocken.

 
[caption id="attachment_6271" align="alignnone" width="650"]Offline-sida hos SVTplay SVT:s felsida för att användaren troligen är offline.[/caption]

Dock finns två begränsningar för att en service worker ska kunna jobba.

  1. Den jobbar bara mot en domän. Det innebär att du kan inte hämta material från en alternativ källa om webbplatsen går ner. Alltså måste en service worker placeras på webbplatsens huvuddomän.
  2. Kräver HTTPS, vilket gör att om man inte erbjuder webbplatsen via HTTPS-protokollet får man lösa det först.

Service worker följer webbstandard, närmare bestämt Progressive Enhancements, vilket innebär att det inte förstör något för de äldre webbläsarna som inte vet vad service workers är för något. Därför kan man dra nytta av det redan nu utan att behöva oroa sig för den typen av tekniska konsekvenser.

För att få till en offline-sida behöver man några saker:

  1. Stoppa in en hänvisning till sin service worker i HTML-kodens HEAD-tag samt “registrera” den.
  2. Skapa en fil med service workerns innehåll, gärna i webbplatsens rot och se till att den inte hamnar i någon cache.
  3. Ta fram en offline-sida och se till att service workern lägger den lokalt i användarens pryl och att den väntar där tills den behövs.

Den första åtgärden är enkel. Se till att ha nedan kod i varje HTML-sidas HEAD-tag, det här är vad som kallas för dess “registration”:

<link rel="serviceworker" href="/serviceworker.js">

Sen behöver en service worker också “registreras” så de används, det görs med nedan kod vilket du kan placera lite var som helst på dina HTML-sidor eller inkludera i externa Javascript. Om du registrerar i en HTML-fil ska koden se ut så här:

<script>
if (navigator.serviceWorker) {
  navigator.serviceWorker.register('/serviceworker.js');
}
</script>

Raden som börjar med if är en så kallad feature detector. Det innebär att den kollar om webbläsaren förstår vad en service worker är för något. Skriptet körs bara om webbläsaren säger sig förstå vad en service worker är.

Innehållet i en service worker

Placerar man sin service worker direkt i webbplatsens rot så kan den kontrollera alla webbadresser för hela webbplatsen. Det är enklast så men det finns andra sätt.

Innehållet i en service worker kan se ut som nedan kod för att få till funktionen att ha en offline-sida.

const version = 'V0.01';
const staticCacheName = version + 'staticfiles';
addEventListener('install', installEvent => {
  installEvent.waitUntil(
    caches.open(staticCacheName)
    .then( staticCache => {
      // dessa filer blockerar inte installationen
      staticCache.addAll([
        '/static/fonts/font.woff',
        '/static/img/logo.svg'
      ]); // end addAll
      // dessa filer måste cachas för en installation
      return staticCache.addAll([
        '/static/css/stylesheet.css',
        '/static/js/javascript.js',
        '/offline.html'
      ]); // end return addAll
    }) // end open then
   ); // end waitUntil
}); // end addEventListener

Man behöver se till att ens service worker kan uppdateras. Det görs genom att sätta en extremt kort livslängd på den filen. Kör du Wordpress eller någon Apache-baserad webbserver har du redan (eller kan skapa) en fil vid namn .htaccess direkt i webbplatsens rot. Ger man den textfilen nedan kod kommer filen serviceworker.js alltid att hämtas på nytt och kan därför förändras.

<IfModule mod_expires.c>
  <FilesMatch "serviceworker.js">
    ExpiresDefault "access plus 0 seconds"
  </FilesMatch>
</IfModule>

Själva offline-meddelandet

Nedan är ett exempel på hur filen offline.html kan se ut, den förväntas ligga i webbplatsens rot om du använder ovanstående kodexempel på service worker. Också värt att tänka på är att den service worker du har kod för ovan räknar med att du har fler filer. Nämligen ett teckensnitt, en logga som SVG, Javascript och CSS. Stryk dessa rader om dessa filer inte används.

<!DOCTYPE html>
<html lang="sv-SE" dir="ltr">
	<head>
		<meta charset="utf-8">
		<title>Oj! Uppkopplingen försvann</title>
	</head>
	<body>
		<h1>Oops!</h1>
		<p>Något har hänt med uppkopplingen mot webbplatsen. Pröva att ladda om snart igen.</p>
	</body>
</html>

Om du vill provköra detta i skarpt läge behöver du antingen veta hur du startar en webbserver på din egen dator eller om du vill testa på en labbsajt innan du går över till skarpt läge.

Hur ska en bra offline-sida designas?

Mmm, det är en bra fråga. Just nu ges det främst exempel på snygga, fyndiga eller på andra sätt tilltalande sidor. Snart kommer det säkert sätta sig en praxis för vad som är användbart och då är det klokt att följa den konventionen precis som vi gör för Error 404-sidor.

Vill du också göra sajten till en Progressive Web App (PWA) när du ändå är igång?

Genom ovanstående åtgärder är du till tvåtredjedelar färdig med att skapa en PWA. Det du saknar är ett manifest. Även den filen ska pekas ut i varje HTML-sidas HEAD-tag, det ser ut så här om du lägger filen i webbplatsens rot:

<link rel="manifest" href="/manifest.json">

Själva innehållet i filen är strukturerat i ett format som heter JSON, ett nyckelord:värde-format och innehållet som sådant är en massa metadata om webbplatsen. Det kan se ut så här:

{
  "lang": "en",
  "name": "Min webbplats",
  "short_name": "Webbplatsen",
  "description": "Det här är min webbplats.",
  "theme_color": "#336699",
  "background_color": "#336699",
  "start_url": "/",
  "display": "standalone",
  "icons": [
    {
      "src": "/images/small-icon.png",
      "sizes": "48x48",
      "type": "image/png"
    },
    {
      "src": "/images/large-icon.jpg",
      "sizes": "512x512",
      "type": "image/jpeg"
    }
  ]
}

Mer om Service Workers och Progressive Web Apps

Läs också gärna artikeln om progressiva webbappar och AMP här på Webperf