RxJS’s Vor- und Nachteile: Fluch oder Segen?

Warum RxJS als Kernbibliothek für die reaktive Programmierung in JavaScript weiter an Einfluss gewinnt und welche Schwächen zu beachten sind.

RxJS (Reactive Extensions for JavaScript) ist die grundlegende Bibliothek für funktionale reaktive Programmierung (FRP) für eine große Anzahl beliebter JavaScript-Frameworks wie Angular, React und NestJS. Sie bietet eine ganze Reihe praktischer Operatoren, die Sie nutzen können, um Ihren Code effizienter, schneller und bissiger zu machen! Aber lassen Sie uns einen genaueren Blick darauf werfen, was RxJS zu einer so guten Wahl für Ihren Tech-Stack in der Webentwicklung macht, und tiefer graben, um zu definieren, was die Bibliothek von der Masse abhebt!

RxJS ist eine der wichtigsten Bibliotheken, die jeder moderne JavaScript-Entwickler in seinem Baukasten haben sollte. Es ist eine Bibliothek, die Entwicklern hilft, den Prozess der Komposition von Callback-basiertem oder asynchronem Code zu vereinfachen. Gleichzeitig hat sie das Potenzial, Ihre Anwendungen noch leistungsfähiger und effizienter zu machen, da sie über eine Vielzahl effektiver Operatoren verfügt. Wenn man all dies bedenkt, kann man mit gutem Gewissen sagen, dass RxJS die De-facto-Basis für jede reaktive Anwendung ist.

Beliebte Frameworks wie Angular und NestJS nutzen aktiv das Konzept der reaktiven Programmierung, was erklärt, warum RxJS eine so beliebte Bibliothek bei JavaScript-Architekten ist. Heute gehört RxJS zu den angesagtesten Bibliotheken in der Welt der Webentwicklung. Es handelt sich um ein funktionelles und leistungsstarkes Werkzeug, das in eine Vielzahl von Frameworks integriert ist. Kurz gesagt, RxJS macht reaktive Programmierung attraktiver und zugänglicher.

Seit seiner Vorstellung durch Microsoft, das es vor fast einem Jahrzehnt als Open-Source-Projekt freigegeben hat, hat sich RxJS rasch weiterentwickelt. Selbst jetzt gewinnt es noch an Dynamik. Hier sind einige Zahlen, die seine große Beliebtheit deutlich machen:

RxJS-Statistiken

  • Zum Zeitpunkt der Erstellung dieses Artikels hat die RxJS-Bibliothek über 6 Millionen (!) Repositories auf GitHub;
  • Mehr als 26.000 Pakete bei NPM;
  • Fast 27,5 Millionen wöchentliche Downloads von NPM!

RxJS-Profis: Warum diese Bibliothek so genial ist!

Die Anzahl der Repositories, NPM-Pakete und wöchentlichen Downloads von RxJS ist beeindruckend. Ist sie jedoch immer die beste Wahl? Werfen wir einen genaueren Blick auf die wichtigsten Vor- und Nachteile dieser Bibliothek, um herauszufinden, was RxJS so attraktiv macht!

RxJS ist gut etabliert, stabil und profitiert von einer aktiven Open-Source-Community

Der enorme Erfolg von RxJS, den wir heute beobachten können, ist zweifellos das Ergebnis jahrelanger harter Arbeit, Hingabe und tausendfacher Verbesserungen und Korrekturen, die von der großen, aktiven Open-Source-Gemeinschaft (OS) vorgenommen wurden. Laut GitHub erschien die erste Version des aktuellen Repositorys im Jahr 2015.

Datum der ersten Veröffentlichung von RxJS auf Github (im neuen Repository)

Die Entwicklung von RxJS begann sogar noch früher – im Jahr 2013. In der Welt der Webentwicklung und von JavaScript macht das RxJS zu einer ziemlich ausgereiften OS-Bibliothek (Open Source Bibliothek).


Datum der ersten Veröffentlichung von RxJS auf GitHub (im alten Repository)

Im Laufe der langen Geschichte des Projekts wurden fast 7000 Beiträge von rund 600 Entwicklern geleistet. Das ist ein gewaltiger Fortschritt!

Hochwertige API

