Översikt
Du inleder detta treveckorsblock med kursens sista teoripass. Sedan är det fullt fokus på examinationsuppgift B3 som gäller! Kursledningen önskar samtidigt dig en riktigt 🎅 God Jul och ett 🎆 Gott Nytt År! Information om veckornas upplägg annonseras löpande i kursens Zulip-kanal.
Stödjande inspelningar
Section titled “Stödjande inspelningar”Kapabla PWAs
Section titled “Kapabla PWAs”Målet: webben som en fullvärdig applikationsplattform
Section titled “Målet: webben som en fullvärdig applikationsplattform”En central del av vad som gör en Progressive Web Application (PWA) “kapabel” är att den ska kunna bete sig och kännas som en native-installerad applikation, utan att sakna möjligheter jämfört med den. Webben är inte helt i mål än, men rör sig konsekvent åt det hållet – varje år tillkommer fler webbläsar-API:er som ger tillgång till funktionalitet som tidigare krävde en native app. Den här genomgången är en katalog över den typen av API:er: ingen förväntas kunnas utantill, poängen är att veta att de finns och kunna slå upp dem när behovet uppstår.
Grafik och media
Section titled “Grafik och media”Canvas API (<canvas>, del av HTML5) ger en rityta för att rita vektorgrafik direkt med JavaScript – grafer, bildkomposition, animationer, enklare realtidsspel. Perfekt när HTML-element (till exempel en massa <div>-boxar för ett stapeldiagram) blir för klumpigt att animera snyggt.
WebGL går längre och ger hårdvaruaccelererad 3D-grafik i webbläsaren utan att användaren behöver installera något extra – bygger på samma grundprinciper som OpenGL. Används bland annat för portade spel och tunga visuella demos direkt i webbläsaren.
WebXR API (tidigare WebVR, omdöpt för att täcka både AR och VR under ett gemensamt namn i W3C) ger tillgång till AR/VR-utrustning direkt från webbläsaren – webben som plattform för den typen av upplevelser är fortfarande i sin linda, men stödet finns.
Gamepad API låter en lyssna på händelsen gamepadconnected när en spelkontroll ansluts till datorn, och därefter koppla händelsehanterare till enskilda knappar – på liknande sätt som klickhändelser på vanliga element.
Kommunikation med enheter och andra klienter
Section titled “Kommunikation med enheter och andra klienter”Flera API:er ger webbapplikationer tillgång till kommunikationsvägar som traditionellt gått via operativsystemet eller en native app:
- Web Bluetooth – synka och kommunicera med Bluetooth-enheter direkt från webbläsaren.
- Web NFC API – läsa/skriva NFC (Near Field Communication), samma teknik som “blippning” vid kortbetalning. Vissa plattformar (historiskt särskilt Apple/Safari) har varit restriktiva med att öppna upp NFC-åtkomst, även för native-appar.
- Web USB API – kommunicera med anslutna USB-enheter.
- WebRTC (Web Real-Time Communication) – peer-to-peer-kommunikation direkt mellan klienter, utan att trafiken behöver gå via en mellanliggande server. Relevant för videochatt eller andra realtidsapplikationer där det vore onödigt (och en integritetsrisk) att låta all trafik passera en server som kanske ligger geografiskt långt bort, trots att båda klienterna sitter i samma nätverk. Ett samlingsbegrepp för flera API:er (
MediaStream,MediaRecorder,RTCPeerConnection,RTCDataChannel) beroende på om man vill skicka video, filer eller annan data. Stödet är idag i praktiken fullständigt i moderna webbläsare.
Generellt gäller: tittar man på kompatibilitetstabeller (till exempel “Can I use”) för de här nyare API:erna är det oftast Safari/iOS Safari som ligger efter i implementation, medan Chrome och Firefox brukar leda beroende på vilken av dem som ursprungligen föreslog API:et.
Betalningar och delning
Section titled “Betalningar och delning”Payment Request API låter webbläsaren själv hålla koll på användarens sparade betalkort, med strikt kontroll över hur webbplatser får använda den informationen – ett försök att lösa samma problem som aktörer som Klarna eller Apple Pay/Google Pay redan löser på andra sätt. Stödet varierar mellan webbläsare och är starkare på desktop än mobil, vilket är en svaghet eftersom mobil e-handel är där behovet ofta är som störst.
Web Share API låter en webbsida trigga operativsystemets inbyggda delningsmeny (samma meny som dyker upp när man delar en länk från mobilens webbläsare). Web Share Target API är den omvända riktningen: gör en installerad PWA till ett valbart mål i andra appars delningsmeny.
Web Animation API ger möjlighet att styra animationer direkt via JavaScript, som ett alternativ till att uteslutande deklarera dem i CSS.
API:er kommer och går – var källkritisk
Section titled “API:er kommer och går – var källkritisk”En viktig poäng som återkommer: många av de nyare, mer udda API:erna är fortfarande utkast (drafts), och flera har redan dragits tillbaka eller kraftigt förändrats efter att ha införts, oftast av integritetsskäl. Två konkreta exempel: Battery Status API (avslöjade användarens batterinivå – togs bort i Firefox som alltför integritetskänsligt) och Vibration API (togs bort i WebKit). Andra API:er värda att känna till, med samma brasklapp om instabilitet: Geolocation API (positionsuppgifter, med obligatorisk användarbekräftelse), Clipboard API (kopiera/klistra in – med varningsdialog i moderna webbläsare, likt native-appar), Ambient Light (omgivande ljusnivå, till exempel för att växla mellan ett dag- och ett nattläge), Device Orientation API (enhetens fysiska rotation – kan delvis också läsas ut via CSS) och Speech Recognition API (taligenkänning/diktering).
Slutsatsen: anta aldrig att ett nytt, udda webbläsar-API kommer finnas kvar för evigt i sin nuvarande form – kontrollera aktuellt stöd innan man bygger vidare på det, särskilt för API:er som rör känslig information om användaren eller enheten.
Dynamiskt kontra statiskt typade språk
Section titled “Dynamiskt kontra statiskt typade språk”JavaScript är dynamiskt typat: en variabels typ kan ändras under körning (en variabel som börjar som ett tal kan senare bli en sträng eller ett objekt). Enda sättet att helt spärra det i ren JavaScript är const – men det låser bara referensen, inte innehållets typ i alla lägen.
Statiskt typade språk (till exempel Java) kräver att typen deklareras redan när koden skrivs, och kompilatorn vägrar kompilera kod som bryter mot den deklarationen (greeting = 2 på en variabel deklarerad som String ger kompileringsfelet “incompatible types: int cannot be converted to String”). Studenter som gått från ett statiskt typat språk till JavaScript brukar landa ungefär 50/50 i om de föredrar den tidiga felkontrollen kompilatorn ger, eller den snabbare, mer flexibla arbetsgången utan typdeklarationer – ingen av synpunkterna är fel, det är en avvägning. En konsekvens värd att notera: eftersom JavaScript inte tvingar fram typdeklarationer blir tydlig dokumentation av vilka typer en funktion förväntar sig (t.ex. via JSDoc) desto viktigare, för att kompensera för det kompilatorn annars skulle fångat upp automatiskt.
TypeScript – JavaScript med valfria typer
Section titled “TypeScript – JavaScript med valfria typer”TypeScript (Microsoft, 2012) lägger till valfri statisk typning ovanpå JavaScript-syntaxen:
let fullName: string = 'Bob Bobbington'let age: number = 37Filer skrivs med filändelsen .ts och kompileras (npx tsc index.ts) till vanlig .js som webbläsaren faktiskt kan köra – verktyg som Babel gör ofta den här typen av omskrivning i bakgrunden som en del av byggpipelinen (Snowpack, Webpack, Parcel och liknande). Deno (skaparen av Node.js sidoprojekt, en omarbetad variant av Node) har numera inbyggt stöd för TypeScript utan separat kompileringssteg. TypeScript är inte ett nytt språk att lära sig från grunden – det är JavaScript med ett tillägg, och begreppet kommer att dyka upp ofta i presentationer och verktygsbeskrivningar oavsett om man själv väljer att använda det.
WebAssembly – att köra annan kod i webbläsaren
Section titled “WebAssembly – att köra annan kod i webbläsaren”WebAssembly (etablerat 2017 gemensamt av W3C, Google, Apple, Mozilla och Microsoft) gör det möjligt att kompilera kod skriven i andra språk (C, C++, Rust, med flera) till ett binärt format som körs direkt i webbläsaren, parallellt med och kommunicerande med JavaScript. Anledningen det är intressant: JavaScripts dynamiska typning gör det svårt för motorn att göra samma djupa optimeringar som ett statiskt typat, kompilerat språk tillåter (se nästa avsnitt). WebAssembly används framför allt för att låna in bibliotek från andra ekosystem (till exempel avancerade bildbehandlingsalgoritmer skrivna i C) och i situationer där prestanda är kritisk. Google Earth är ett konkret exempel på en WebAssembly-baserad applikation i produktion. AssemblyScript är ett TypeScript-liknande språk designat specifikt för att kompileras till WebAssembly, för den som vill slippa lära sig ett helt nytt språk bara för det syftet.
Varför det här är värt att känna till
Section titled “Varför det här är värt att känna till”Webben fortsätter att växa i betydelse som applikationsplattform, inte bara på mobil utan även på desktop – många klarar sig idag i praktiken med enbart en webbläsare (Chromebooks som exempel). Att specialisera sig på klientsideutveckling är därför inget begränsat val: de här API:erna, tillsammans med webbkomponenter och de standarder som redan gåtts igenom i kursen, är byggstenarna som gör webben till en plattform i klass med native-utveckling – inte en ersättning för alla andra verktyg, men en allt starkare kandidat för allt fler typer av applikationer.
Web Sockets API
Section titled “Web Sockets API”Varför HTTP inte räcker för realtidsdata
Section titled “Varför HTTP inte räcker för realtidsdata”HTTP designades ursprungligen för att servera enstaka HTML-dokument: klienten initierar alltid en förfrågan, servern svarar, klar. Modellen har relativt mycket overhead per anrop och passar dåligt när applikationen behöver realtidsdata – en graf som ska uppdateras live utifrån inkommande mätvärden, positionerna för alla spelare i ett webbaserat spel, eller ett chattmeddelande som ska dyka upp hos alla andra anslutna klienter så fort någon skickar det.
Att skicka data till servern med ett vanligt fetch-anrop är inget problem i sig. Problemet är att få reda på när ny data finns att hämta – det enda sättet en klient kan göra det med bara HTTP är att fråga servern om och om igen (“har det kommit något nytt? har det kommit något nytt?”, som ett barn i baksätet som frågar “är vi framme snart?”). Kortare intervall mellan frågorna ger snabbare uppdateringar men belastar servern hårt med ständiga anrop som oftast inte ger något nytt svar. En äldre teknik, long polling, förbättrade detta något genom att låta servern hålla kvar en HTTP-förfrågan öppen istället för att svara direkt, tills antingen ny data fanns eller anropet tajmade ut – men det är fortfarande en omväg runt en begränsning i HTTP snarare än en riktig lösning.
Web Sockets: ett eget protokoll, inte HTTP
Section titled “Web Sockets: ett eget protokoll, inte HTTP”WebSocket (ws://) och WebSocket Secure (wss://, den krypterade varianten) är ett eget protokoll, skilt från HTTP – men det delar samma portar som HTTP (80 respektive 443), vilket betyder att brandväggar som redan släpper igenom vanlig webbtrafik även släpper igenom WebSocket-trafik utan extra konfiguration.
Uppkopplingen börjar med en handskakning: klienten frågar servern om anslutningen kan uppgraderas till en WebSocket-connection, och accepterar servern det uppgraderas den vanliga uppkopplingen till en socket – i praktiken en öppen tvåvägstunnel mellan klient och server. Skillnaden mot HTTP är avgörande: när socketen väl är öppen kan båda sidor skicka data när som helst, inte bara klienten som initierar. Web Sockets passar bäst för relativt små datapaket som skickas ofta (positionsuppdateringar, chattmeddelanden) snarare än stora, sällsynta dataöverföringar – där finns ingen “bestraffning” för att skicka ofta, till skillnad från upprepade HTTP-anrop.
API:et
Section titled “API:et”const socket = new window.WebSocket('ws://www.example.com/socketserver', 'chatroom')
const data = { x: 12, y: 14 }
socket.addEventListener('open', event => { socket.send(JSON.stringify(data))})
socket.addEventListener('message', event => { console.log(event.data)})
socket.close()Andra argumentet till konstruktorn ('chatroom' ovan) är en fritt vald textsträng – ett protokollnamn som klient och server kommer överens om, användbart för att skilja olika typer av meddelanden eller kanaler åt om samma server hanterar flera parallella syften.
De två händelser som täcker de flesta behov: open, som talar om att uppkopplingen är uppgraderad och klar – data kan inte skickas förrän den har utlösts – och message, som utlöses varje gång ett meddelande kommer in från motparten (event.data innehåller den mottagna texten). Eftersom socket.send() bara skickar ren text är det vanligt att serialisera data med JSON.stringify före sändning och JSON.parse vid mottagning.
Web Socket-API:et togs fram runt 2010–2011, vilket syns i att det bygger på händelselyssnare/callbacks snarare än till exempel Promises – men API:et i sig är litet och okomplicerat att jobba med.
Livslängd och nedstängning
Section titled “Livslängd och nedstängning”En socket som är helt tyst en längre stund (ofta runt 60 sekunder, beroende på serverkonfiguration) kan tajma ut och stängas automatiskt. Ska en uppkoppling hållas vid liv trots låg aktivitet behöver servern skicka periodiska meddelanden på kanalen. Händelsen close utlöses när en socket stängs, oavsett om det sker av en timeout eller manuellt via socket.close(). Ligger en socket inuti en webbkomponent är disconnectedCallback en lämplig plats att stänga den manuellt och städa upp, på samma sätt som andra resurser som startats av komponenten.
Kursen kräver inte att man själv skriver en WebSocket-server (en sådan tillhandahålls för de examinationsuppgifter som behöver det) – fokus ligger på att kunna konsumera ett WebSocket-API från klientsidan.
Läsanvisningar
Section titled “Läsanvisningar”Under läsanvisningar hittar du veckornas kapitel som ska läsas i kurslitteraturen. Planera upp och dela upp läsningen under veckorna.
Handledning
Section titled “Handledning”Några handledningspass finns insprängda under veckorna. I övrigt hänvisas du till Zulip! Första timmen på handledningen kommer ett ett Zoom-möte öppnas där kursledningen kommer att svara på frågor generellt. Skicka gärna in frågor på förhand via formuläret som du når här:
Examinationsuppgift B3
Section titled “Examinationsuppgift B3”Fortsätt arbetet med examinationsuppgiften. Läs mer om examinationsuppgift B3.
