Clientseitig vs. Serverseitig vs. Pre-Rendering für Web-Apps

Veröffentlicht: 2022-03-11

In letzter Zeit tut sich etwas in der Front-End-Community. Serverseitiges Rendering gewinnt dank React und seiner integrierten serverseitigen Hydration-Funktion immer mehr an Zugkraft. Aber es ist nicht die einzige Lösung, um dem Benutzer ein schnelles Erlebnis mit einem superschnellen Time-to-First-Byte (TTFB)-Score zu bieten: Pre-Rendering ist auch eine ziemlich gute Strategie. Was ist der Unterschied zwischen diesen Lösungen und einer vollständig vom Client gerenderten Anwendung?

Client-gerenderte Anwendung

Seit es Frameworks wie Angular, Ember.js und Backbone gibt, neigen Frontend-Entwickler dazu, alles clientseitig zu rendern. Dank Google und seiner Fähigkeit, JavaScript zu „lesen“, funktioniert es ziemlich gut und ist sogar SEO-freundlich.

Bei einer clientseitigen Rendering-Lösung leiten Sie die Anfrage an eine einzelne HTML-Datei weiter und der Server liefert sie ohne Inhalt (oder mit einem Ladebildschirm), bis Sie das gesamte JavaScript abrufen und den Browser alles kompilieren lassen, bevor der Inhalt gerendert wird.

Unter einer guten und zuverlässigen Internetverbindung ist es ziemlich schnell und funktioniert gut. Aber es kann viel besser sein, und es muss nicht schwierig sein, es so zu machen. Das werden wir in den folgenden Abschnitten sehen.

Serverseitiges Rendern (SSR)

Eine SSR-Lösung ist etwas, was wir vor vielen Jahren oft gemacht haben, aber zugunsten einer clientseitigen Rendering-Lösung vergessen haben.

Bei alten serverseitigen Rendering-Lösungen haben Sie eine Webseite erstellt – beispielsweise mit PHP –, der Server hat alles kompiliert, die Daten eingefügt und eine vollständig ausgefüllte HTML-Seite an den Client geliefert. Es war schnell und effektiv.

Aber … jedes Mal, wenn Sie zu einer anderen Route navigierten, musste der Server die Arbeit von vorne erledigen: Holen Sie sich die PHP-Datei, kompilieren Sie sie und liefern Sie den HTML-Code, wobei all das CSS und JS das Laden der Seite um einige hundert ms verzögerten oder sogar ganze Sekunden.

Was wäre, wenn Sie das Laden der ersten Seite mit der SSR-Lösung durchführen und dann ein Framework verwenden könnten, um dynamisches Routing mit AJAX durchzuführen und nur die erforderlichen Daten abzurufen?

Aus diesem Grund gewinnt SSR innerhalb der Community immer mehr an Bedeutung, da React dieses Problem mit einer einfach zu verwendenden Lösung populär gemacht hat: Die RenderToString -Methode.

Diese neue Art von Webanwendung wird als universelle App oder isomorphe App bezeichnet. Es gibt immer noch einige Kontroversen über die genaue Bedeutung dieser Begriffe und die Beziehung zwischen ihnen, aber viele Leute verwenden sie synonym.

Wie auch immer, der Vorteil dieser Lösung besteht darin, eine App serverseitig und clientseitig mit demselben Code zu entwickeln und dem Benutzer mit benutzerdefinierten Daten ein wirklich schnelles Erlebnis zu bieten. Der Nachteil ist, dass Sie einen Server betreiben müssen.

SSR wird verwendet, um Daten abzurufen und eine Seite vorab mit benutzerdefinierten Inhalten zu füllen, wobei die zuverlässige Internetverbindung des Servers genutzt wird. Das heißt, die eigene Internetverbindung des Servers ist besser als die eines Benutzers mit lie-fi), sodass er Daten vorab abrufen und zusammenführen kann, bevor er sie an den Benutzer liefert.

Mit den vorab ausgefüllten Daten kann die Verwendung einer SSR-App auch ein Problem beheben, das von Clients gerenderte Apps mit Social Sharing und dem OpenGraph-System haben. Wenn Sie beispielsweise nur eine index.html -Datei an den Client liefern müssen, wird dieser nur eine Art von Metadaten haben – höchstwahrscheinlich Ihre Homepage-Metadaten. Dies wird nicht kontextualisiert, wenn Sie eine andere Route teilen möchten, sodass keine Ihrer Routen auf anderen Websites mit ihrem richtigen Benutzerinhalt (Beschreibung und Vorschaubild) angezeigt wird, die Benutzer mit der Welt teilen möchten.

Vorab-Rendering

Der obligatorische Server für eine universelle App kann für einige abschreckend und für eine kleine Anwendung übertrieben sein. Aus diesem Grund kann Pre-Rendering eine wirklich gute Alternative sein.

Ich habe diese Lösung mit Preact und seiner eigenen CLI entdeckt, mit der Sie alle vorab ausgewählten Routen kompilieren können, damit Sie eine vollständig ausgefüllte HTML-Datei auf einem statischen Server speichern können. Auf diese Weise können Sie dem Benutzer dank der Preact/React-Hydratationsfunktion ein superschnelles Erlebnis bieten, ohne dass Node.js erforderlich ist.

