In den letzten zwei Jahren habe ich den Begriff isomorphe Web-Apps immer häufiger positiv erwähnt hören. Auch in dieser Zeit habe ich mir einige Gedanken über die Technik gemacht. Meine Schlussfolgerung ist, dass isomorphe Web-Apps für mich oder die typischen Organisationen, für die ich arbeite, keinen Mehrwert bieten würden. Mehrere Dinge haben mich zu dieser Schlussfolgerung geführt.
Bevor ich jedoch die Gründe aufzählen möchte, möchte ich zunächst betonen, dass ich isomorphe Javascript-Bibliotheken (dh lodash.js) sind genial. Ich denke auch, dass isolierte isomorphe Komponenten wertvoll sein können, zum Beispiel ein live aktualisierter Börsenindikator.
Die Gründe, warum ich nicht glaube, dass isomorphe Web-Apps für mich oder die Organisationen, für die ich arbeite, wertvoll sind, sind:
- Der Webserver kann jetzt nur noch in Javascript geschrieben werden
- Isomorphe Web-Apps können niemals progressiv sein Verbesserung für nicht-triviale Apps
- Blockierender vs nicht blockierender Datenfluss
- Time-to-Interaktion und das unheimliche Tal
- Mobile Geräte frieren beim Parsen von Javascript ein
- Ihre besten Entwickler sind jetzt damit beschäftigt, keinen Wert zu erzeugen
Ich möchte mit einer Definition von isomorphen Web-Apps beginnen. Eine isomorphe Web-App ist eine Web-App, bei der der Anwendungscode nicht weiß, wo er ausgeführt wird. Stattdessen wird dieses Wissen im Infrastrukturcode gespeichert und ermöglicht es der Anwendung als Ganzes, sowohl clientseitig als auch serverseitig ausgeführt zu werden.
- Der Webserver kann jetzt nur in Javascript geschrieben werden
- Isomorphe Web-Apps können niemals eine progressive Verbesserung für nicht-triviale Apps sein
- Blockierender vs. nicht blockierender Datenfluss
- Time-to-Interaction und das unheimliche Tal
- Mobile Geräte frieren beim Parsen von Javascript ein
- Ihre besten Entwickler sind jetzt damit beschäftigt, keinen Wert zu erzeugen
- Zusammenfassung
- Danksagung
Der Webserver kann jetzt nur in Javascript geschrieben werden
Wenn der Client-Code und der Server-Code identisch sind (und der Client heute nur Javascript interpretieren kann), sind wir darauf beschränkt, nur Javascript auf dem Server zu verwenden. Ich mag Knoten.js sehr, aber ich denke, es ist aus meiner Sicht besser, in Zukunft offen für Alternativen zu sein.
Isomorphe Web-Apps können niemals eine progressive Verbesserung für nicht-triviale Apps sein
Clientseitiges Javascript hat Zugriff auf eine In-Memory-Zustandsmaschine, die eine feinkörnige Interaktionsebene mit einer sehr geringen Latenz (unter Millisekunden) ermöglicht. Dasselbe gilt nicht für die HTTP-Zustandsmaschine, die durch Linkklicks und Formularübermittlungen gesteuert wird.
Für mich bedeutet Progressive Enhancement, mit einer Baseline zu beginnen, die für alle möglichen Geräte / Browser zugänglich ist, von alt über aktuell bis in die Zukunft. In der Praxis bedeutet dies eine Baseline des serverseitigen Renderns. Der Verbesserungsschritt ist eine Geschäftsentscheidung darüber, wo die Site / App verbessert werden soll, um den Wert zu steigern. Mit anderen Worten, die Verbesserung erfolgt im Anwendungscode (spezifisch) und * nicht * im Infrastrukturcode (allgemein), mit Ausnahme von Optimierungstechniken wie pjax oder Turbolinks.
Die Möglichkeit für isomorphe Web-Apps, eine progressive Verbesserung zu erhalten, besteht darin, diese feinkörnige In-Memory-Zustandsmaschine so zu „übersetzen“, dass nur Links und Formulare verwendet werden. Die einzigen Fälle, in denen dies möglich ist, sind Fälle, in denen Sie überhaupt kein vollständiges clientseitiges Rendering benötigten, sondern sich auf die oben genannten Optimierungstechniken und clientseitigen Komponenten verlassen konnten, um die Erfahrung zu verbessern (dh eine Kalenderkomponente für ein Eingabefeld für ein Datum).
Eine Variante dieser Lösung besteht darin, nicht jeden clientseitigen Status / Übergang in der serverseitigen Zustandsmaschine zu unterstützen. In diesem Fall sollte dies eine Geschäftsentscheidung sein, die sich im Anwendungscode widerspiegeln muss, wodurch die Anwendungscodeumgebung empfindlich wird, was der Idee isomorpher Web-Apps zuwiderläuft.
Die Möglichkeit für isomorphe Web-Apps, eine progressive Verbesserung zu erhalten, besteht darin, diese feinkörnige In-Memory-Zustandsmaschine so zu „übersetzen“, dass nur Links und Formulare verwendet werden.
Blockierender vs. nicht blockierender Datenfluss
Die Rendersequenz für serverseitiges Web und clientseitiges Web ist unterschiedlich: Die serverseitige blockiert und die clientseitige blockiert nicht.
Stellen Sie sich vor, wir müssen zwei Anforderungen an einige Dienste stellen, um eine Ansicht zu rendern. Wir können diese Anfragen parallel bearbeiten.
Wenn die zweite Anforderung auf der Serverseite zuerst zurückkehrt, kann sie diesen Teil der Antwort rendern, muss jedoch das Senden dieser Bytes blockieren, bis die erste Anforderung diesen Teil der Antwort gerendert und an den Browser zurückgegeben hat.
Auf der Clientseite ist diese Einschränkung nicht vorhanden: Die beiden Antworten können unabhängig voneinander behandelt und gerendert werden.
Ich denke auch, dass das obige das einfachste Beispiel darstellt. Stellen Sie sich vor, Sie haben einen Komponentenbaum, in dem die Stammkomponente intelligent ist (eine Erläuterung der intelligenten / dummen Komponenten finden Sie unter Präsentations- und Containerkomponenten), gefolgt von einigen Ebenen dummer Komponenten und mindestens einer Blattkomponente, die intelligent ist.
Die Infrastruktur benötigt dann eine Möglichkeit, um sicherzustellen, dass der Kontext des Smart Leaf nicht verloren geht, sodass wir die Kontrolle über die blockierende / nicht blockierende Ausführung verlieren, abhängig vom Server / Client-Modus. Eine Möglichkeit, dieses Problem zu lösen, könnte darin bestehen, das gesamte Programm in einer freien Monade auszuführen, die die Ausführung als später zu interpretierende Daten darstellt. Eine andere Lösung könnte darin bestehen, eine Art Besuchermuster zu verwenden und Komponenten deklarieren zu lassen, welche Daten sie benötigen (ähnlich dem Tutorial: Erstellen einer isomorphen Redux-Anwendung (mit Liebe) ). Letzteres ist wahrscheinlich am einfachsten. Mein Punkt ist, dass das Problem der verschiedenen Blockierungsmodi wahrscheinlich viel komplizierter ist, als man sich anfangs vorstellt.
Ein alternatives Design besteht darin, eine Regel zu haben, die besagt, dass „Nur die Wurzelkomponente eine intelligente Komponente sein kann“, ähnlich wie Sie die IO-Monade in Haskell verwenden, die Blätter rein halten und nur Nebenwirkungen auf der obersten Ebene haben. Ich denke, dieses Design ist auf der Serverseite gut, aber nicht auf der Clientseite: Eine Komponente auf der Clientseite sollte in der Lage sein, zumindest in einigen Szenarien ihre eigenen Daten zu laden, beispielsweise in Bezug auf Komponenten im Zusammenhang mit sozialen Medien. Eine Regel zu haben, die diese Szenarien niemals zulässt, scheint sehr unproduktiv zu sein.
Time-to-Interaction und das unheimliche Tal
Mit dem Isomorphic Web Apps-Ansatz wird es eine Zeitspanne geben, in der der Benutzer grafische Elemente auf dem Bildschirm sieht, die interaktiv erscheinen, aber nicht interaktiv sind. Mit anderen Worten, die Zeit zwischen dem Zeitpunkt, zu dem der Browser die Serverantwort gerendert hat, und dem Zeitpunkt, zu dem das Javascript heruntergeladen, analysiert und ausgeführt wird. Dies wird als „Unheimliches Tal“ oder „Potemkin-Dorf“ bezeichnet.
Weitere Informationen finden Sie in diesem Tweet und in den Antworten.
Mobile Geräte frieren beim Parsen von Javascript ein
Auf einem „typischen“ Mobiltelefon erhalten Sie laut diesem Tweet 1 ms UI-Thread-Stall pro 1 KB Javascript. Malte Ubl ist der technische Leiter des AMP-Projekts, daher vermute ich, dass er weiß, wovon er spricht.
Ihre besten Entwickler sind jetzt damit beschäftigt, keinen Wert zu erzeugen
Isomorphe Web-Apps sind ein Ansatz, der ein hohes Maß an Entwicklungskompetenz erfordert. In vielen Bereichen (zumindest in der westlichen Welt) ist es schwierig, hochqualifizierte Entwickler zu finden und zu rekrutieren. Die Entscheidung, isomorphe Web-Apps zu entwickeln, weist diesen Entwicklern zu, etwas zu tun, von dem ich in Frage stelle, dass es überhaupt einen geschäftlichen Wert erzeugt. Es gibt bessere Möglichkeiten, ihre Zeit zu nutzen.
Zusammenfassung
Isomorphe Web-Apps beschränken die Auswahl der Sprache / Plattform Ihres Webservers auf nur Javascript. Es hat den Ehrgeiz, progressive Verbesserungen zu ermöglichen, aber es kann nicht liefern. Es führt aufgrund der Unterschiede im blockierenden / nicht blockierenden Datenfluss zu einem hohen Maß an technischer Komplexität. Es führt ein Zeitfenster ein, in dem die Dinge interaktiv zu sein scheinen, aber nicht (das unheimliche Tal). Eine hohe Menge an Javascript friert auch mobile Browser ein, mit der Faustregel, dass 1 KB Javascript 1 ms blockierten UI-Thread bedeutet. Und da es ein kompliziertes Softwaredesign erfordert, kostet es wertvolle Zeit und Mühe von Ihren besten Entwicklern – es gibt bessere Möglichkeiten, ihre Zeit zu nutzen.
Schließlich möchte ich betonen, dass Ihre Erfahrungen von meinen abweichen können. Vielleicht gibt es Szenarien, in denen isomorphe Web-Apps gut sind. Sie sind jedoch kein Allheilmittel, um jede Lücke zwischen serverseitigen Webvorteilen und clientseitigen Webvorteilen zu schließen und gleichzeitig keine der Nachteile beider Ansätze zu erzielen.
Was denkst du? Haben Sie überlegt, „isomorph zu werden“? Haben Sie Gedanken zu den Herausforderungen und Kosten? Wie gehen Sie damit um?
Danksagung
Vielen Dank an Oskar Wickström und Per Ökvist für wertvolle Diskussionen zu diesem Thema. Oskar hat auch diesen Beitrag überprüft – danke Oskar.