Dank seiner anmutigen API macht es RxJS einfach, einen komplexen Datenstrom kompakter zu beschreiben. Zu diesem Zweck verfügt es über ein umfassendes Paket von Standard-Entities (Subjects, Observables und Operatoren), die die gesamte Schwerarbeit übernehmen. Die Komplexität des Prozesses bleibt für den Entwickler relativ verborgen, so dass er sich mehr auf die Logik der zu entwickelnden Anwendung konzentrieren kann.

Die Rolle von RxJS in der React.js Entwicklung

Was bedeutet das für React-Entwickler? Mit ein wenig Erfahrung ist es möglich, den Workflow mit asynchronen Datenflüssen erheblich zu vereinfachen. Zum Beispiel mit UI-Events, HTTP-Anfragen oder WebSocket-Messaging. Dies ermöglicht es Entwicklern, Zeit und Mühe für andere Aufgaben einzusparen.

RxJS-Verwendungsbeispiel:

Die API-Stabilität von RxJS ist besonders erwähnenswert – sie ist erstklassig! JavaScript-Entwickler, die RxJS verwenden, können die Abwärtskompatibilität länger aufrechterhalten, was den Benutzern zusätzliche Zeit gibt, von veralteten APIs auf die neuesten umzusteigen. Darüber hinaus stellt RxJS seiner Nutzergemeinschaft Tools und Anleitungen für die halbautomatische Migration auf jede neue Hauptversion zur Verfügung.

Starke Optimierung und Schutz vor Speicherlecks.

Die Ausgereiftheit von RxJS und die aktive OS-Community bedeuten, dass die Entwickler auf die Qualität der Optimierung vertrauen können. Im Laufe der Zeit und dank der Beiträge der RxJS-Community wurden viele subtile Probleme mit der RxJS-Bibliothek gelöst. Insbesondere wurden Probleme im Zusammenhang mit Speicherlecks erkannt und richtig behandelt.

RxJS-Statistiken zu Speicherlecks

Erweitbarkeit

Trotz eines umfangreichen Satzes von Standardoperatoren kann es gelegentlich notwendig sein, sich wiederholende Algorithmen in neue RxJS-Operatoren umzuwandeln. Dies kann leicht erreicht werden, indem man der offiziellen Referenzdokumentation folgt. YouTube-Tutorials erklären es auch gut, zum Beispiel dieses Video:

Minimaler Fußabdruck

RxJS ist bekannt für seine hochwertige Optimierung und modulare Architektur. Beide Merkmale sorgen auch für einen geringeren Platzbedarf, was bedeutet, dass das Produktionspaket nur die Teile enthält, die wirklich verwendet werden.

Keine Abhängigkeit von Dritten

RxJS ist eine eigenständige Bibliothek, die im Gegensatz zu vielen anderen Bibliotheken kaum von Drittanbieter-Abhängigkeiten abhängig ist. Daher ist ihr Einfluss auf die Größe eines Projekts optimal und hängt davon ab, wie viel von ihr tatsächlich genutzt wird.


RxJS-Abhängigkeiten

Laut NPM hat RxJS derzeit nur eine Abhängigkeit – tslib, die Typescript-Unterstützung bietet.

Ein weiterer Vorteil, der durch das Fehlen von Abhängigkeiten gewährleistet wird, besteht darin, dass es relativ einfach ist, RxJS selbst als dependency (Abhängigkeit) für andere Pakete zu übernehmen. Zum Beispiel API-SDKs, Hilfspakete, serverseitige Programme, Webhook-Implementierungen und auch Front-End-Event-Manager.

Große, aktive Community

Eine der größten Stärken der RxJS-Bibliothek ist ihre große und vielfältige Community. Dank einer so reaktionsfreudigen Community wird RxJS immer besser und beliebter. Die Teilnehmer der Community helfen sich gegenseitig bei der Bewältigung von Problemen und Fragen zu allen möglichen RxJS-Themen auf StackOverflow und Gitter.

Dokumentation

Obwohl reaktive Programmierung und RxJS im Allgemeinen schwer zu beherrschen sind, wird die Überwindung dieser hohen Lernkurve durch die umfangreiche Dokumentation der Bibliothek erleichtert.  Auf der offiziellen Webseite von RxJS finden Sie eine Vielzahl offizieller Dokumentationen sowie von der Community bereitgestellte Ressourcen, die Konzepte, Best Practices, Muster und Beispiele näher erläutern und den Nutzern helfen, ihr theoretisches Wissen und ihre praktischen Fähigkeiten zu verbessern.

Regelmäßige Updates und RxJS v.8.0

Der letzte, aber ganz sicher nicht der letzte große Vorteil dieser Bibliothek ist, dass sie gut gepflegt wird. Es werden regelmäßig Updates auf GitHub veröffentlicht, was sie zu einer sehr zuverlässigen Code-Basis macht. Die neueste Version 7.4.0 wurde am 6. Oktober 2021 veröffentlicht. Wir befinden uns derzeit auf der Roadmap für Version 8, in der die Verwerfungen entfernt werden, bei denen das Team ESLint-Code-Transformationen hinzufügen konnte. Das wird die Ersetzung veralteter APIs weiter vereinfachen. Es wird auch erwartet, dass die Größe der Pakete verringert wird, in einigen Fällen sogar um 40 % der derzeitigen Größe, und dass die Bemühungen, mit den neuesten Versionen von Typescript und JavaScript Schritt zu halten, fortgesetzt werden.

Noch wichtiger als die Konsistenz der Aktualisierungen ist, dass jede neue Version eine allgemeine Verbesserung von RxJS mit sich bringt, die es noch leistungsfähiger, performanter, zuverlässiger und bequemer macht.

RxJS Nachteile: Zu beachtende Schwachstellen

Während RxJS zweifelsohne viele Stärken hat, gibt es auch einige Nachteile, die im Auge behalten werden müssen:

Daten müssen unveränderlich sein

Jeder Entwickler, der mit RxJS arbeitet, sollte sich darüber im Klaren sein, dass die Unveränderlichkeit der Daten (data immutability) in der Bibliothek weniger eine Anforderung als vielmehr ein integraler Bestandteil der funktionalen Programmierung ist.

Die reaktive Programmierung birgt selbst viele Fallstricke, und wenn dieses Paradigma auf JavaScript angewandt wird, können durch die Spracheigenschaften verursachte Probleme auftauchen. Insbesondere der Mangel an nativer Unterstützung für die Unveränderlichkeit von Daten in JavaScript kann einen Entwickler dazu zwingen, auf Bibliotheken und Workarounds von Drittanbietern zurückzugreifen, was schwierig und ineffizient sein kann.

Das reaktive Paradigma funktioniert am besten in Kombination mit funktionaler Programmierung. Diese Symbiose ist weder neu noch selten in der Welt der Programmierung und wird „funktionale reaktive Programmierung“ (oder kurz FRP) genannt. Sie bietet erhebliche Vorteile wie die einfache Erstellung von Multithreading-Anwendungen und die effektive Nutzung von Rechenressourcen. Aber wie alle Paradigmen ist auch dieses keine „Wunderwaffe“.

Moderne Anwendungen, die auf der Symbiose von objektorientierter, funktionaler und reaktiver Programmierung basieren, picken sich so oder so die besten Aspekte aller Paradigmen heraus.

Komplexität der Prüfung

Es ist erwähnenswert, dass die spezifischen Merkmale der reaktiven Programmierung bedeuten, dass ein Entwickler eine Reihe zusätzlicher Tools und Techniken beherrschen muss, um RxJS-Code zu testen.

Da wir es hier mit asynchronem Code zu tun haben, führt kein Weg am Testen vorbei, ohne zusätzliche Tools zu verwenden. Glücklicherweise hat das RxJS-Team eine eigene Lösung entwickelt –Marble diagrams. Das Hauptziel dieses Tools ist es, gut integrierte Datenströme zu ermöglichen. Leider macht die Notwendigkeit, zusätzliche Tools zu verwenden, den Prozess der Texterstellung etwas komplizierter. Die Syntax von Marble diagrams kann knifflig sein, was bedeutet, dass Entwickler, die sich noch mit RxJS vertraut machen müssen, hier eine zusätzliche Lernkurve haben.


Anatomie eines Marble diagram (Quelle)

Strenge Typisierungsprobleme

Wie bereits erwähnt, ist die einzige Abhängigkeit von RxJS die tslib, die Ihnen die Unterstützung von Typescript bietet. Typescript bringt definitiv eine Reihe von Vorteilen mit sich, wie z. B. starke Typisierung, automatische Vervollständigung usw. Allerdings kann es vorkommen, dass Benutzer die falsche Verwendung von Zugriffsmodifikatoren (private/public) feststellen, wodurch interne Methoden von außen zugänglich werden.

