Webseiten mit Blazor Server (Teil 2)

Webseiten mit Blazor Server (Teil 2)

Nachdem ich im ersten Teil dieses Beitrags zu den Ladezeiten, zur Komplexität sowie zur Performance von Blazor-Anwendungen eingegangen bin, möchte ich hier nun die Fragen zum Ressourcenverbrauch, zur Skalierung und zum Einsatz von JavaScript in Blazor-Anwendungen beantworten.

Zurück zu Webseiten mit Blazor Server (Teil 1)

Benötigt Blazor Server nicht zu viele Ressourcen?

Blazor Server ist ein zustandsorientiertes App-Framework, in welchem die Verbindung vom Client zum Server aufrecht gehalten werden muss. Der aktuelle Zustand der App wird während der gesamten Lebensdauer der Verbindung im Speicher des Servers, in einem sogenannten "Curcuit", gehalten. Für eine einfache "Hello world!" App werden für jeden Curcuit ca. 250 kB Speicher benötigt. Bei 5000 gleichzeitig verbundenen Anwendern sollte man somit ca. 1,5 GB Speicher für die App bereitstellen. Für komplexere Webseiten wird entsprechend mehr Arbeitsspeicher benötigt.

Während der Entwicklung einer Webseite werden oftmals Dependency Injection Frameworks (z.B. Inversion of Control Container) eingesetzt. Dependency Injection Frameworks verwalten die Abhängigkeiten zwischen den einzelnen Komponenten einer Anwendung, so dass diese auch bei wachsender Größe und Komplexität einfach zu ändern ist. Die Komponenten werden dabei in verschiedenen Scopes erzeugt. Dies kann beispielsweise der Anwendungs-Scope sein, in dem eine Komponente solange existiert, wie die Anwendung lauft (Singleton) und die von in allen Anfragen an den Server verwendet wird. In klassischen Webseiten werden viele Komponenten während einer Anfrage an den Server erstellt. Nach dem Bearbeiten der Anfrage werden diese Komponenten wieder destruiert und somit der benötigte Arbeitsspeicher freigegeben. In Blazor Server-Anwendungen existieren diese Komponenten jedoch solange, wie eine Verbindung zum Client besteht. Der für die Komponenten benötigte Arbeitsspeicher wird somit also auch über die Abarbeitung einer Abfrage hinaus belegt. Ggf. müssen hier andere Entwicklungsmuster wie z.B. das Service Locator Pattern angewendet werden.

Im Vergleich zu zustandslosen Web-Apps benötigt Blazor tatsächlich wesentlich mehr Arbeitsspeicher. Wieviel Speicher ein Curcuit aber tatsächlich benötigt und wie viele aktive Curcuits eine App gleichzeitg verwalten kann, hängt weitgehend davon ab, wie die App geschrieben ist. Bereits im Vorfeld der Entwicklung einer Blazor Server Anwendung sollten Sie sich daher Gedanken dazu machen, wie viele Anwender voraussichtlich gleichzeitig auf die App zugreifen und welche Ressourcen zur Verfügung stehen. Bei einer sogfältigen Planung gibt es dann keine bösen Überraschungen.

Blazor Server und Load-Balancing: Funktioniert das?

Zum Aufbau einer WebSocket-Verbindung zwischen Client und Server werden in der Initialisierungsphase zunächst mehrere HTTP-Anfragen vom Client an den Server gesendet. SignalR erfordert dabei, dass sämtliche HTTP-Anfragen für diese Verbindung von demselben Serverprozess bearbeitet werden. In einer Server-Farm (mehrere Server) kommen Load-Balancer zum Einsatz, welche sicherstellen sollen, dass alle Anfragen gleichmäßig auf alle Server verteilt werden. Eine Weiterleitung der HTTP-Anfragen an den selben Prozess kann so jedoch nicht gewährleitet werden. Um sicherzustellen, dass dennoch alle zum Aufbau der SignalR-Verbindung erforderlichen HTTP-Anfragen vom selben Server-Prozess bearbeitet werden, muss Session Persistance verwendet werden. Sessions Persistance wird auch als "Sticky Sessions" oder "Session Affinity" bezeichnet. Der Azure App Service verwendet Application Request Routing (ARR), um Anfragen weiterzuleiten. Wenn Sie die Einstellung "ARR Affinity" in Ihrem Azure App Service auswählen, werden "sticky sessions" aktiviert. Ein weiteres Problem ist das Senden von Nachrichten an die Clients. Jeder Server in einer Server-Farm kennt nur die mit ihm verbundenen Clients. Das Senden von Nachrichten an alle Clients ist somit nicht möglich. Hier schafft die Redis-Backplane Abhilfe: Möchte ein Server eine Nachricht an alle Clients versenden, sendet er die Nachricht zunächst an den Redis-Server. Dieser leitet die Nachricht dann an alle Server der Server-Farm weiter, so dass diese dann die Nachricht jeweils an alle mit ihnen verbundenen Clients senden können.

