Isomorfism- nyckeln till att få JavaScript-applikationer att fungera även utan JavaScript

SVT är ett public service-bolag, och som sådant är stor tillgänglighet för våra besökare inte bara en bra idé, utan ett krav som är lagstadgat. Tillgänglighet har därför alltid varit enormt viktigt för oss, vilket är bekymmersamt då mängden olika enheter som våra besökare använder konstant ökar.

Vi är förstås intresserade av att ligga i bräschen, använda oss av den bästa teknologin som finns tillgänglig för oss, och att erbjuda våra besökare den bästa upplevelsen vi förmår. Det innebär dock att vi får lägga mycket tid på bakåtkompatibilitet, med otaliga fallbacklösningar och specialgrepp för enskilda webbläsare och enheter som konsekvens.

På grund av detta började vi för något år sedan utforska möjligheten till att köra samma kod både på servern och webbläsaren. Konceptet kallas för Isomorphic JavaScript och populäriserades av Airbnb i en uppmärksammad bloggpost i slutet av 2013.

Själva isomorfismen i Isomorphic JavaScript handlar om att samma kodbas går att köra både i webbläsaren och på servern. Med andra ord, till de användare som saknar moderna webbläsare eller har udda enheter kan vi skicka ut en förrenderad version av den kod som vi annars kör direkt i webbläsaren. Som följd av detta blir det mycket lättare för oss att använda nya teknologier och samtidigt känna oss säkra på att det kommer att fungera för ett maximalt antal användare.

Så hur fungerar det då?

Det är egentligen inte så komplicerat. När ett första anrop når servern, hämtar JavaScriptet data från backendsystemet, och renderar därefter ut färdig HTML som skickas till klienten. Sidan visas direkt för användaren så fort den förrenderade HTMLen tagits emot. Under tiden drar JavaScript-applikationen igång i bakgrunden hos klienten och “hängs på” på den förrenderade HTMLen. Alla vidare anrop sker därmed asynkront, utan att servern renderar om sidan. Om JavaScript inte stöds av klienten (eller stöds dåligt) så renderar servern om HTMLen för varje anrop istället, som med traditionella webbramverk.

Bild Henrik Eneroth : Visualisering av dataflöden genom en ismorfisk applikation

Isomorphic JavaScript är inte ett ramverk, utan snarare ett mönster, och kräver därmed ingen specifik teknologi. Vi tycker dock att det underlättar väsentligt att använda NodeJS för att exekvera JavaScript-kod på servern.

React

För att kunna jobba helt isomorfiskt med vår applikation behöver vi alltså kunna rita ut den på både server och klient. Det innebär att vi måste kunna hålla den plattforms-specifika koden till ett minimum. För att lösa det problemet har vi valt att använda React.

React ett JavaScript-bibliotek som utvecklas och används av Facebook, men som också börjat användas av andra stora aktörer som Netflix, Yahoo, och nu även av oss på SVT.

React möjliggör en sammanhållen kodbas för både server och klient, men det finns många andra fördelar med React. Det mesta går att läsa om på verktygets hemsida, men för att nämna något så tycker vi att Facebook har hittat ett genialt sätt att hantera den annars ganska ohanterliga DOMen i webbläsaren.

Istället för att detaljstyra ändringar i DOMen kan vi genom att använda React koncentrera oss på att berätta för vår applikation vad som ska hända, istället för att bry oss särskilt mycket om hur det ska ske. React löser detta genom att rendera alla förändringar som vi efterfrågar till en virtuell DOM. När en förändring sker i den virtuella DOMen så räknar React själv ut vad det innebär för förändringar i webbläsarens DOM, och utför de uppdateringar som behövs. Det här förloppet liknar väldigt mycket den renderingsloop som återfinns i spelmotorer, där jobbet är att räkna ut vilka delar av spelvärlden som ska uppdateras, och vad som inte har förändrats och därmed inte behöver någon uppdatering. I både fallet med ett spel och med webbläsaren så innebär detta att vi får bättre prestanda än om alltihop skulle renderas om vid varje förändring.

På Facebook har de även tänkt på att den mentala modellen av en applikation ska vara enkel och lätt att resonera kring. React byggs med hjälp av sammanhängande kodbitar som kallas för components. Målet är att en komponent ska vara hyfsat fristående, och att det ska gå att förstå vad som händer när man läser källkoden för den. React uppmuntrar på så sätt till utveckling av applikationer som är tydliga och lätta att förstå.

För SVTi som organisation är detta förstås otroligt värdefullt. När en ny utvecklare börjar med ett React-projekt så går det förhållandevis snabbt att ändra en komponent.

Flux

React säger egentligen ingenting om hur man ska strukturera en applikation. Det är inte ett ramverk i den klassiska bemärkelsen där det finns tydliga mönster för hur saker och ting ska göras, och det är avsiktligt. Facebook har istället valt att utveckla en separat applikationsarkitektur som heter Flux.

Bild Henrik Eneroth : Visualisering av dataflöden genom en flux applikation

Flux sätter framförallt en struktur på hur data lagras och flödar genom applikationen. Detta gör det lättare att spåra förändringar vilket i sin tur förenklar både utveckling och felrättningar, vilket är en av anledningarna  till att vi på SVTi har valt att använda oss av den.

Det är också värdefullt för oss att strukturera alla våra applikationer på ett liknande sätt så att utvecklare som är obekanta med kodbasen snabbt kan komma igång.

Slutligen

Isomorfiska JS-applikationer är fortfarande en relativt ny företeelse. Det experimenteras fortfarande mycket, och saker förändras fort. Det finns dock i vår mening ingen anledning att vänta med att arbeta isomorfiskt, tvärtom finns det en mängd fördelar redan nu. Vi har redan nämnt flera av dessa: det är lättare att strukturera koden, applikationer upplevs som snabbare, det blir lättare att hitta buggar, etc. Men en sak till måste nämnas: det här är ett otroligt roligt sätt att jobba på. Det är kul att skriva saker i React, och det gör automatiskt att allt annat blir mycket lättare.

Det är dessutom väldigt roligt att vara med och befästa teknologin och hitta nya vägar framåt. Fördelarna är många, för oss själva, för vår avdelning, och i slutändan för våra användare i det att vi tar oss framåt snabbare, men utan att för den sakens skull glömma dem på äldre enheter eller webbläsare. I slutändan blir det en rikare användarupplevelse för alla.

Extra tack till Henrik Eneroth för hjälpen.

För er som vill veta mer kommer här lite länkgodis.
Community

React

Komma igång

Olika miljöer

Flux