Hier ist ein klares Beispiel für dieses Problem, das auf der tatsächlichen Implementierung basiert (die Methode wird normalerweise mit einem privaten oder geschützten Modifikator versteckt):

export class Observable<T> { ... /** @internal This is an internal implementation detail, do not use. */ _subscribe(subscriber: Subscriber<any>): TeardownLogic { const { source } = this; return source && source.subscribe(subscriber); } ... }

Ideal wäre es, wenn der Zugang zu sensiblen Details der internen Implementierung in RxJS beobachtbar wäre, insbesondere in Klassen, die Teil einer öffentlichen API sind. Dies ist jedoch nicht immer der Fall, was einen erheblichen Nachteil darstellt.

Operatornamen können mit anderen importierten Funktionen in Konflikt geraten

Die Kompaktheit des RxJS-Codes ist eine bedeutende Designleistung. Es gibt jedoch noch ein weiteres Problem, das einige der damit verbundenen Vorteile zunichte macht. Im Code können kurze Namen von Operatoren (wie map, filter, reduce) mit anderen Funktionsnamen aus anderen Paketen, z. B. lodash, in Konflikt geraten. Hier ist ein kleines Beispiel:

import { filter, map } from 'rxjs/operators';
import { filter } from 'lodash'; // Error. Duplicate imports.

Of course, such conflicts, though not ideal, can be solved with aliases for imported methods. But doing so is an inconvenience, which makes it a weakness of the library.

import { filter, map } from 'rxjs/operators';
import { filter as _filter } from 'lodash'; // Ok, imports have different names

Long stack traces

Während des Debugging-Prozesses kann ein Entwickler mit der Notwendigkeit konfrontiert werden, den Stack-Trace von RxJS zu untersuchen, der aufgrund seiner Größe entmutigend wirken kann. Das wirft die Frage auf, warum es so komplex ist!?

RxJS basiert auf FP-Prinzipien wie funktionale Komposition, partielle Ausführung und Delegation. Hinzu kommt die Tatsache, dass Daten durch den Stream geleitet und von Operatoren verarbeitet werden, die einige Aufgaben an bestimmte Funktionen delegieren. Der RxJS-Stream ist ein komplexes zusammengesetztes System, das zu besonders langen Stack Traces führt.

Obwohl besonders lange Stack Traces überwältigend oder zumindest lästig sein können, ist die gute Nachricht, dass sich dies mit RxJS 8.0 wahrscheinlich ändern wird. Das Entwicklerteam von RxJS hört auf die Community und ergreift, wenn möglich, Maßnahmen, um häufige Beschwerden zu beheben oder zu verbessern.

Fazit

Die Rolle des reaktiven RxJS-Konzepts im JavaScript-Ökosystem war ziemlich vorhersehbar, wenn man die obigen Ausführungen zu Ende denkt. Die Notwendigkeit der Bibliothek basiert auf der Reife von FRP als Paradigma und der Tatsache, dass es gut mit JavaScript-Funktionen funktioniert. Seit ihrer Veröffentlichung im Jahr 2015 hat RxJS an Dynamik gewonnen und andere beliebte Bibliotheken und Frameworks wie Angular und NestJS mitgeprägt.

Das von RxJS angebotene Modell für den Betrieb der Datenströme erwies sich als erfolgreich und sehr gefragt. Dies ermutigte die Gemeinschaft zu der Forderung, diese Funktionalität in den ECMAScript-Standard zu implementieren. Diese Entscheidung hat zu einem großen Schritt in der Entwicklung der RxJS-Bibliothek geführt und spiegelt die Entwicklung von Promise wider, als es dem Standard hinzugefügt wurde.

Ist RxJS also ein heiliger Gral oder ein Ärgernis für einen Webentwickler? Unsere endgültige Meinung ist, dass diese Bibliothek eine sehr solide Lösung für eine komfortablere reaktive Programmierung ist. Es lohnt sich auf jeden Fall, sie zu erlernen und zu implementieren. Und da die Zukunft eine zunehmende Verwendung von RxJS in der JavaScript-Entwicklung verspricht, wird sie zu einem immer wichtigeren Teil des Tech-Stacks eines Webentwicklers!

Wenn Sie Ihre Entwicklungsbedürfnisse oder ein bevorstehendes Projekt mit uns besprechen möchten, nehmen Sie bitte Kontakt mit uns auf!

Ausgewählte Blogbeiträge