By Spike Brehm
Detta inlägg har korsats på VentureBeat.
På Airbnb har vi lärt oss mycket under de senaste åren när vi byggt rika webbupplevelser. Vi dök in i appvärlden med en enda sida 2011 med vår mobila webbplats, och har sedan dess lanserat bland annat Wish Lists och vår nydesignade söksida. Var och en av dessa är en stor JavaScript-app, vilket innebär att huvuddelen av koden körs i webbläsaren för att stödja en modernare, interaktiv upplevelse.
Detta tillvägagångssätt är vanligt idag, och bibliotek som Backbone.js, Ember.js och Angular.js har gjort det enklare för utvecklare att bygga dessa rika JavaScript-appar. Vi har dock upptäckt att dessa typer av appar har vissa kritiska begränsningar. För att förklara varför, låt oss först ta en snabb omväg genom webbapparnas historia.
JavaScript växer upp
Sedan webbens början har surfupplevelsen fungerat så här: en webbläsare begärde en viss sida (låt oss säga ”http://www.geocities.com/”), vilket ledde till att en server någonstans på Internet genererade en HTML-sida och skickade den tillbaka över kabeln. Detta har fungerat bra eftersom webbläsare inte var särskilt kraftfulla och HTML-sidor representerade dokument som för det mesta var statiska och fristående. JavaScript, som skapades för att göra webbsidor mer dynamiska, möjliggjorde inte mycket mer än bildspel och widgetar för att välja datum.
Efter år av framsteg inom persondatorer har kreativa tekniker drivit webben till dess gränser, och webbläsare har utvecklats för att hänga med. Nu har webben mognat till en applikationsplattform med fullständiga funktioner, och snabba JavaScript-körtider och HTML5-standarder har gjort det möjligt för utvecklare att skapa de rika appar som tidigare bara var möjliga på inhemska plattformar.
Den ensidiga appen
Det dröjde inte länge förrän utvecklare började bygga upp hela applikationer i webbläsaren med hjälp av JavaScript, och dra nytta av dessa nya möjligheter. Appar som Gmail, det klassiska exemplet på en-sidig app, kunde reagera omedelbart på användarens interaktioner och behövde inte längre göra en rundresa till servern bara för att rendera en ny sida.
Bibliotek som Backbone.js, Ember.js och Angular.js kallas ofta för klientsidebibliotek med MVC- (Model-View-Controller) eller MVVM- (Model-View-ViewModel) beteckningar. Den typiska MVC-arkitekturen på klientsidan ser ut ungefär så här:
Den största delen av applikationslogiken (vyer, mallar, controllers, modeller, internationalisering etc.) bor i klienten, och den pratar med ett API för data. Servern kan skrivas i vilket språk som helst, t.ex. Ruby, Python eller Java, och den hanterar huvudsakligen servering av en första HTML-sida. När JavaScript-filerna laddas ner av webbläsaren utvärderas de och appen på klientsidan initieras, hämtar data från API:et och renderar resten av HTML-sidan.
Detta är bra för användaren eftersom appen, när den väl har laddats initialt, kan stödja snabb navigering mellan sidor utan att behöva uppdatera sidan, och om det görs på rätt sätt kan den till och med fungera offline.
Detta är bra för utvecklaren eftersom den idealiserade appen med en enda sida har en tydlig åtskillnad mellan klienten och servern, vilket främjar ett trevligt utvecklingsarbetsflöde och förhindrar behovet av att dela för mycket logik mellan de två, som ofta är skrivna i olika språk.
I praktiken finns det dock några fatala brister med det här tillvägagångssättet som gör att det inte är rätt för många användningsfall.
SEO
En applikation som bara kan köras på klientsidan kan inte servera HTML till crawlers, så den kommer att ha dålig SEO som standard. Webbsökare fungerar genom att göra en förfrågan till en webbserver och tolka resultatet; men om servern returnerar en tom sida är det inte av särskilt stort värde. Det finns lösningar, men inte utan att man måste ta sig igenom några hinder.
Prestanda
På samma sätt, om servern inte renderar en hel HTML-sida utan i stället väntar på att JavaScript på klientsidan ska göra det, kommer användarna att få uppleva några kritiska sekunder med en tom sida eller en laddningsspinnare innan de kan se innehållet på sidan. Det finns gott om studier som visar den drastiska effekt som en långsam webbplats har på användarna och därmed på intäkterna. Amazon hävdar att varje 100 ms minskning av sidans laddningstid ökar intäkterna med 1 %. Twitter ägnade ett år och 40 ingenjörer åt att bygga om sin webbplats för att rendera på servern i stället för på klienten och hävdar att den upplevda laddningstiden förbättrats med fem gånger.
Underhållbarhet
Samtidigt som idealfallet kan leda till en snygg och ren separation av problemställningar, är det oundvikligt att vissa bitar av applikationslogik eller visningslogik hamnar i duplicerad form mellan klient och server, ofta i olika språk. Vanliga exempel är datum- och valutaformatering, validering av formulär och routningslogik. Detta gör underhållet till en mardröm, särskilt för mer komplexa appar.
En del utvecklare, däribland jag själv, känner sig biten av detta tillvägagångssätt – det är ofta först efter att ha investerat tid och ansträngning i att bygga en app med en enda sida som det blir tydligt vilka nackdelarna är.
En hybridmetod
I slutändan vill vi egentligen ha en hybrid av den nya och den gamla metoden: vi vill servera helt formad HTML från servern för prestanda och SEO, men vi vill ha snabbheten och flexibiliteten hos programlogik på klientsidan.
För detta ändamål har vi på Airbnb experimenterat med ”Isomorphic JavaScript”-appar, som är JavaScript-applikationer som kan köras både på klient- och serversidan.
En isomorf app kan se ut så här, som här kallas ”Client-server MVC”: