under de senaste två åren har jag hört termen isomorfa webbappar som nämns på ett positivt sätt allt oftare. Även under denna tid, jag har gjort en del tänker själv om tekniken. Min slutsats är att isomorfa webbappar är något som inte skulle tillföra värde för mig eller de typiska organisationer jag arbetar för. Flera saker har lett mig till denna slutsats.
men innan jag listar orsakerna, låt mig först betona att jag tycker isomorfa javascript-bibliotek (dvs. lodash.js) är fantastiska. Jag tror också att isolerade isomorfa komponenter kan vara värdefulla, till exempel en levande uppdaterad aktiemarknadsindikator.
anledningarna till att jag inte tror att isomorfa webbappar är värdefulla för mig eller de organisationer jag arbetar för är:
- webbservern kan nu bara skrivas i javascript
- isomorfa webbappar kan aldrig vara progressiv förbättring för icke-triviala appar
- blockering vs icke-blockerande dataflöde
- Time-to-interaction och Uncanny Valley
- mobila enheter fryser under tolkning av javascript
- dina bästa utvecklare är nu upptagna med att inte producera värde
jag vill börja med en definition av isomorfa webbappar. En isomorf webbapp är en webbapp där applikationskoden inte har någon kunskap om var den körs. Istället hålls denna kunskap i infrastrukturkoden och gör att applikationen som helhet kan köras på både klient-och serversidan.
- webbservern kan nu bara skrivas i javascript
- isomorfa webbappar kan aldrig vara progressiv förbättring för icke-triviala appar
- blockering vs icke-blockerande dataflöde
- Time-to-interaction och Uncanny Valley
- mobila enheter fryser under tolkning av javascript
- dina bästa utvecklare är nu upptagna med att inte producera värde
- sammanfattning
- erkännanden
webbservern kan nu bara skrivas i javascript
om klientkoden och serverkoden är densamma (och klienten kan idag bara tolka javascript), är vi begränsade till att bara använda javascript på servern. Jag gillar node.js mycket, men jag tror att det är bättre att vara öppen för alternativ i framtiden, i mitt perspektiv.
isomorfa webbappar kan aldrig vara progressiv förbättring för icke-triviala appar
klientsidan javascript har tillgång till en in-memory State-maskin som möjliggör en finkornig nivå av interaktion, med mycket låg latens (under millisekunder). Detsamma gäller inte för HTTP – tillståndsmaskinen, som drivs av länkklick och formulärinlämningar.
för mig är progressiv förbättring att börja med en baslinje som är tillgänglig för alla möjliga enheter/webbläsare, från gamla till nuvarande till framtida. I praktiken innebär detta en baslinje för rendering på serversidan. Förbättringssteget är ett affärsbeslut om var webbplatsen/appen ska förbättras för att öka värdet. Med andra ord görs förbättringen i applikationskoden (specifik) och *inte* i infrastrukturkoden (allmän), förutom optimeringstekniker som pjax eller turbolänkar.
vägen för isomorfa webbappar för att få progressiv förbättring är att ta denna finkorniga in-memory state-maskin och ”översätta” den för att bara använda endast länkar och formulär. De enda Fallen jag kan se var detta är möjligt är där du inte behövde fullständig klientsidan rendering i första hand, men i stället kunde förlita sig på ovan nämnda optimeringstekniker och klientsidan komponenter för att förbättra upplevelsen (dvs. en kalenderkomponent för ett inmatningsfält för ett datum).
en variant av denna lösning är att inte stödja varje klientsidans tillstånd/övergång i serverns tillståndsmaskin. I det här fallet bör detta vara ett affärsbeslut som måste återspeglas i applikationskoden, vilket gör applikationskoden miljökänslig, vilket strider mot tanken på isomorfa webbappar.
vägen för isomorfa webbappar för att få progressiv förbättring är att ta denna finkorniga in-memory state machine och ”översätta” den för att bara använda endast länkar och formulär.
blockering vs icke-blockerande dataflöde
renderingssekvensen för serversidan och klientsidan är olika: serversidan blockerar och klientsidan blockerar inte.
Föreställ dig att vi måste göra två förfrågningar till vissa tjänster för att göra en vy. Vi kan göra dessa förfrågningar parallellt.
på serversidan, om den andra begäran returnerar först, kan den återge den delen av svaret men måste blockera att skicka dessa byte tills den första har återgivit och returnerat den delen av svaret tillbaka till webbläsaren.
på klientsidan finns inte denna begränsning: de två svaren kan hanteras och återges oberoende.
jag tror också att ovanstående representerar det enklaste av exemplen. Tänk dig att du har ett träd av komponenter, där rotkomponenten är smart (se presentations-och Behållarkomponenter för en förklaring av smarta/dumma komponenter), följt av några nivåer av dumma komponenter, och sedan minst en bladkomponent som är smart.
infrastrukturen behöver då ett sätt att se till att smart Leafs sammanhang inte går vilse, så att vi förlorar kontrollen över blockeringen/icke-blockerande körning, beroende på server/klientläge. Ett sätt att lösa detta problem kan vara att få hela programmet att köras i en fri monad, som representerar körningen som data som senare ska tolkas. En annan lösning kan vara att använda någon form av besöksmönster och låta komponenter förklara vilka data de behöver (liknande handledning: Handcrafting en isomorf Redux-applikation (med kärlek)). Det senare är förmodligen lättast. Min poäng är att problemet med olika blockeringslägen förmodligen är mycket mer komplicerat som man föreställer sig initialt.
en alternativ design är att ha en regel som säger ”endast rotkomponenten kan vara en smart komponent”, liknande hur du kan använda IO Monad i Haskell, hålla bladen rena och bara ha biverkningar på toppnivå. Jag tycker att den här designen är bra på serversidan men inte på klientsidan: en komponent på klientsidan ska kunna ladda sina egna data i åtminstone vissa scenarier, till exempel när det gäller sociala medierelaterade komponenter. Att ha en regel som aldrig tillåter dessa scenarier verkar mycket oproduktiv.
Time-to-interaction och Uncanny Valley
med Isomorphic Web Apps-metoden kommer det att finnas en tid där användaren ser grafiska element på skärmen som verkar vara interaktiva men inte. med andra ord, tiden mellan när webbläsaren har gjort serverns svar och när javascript laddas ner, analyseras och körs. Detta kallas ”Uncanny Valley”eller” Potemkin Village”.
se denna tweet och svaren för mer information.
mobila enheter fryser under tolkning av javascript
på en” typisk ” mobiltelefon får du 1ms UI-trådstall per 1KB javascript, enligt denna tweet. Malte Ubl är Teknisk ledare för AMP-projektet, så jag misstänker att han vet vad han pratar om.
dina bästa utvecklare är nu upptagna med att inte producera värde
Isomorphic Web Apps är ett tillvägagångssätt som kräver en hög utvecklingsnivå. På många områden (åtminstone i västvärlden) är det svårt att hitta och rekrytera högkvalificerade Utvecklare. Att välja att utveckla isomorfa webbappar allokerar dessa utvecklare att göra något som jag ifrågasätter ger något affärsvärde alls. Det finns bättre sätt att använda sin tid.
sammanfattning
Isomorphic Web Apps begränsar ditt val av webbserverspråk/plattform till att endast vara javascript. Det har ambitionen att möjliggöra progressiv förbättring, men det kan inte leverera. Det introducerar en hög nivå av teknisk komplexitet på grund av skillnaderna i blockering/icke-blockerande dataflöde. Det introducerar ett tidsfönster där saker verkar vara interaktiva, men inte (The Uncanny Valley). En stor mängd javascript fryser också mobila webbläsare, med tumregeln att 1KB javascript betyder 1ms av stoppad UI-tråd. Och eftersom det kräver en komplicerad mjukvarudesign tar det värdefull tid och ansträngning från dina bästa utvecklare – det finns bättre sätt att använda sin tid.
slutligen vill jag betona att dina erfarenheter kan skilja sig från mina. Kanske finns det scenarier när isomorfa webbappar är bra. Men de är inte en silverkula för att överbrygga varje gap mellan webbfördelar på serversidan och webbfördelar på klientsidan, samtidigt som de inte får någon av nackdelarna med båda metoderna.
vad tycker du? Har du funderat på att ”gå isomorf”? Har du några tankar om utmaningar och kostnader? Hur hanterar du dem?
erkännanden
tack till Oskar Wickstr Jacobm och Per Millikvist för värdefulla diskussioner kring detta ämne. Oskar granskade också detta inlägg-tack Oskar.