Microsoft empfiehlt den Einsatz des Azure SignalR Service, welcher den ASP.NET Core eigenen SignalR Service ersetzt. Bei der Verwendung des Azure SignalR Service sind "Sticky Sessions" nicht erforderlich, da die Clients beim Verbindungsaufbau sofort an den Service weitergeleitet werden und dieser die Anfragen an den jeweils richtigen Server weiterleitet. Da dem Azure SignalR Service sämtliche verbundenen Clients bekannt sind, dient er gleichzeitig als Backplane. Möchte ein Server eine Nachricht an alle Clients senden, übergibt er diese an den SignalR Service. Dieser leitet dann die Nachricht dann an die verbundenen Clients weiter.

Sehr empfehlenswert zum Thema Skalierung ist das Video Deploying and Scaling Blazor Server Apps: Carl Franklin's Blazor Train.

Ersetzt Blazor JavaScript?

Blazor Anwendungen können tatsächlich ohne die Zuhilfenahme von JavaScript erstellt werden, man sollte jedoch daren denken, dass Blazor selbst, sowie auch zahlreiche Bibliotheken JavaScript verwenden. Die Unterstützung von JavaSkript ist somit Client-seitig immer erforderlich. Kompliziertes JavaScript zur Anpassung der Oberfläche, wie es bei SPAs auf JavaScript-Basis erforderlich ist, wird nicht benötigt. Dennoch sollten Entwickler in der Lage sein, Teile einer Anwendung auch in JavaScript zu implementieren. Blazor bietet eine hervorragende Interoperabilität mit Javascript. So kann eine Blazor-Anwendung Javascript-Funktionen aus .NET-Methoden und .NET-Methoden aus Javascript-Funktionen heraus aufrufen.

JavaScript hat derzeit im Vergleich zu Blazor eine weitaus größere Community. Für viele Probleme gibt es bereits fertige frei verfügbare Lösungen, welche für Blazor Anwendungen erst entwickelt werden müssen. Entwicker sollten immer die für den Kunden optimale Lösung einsetzen um so die Anwendung schnell und effizient zu erstellen.

Fazit

Blazor ist eine ausgereifte Technologie und eine hervorragende und leistungsstarke Alternative zu JavaScript-basierten Anwendungen. Sowohl bei den Ladezeiten als auch bei der Performance können Blazer Server Anwendungen mühelos mit JavaScript basierten Single Page Apps mithalten. Auch die Skalierung und das Load-Balancing sind dank des Azure SignalR Services kein nennenswertes Thema. Lediglich der erhöhte Resourcenverbrauch schlägt etwas negativ zu Buche.
Blazor ist für nahezu alle Einsatzgebiete geeignet, zeigt aber seine wahren Stärken besonders dann, wenn Server-Client Kommunikation mit Echtzeit-Funktionalität gefordert ist. Dies sind z.B. Anwendungen im Business- und IoT-Bereich, bei denen Sales- oder Messdaten in Echtzeit dargestellt werden sollen. Aber auch bei Social Media Apps, Chats und nachrichtenbasierte Diensten ist Blazor uneingeschränkt zu empfehlen.

An error has occurred. This application may no longer respond until reloaded. An unhandled exception has occurred. See browser dev tools for details. Reload 🗙