Der Haken ist, dass Sie an dieser Stelle keine benutzerspezifischen Daten anzeigen müssen, da dies kein SSR ist – es ist nur eine statische (und etwas generische) Datei, die direkt bei der ersten Anfrage gesendet wird, so wie sie ist. Wenn Sie also benutzerspezifische Daten haben, können Sie hier ein schön gestaltetes Skelett integrieren, um dem Benutzer zu zeigen, dass seine Daten kommen, um Frust seinerseits zu vermeiden:

Verwenden eines Dokumentskeletts als Teil eines Ladeindikators

Es gibt noch einen weiteren Haken: Damit diese Technik funktioniert, benötigen Sie immer noch einen Proxy oder etwas, um den Benutzer auf die richtige Datei umzuleiten.

Warum?

Bei einer Single-Page-Anwendung müssen Sie alle Anforderungen an die Stammdatei umleiten, und dann leitet das Framework den Benutzer mit seinem integrierten Routing-System um. Das Laden der ersten Seite ist also immer dieselbe Root-Datei.

Damit eine Pre-Rendering-Lösung funktioniert, müssen Sie Ihrem Proxy mitteilen, dass einige Routen bestimmte Dateien benötigen und nicht immer die index.html .

Angenommen, Sie haben vier Routen ( / , /about , /jobs und blog ) und alle haben unterschiedliche Layouts. Sie benötigen vier verschiedene HTML-Dateien, um das Skelett an den Benutzer zu liefern, der dann React/Preact/etc. rehydrieren Sie es mit Daten. Wenn Sie also all diese Routen auf die Root-Datei index.html umleiten, wird die Seite beim Laden ein unangenehmes, fehlerhaftes Gefühl haben, wodurch der Benutzer das Skelett der falschen Seite sieht, bis das Laden abgeschlossen ist und das Layout ersetzt wird. Beispielsweise könnte der Benutzer ein Homepage-Skelett mit nur einer Spalte sehen, wenn er nach einer anderen Seite mit einer Pinterest-ähnlichen Galerie gefragt hat.

Die Lösung besteht darin, Ihrem Proxy mitzuteilen, dass jede dieser vier Routen eine bestimmte Datei benötigt:

  • https://my-website.com → Weiterleitung zur Root-Datei index.html
  • https://my-website.com/about → Weiterleitung zur Datei /about/index.html
  • https://my-website.com/jobs → Weiterleitung zur Datei /jobs/index.html
  • https://my-website.com/blog → Weiterleitung zur Datei /blog/index.html

Aus diesem Grund kann diese Lösung für kleine Anwendungen nützlich sein – Sie können sehen, wie schmerzhaft es wäre, wenn Sie ein paar hundert Seiten hätten.

Genau genommen ist dies nicht zwingend erforderlich – Sie könnten einfach eine statische Datei direkt verwenden. Beispielsweise funktioniert https://my-website.com/about/ ohne Umleitung, da es automatisch nach einer index.html in seinem Verzeichnis sucht. Aber Sie brauchen diesen Proxy, wenn Sie Parameter-URLs haben – https://my-website.com/profile/guillaume muss die Anfrage an /profile/index.html mit einem eigenen Layout umleiten, weil profile/guillaume/index.html existiert nicht und löst einen 404-Fehler aus.

Ein Flussdiagramm, das zeigt, wie ein Proxy in einer Pre-Rendering-Lösung einen Unterschied macht, wie im vorherigen Absatz beschrieben


Kurz gesagt, bei den oben beschriebenen Rendering-Strategien spielen drei grundlegende Ansichten eine Rolle: Ein Ladebildschirm, ein Skelett und die vollständige Seite, sobald sie endgültig gerendert ist.

Vergleich eines Ladebildschirms, eines Skeletts und einer vollständig gerenderten Seite

Abhängig von der Strategie verwenden wir manchmal alle drei dieser Ansichten, und manchmal springen wir direkt zu einer vollständig gerenderten Seite. Nur in einem Anwendungsfall sind wir gezwungen, einen anderen Ansatz zu verwenden:

Methode Landung (zB / ) Statisch (zB /about ) Fixed Dynamic (z. B. /news ) Parametrisierte Dynamische (z. B. /users/:user-id )
Client-gerendert Laden → Voll Laden → Voll Laden → Skelett → Voll Laden → Skelett → Voll
Vor gerendert Voll Voll Skelett → Voll HTTP 404 (Seite nicht gefunden)
Vorgerendert mit Proxy Voll Voll Skelett → Voll Skelett → Voll
SSR Voll Voll Voll Voll

Client-only-Rendering ist oft nicht genug

Vom Client gerenderte Anwendungen sollten wir jetzt vermeiden, weil wir es für den Benutzer besser machen können. Und es besser zu machen, ist in diesem Fall so einfach wie die Pre-Rendering-Lösung. Es ist definitiv eine Verbesserung gegenüber dem reinen Client-Rendering und einfacher zu implementieren als eine vollständig serverseitig gerenderte Anwendung.

Eine SSR/universelle Anwendung kann wirklich leistungsfähig sein, wenn Sie eine große Anwendung mit vielen verschiedenen Seiten haben. Es ermöglicht, dass Ihre Inhalte fokussiert und relevant sind, wenn Sie mit einem sozialen Crawler sprechen. Dies gilt auch für Suchmaschinen-Roboter, die jetzt die Leistung Ihrer Website beim Ranking berücksichtigen.

Bleiben Sie dran für ein Folge-Tutorial, in dem ich die Umwandlung einer SPA in vorgerenderte und SSR-Versionen durchführe und ihre Leistung vergleiche.

Siehe auch: Überblick über beliebte Static-Site-Generatoren