Af Spike Brehm
Dette indlæg er blevet krydspostet på VentureBeat.
I Airbnb har vi lært meget i løbet af de sidste par år, mens vi har bygget rige weboplevelser. Vi kastede os ud i app-verdenen med en enkelt side i 2011 med vores mobilwebsite, og siden da har vi bl.a. lanceret Wish Lists og vores nyligt omdesignede søgeside. Hver af disse er en stor JavaScript-app, hvilket betyder, at hovedparten af koden kører i browseren for at understøtte en mere moderne, interaktiv oplevelse.
Denne tilgang er almindelig i dag, og biblioteker som Backbone.js, Ember.js og Angular.js har gjort det lettere for udviklere at bygge disse rige JavaScript-apps. Vi har dog fundet ud af, at disse typer apps har nogle kritiske begrænsninger. For at forklare hvorfor, skal vi først tage en hurtig omvej gennem webapps historie.
JavaScript vokser op
Siden starten af internettet har browsing-oplevelsen fungeret på følgende måde: En webbrowser anmodede om en bestemt side (lad os sige “http://www.geocities.com/”), hvilket fik en server et sted på internettet til at generere en HTML-side og sende den tilbage over kablet. Dette har fungeret godt, fordi browsere ikke var særlig effektive, og HTML-sider repræsenterede dokumenter, der for det meste var statiske og selvstændige. JavaScript, der blev skabt for at gøre websiderne mere dynamiske, gav ikke mulighed for meget mere end billeddiasshow og widgets til at vælge dato.
Efter mange års fremskridt inden for personlig databehandling har kreative teknologer presset internettet til dets grænser, og webbrowsere har udviklet sig for at følge med. Nu er internettet modnet til en applikationsplatform med alle funktioner, og hurtige JavaScript-køretider og HTML5-standarder har gjort det muligt for udviklere at skabe de rige apps, som før kun var mulige på native platforme.
The Single-Page App
Det varede ikke længe, før udviklere begyndte at opbygge hele applikationer i browseren ved hjælp af JavaScript og drage fordel af disse nye muligheder. Apps som Gmail, det klassiske eksempel på single-page-appen, kunne reagere øjeblikkeligt på brugerinteraktioner og behøvede ikke længere at foretage en rundrejse til serveren blot for at rendere en ny side.
Biblioteker som Backbone.js, Ember.js og Angular.js omtales ofte som klientside MVC- (Model-View-Controller) eller MVVM- (Model-View-ViewModel) biblioteker. Den typiske klientside MVC-arkitektur ser nogenlunde sådan ud:
Størstedelen af applikationslogikken (visninger, skabeloner, controllere, modeller, internationalisering osv.) bor i klienten, og den taler til et API for at få data. Serveren kan være skrevet i et hvilket som helst sprog, f.eks. Ruby, Python eller Java, og den håndterer for det meste at servere en indledende HTML-side med barebones. Når JavaScript-filerne er hentet af browseren, evalueres de, og appen på klientsiden initialiseres, idet den henter data fra API’et og gengiver resten af HTML-siden.
Dette er godt for brugeren, for når appen først er indlæst, kan den understøtte hurtig navigation mellem siderne uden at opdatere siden, og hvis det gøres rigtigt, kan den endda fungere offline.
Det er godt for udvikleren, fordi den idealiserede single-page-app har en klar adskillelse af bekymringer mellem klienten og serveren, hvilket fremmer en god udviklingsarbejdsgang og forhindrer behovet for at dele for meget logik mellem de to, som ofte er skrevet i forskellige sprog.
I praksis er der imidlertid et par fatale fejl ved denne tilgang, som forhindrer den i at være den rigtige til mange anvendelsestilfælde.
SEO
En applikation, der kun kan køre på klientsiden, kan ikke servere HTML til crawlere, så den vil som standard have dårlig SEO. Webcrawlere fungerer ved at sende en forespørgsel til en webserver og fortolke resultatet; men hvis serveren returnerer en tom side, er det ikke af stor værdi. Der findes løsninger, men ikke uden at hoppe igennem nogle huller.
Performance
På samme måde vil brugerne, hvis serveren ikke renderer en hel HTML-side, men i stedet venter på, at JavaScript på klientens side gør det, opleve et par kritiske sekunder med en tom side eller en indlæsningsspinner, før de kan se indholdet på siden. Der er masser af undersøgelser, der viser den drastiske virkning, som et langsomt websted har på brugerne og dermed på indtægterne. Amazon hævder, at hver 100 ms reduktion i sideindlæsningstiden øger omsætningen med 1 %. Twitter brugte et år og 40 ingeniører på at ombygge deres websted til at blive gengivet på serveren i stedet for på klienten og hævder, at den opfattede indlæsningstid blev forbedret 5 gange.
Vedligeholdbarhed
Selv om det ideelle tilfælde kan føre til en fin, ren adskillelse af problemer, ender det uundgåeligt med, at nogle dele af applikationslogikken eller visningslogikken ender med at blive dubleret mellem klient og server, ofte i forskellige sprog. Almindelige eksempler er dato- og valutaformatering, valideringer af formularer og routing-logik. Dette gør vedligeholdelsen til et mareridt, især for mere komplekse apps.
Nogle udviklere, mig selv inklusive, føler sig bidt af denne tilgang – det er ofte først efter at have investeret tid og kræfter i at bygge en single-page-app, at det bliver klart, hvad ulemperne er.
En hybrid tilgang
I sidste ende ønsker vi egentlig en hybrid af den nye og den gamle tilgang: Vi ønsker at servere fuldt formet HTML fra serveren af hensyn til ydeevne og SEO, men vi ønsker hastigheden og fleksibiliteten ved applikationslogikken på klient-siden.
Med henblik herpå har vi hos Airbnb eksperimenteret med “Isomorphic JavaScript”-apps, som er JavaScript-applikationer, der kan køre både på klientsiden og server-siden.
En isomorphic app kan se således ud, her døbt “Client-server MVC”: