FreshRSS

🔒
✇ Technology Review Blog

Neu in .NET 8.0 [10]: Plattformneutrale Abfrage der Privilegien

Von heise online — 16. Februar 2024 um 12:42
In der Klasse System.Environment hat Microsoft in .NET 8.0 die Eigenschaft IsPrivilegedProcess hinzugefügt.
✇ Technology Review Blog

Die Produktwerker: Wie kann Innovation im Unternehmen "trotz Scrum" gelingen?

Von heise online — 13. Februar 2024 um 12:25
Wie kann Innovation im Unternehmen gelingen und auf welche Hindernisse muss man sich gefasst machen? Zu Gast in dieser Podcastfolge ist Marcel Mellor.
✇ Technology Review Blog

Die Formatierungsbibliothek in C++20: Formatieren benutzerdefinierter Datentypen

Von heise online — 12. Februar 2024 um 12:03
Neben den Basistypen und std::string lassen sich in C++20 auch benutzerdefinierte Typen formatieren.
✇ Technology Review Blog

Neu in .NET 8.0 [9]: Neue und erweiterte Datenannotationen

Von heise online — 09. Februar 2024 um 15:33
In .NET 8.0 hat Microsoft die Annotationsklassen im Namensraum System.ComponentModel.DataAnnotations erweitert.
✇ Technology Review Blog

Scrum-Team versus agiles Team

Von heise online — 07. Februar 2024 um 14:43
Aus welchen Personen ein Scrum-Team besteht, ist klar definiert. Aber was ist mit einem agilen Team?
✇ Developer-Blog - Neuigkeiten von der Insel

06. Februar 2024 um 13:13

[unable to retrieve full-text content]

✇ Technology Review Blog

Die Formatierungsbibliothek in C++20: Details zum Formatstring

Von heise online — 05. Februar 2024 um 14:35
Der zweite Teil der Serie zu Formatstrings in C++20 beschäftigt sich mit der Breite, der Genauigkeit und dem Datentyp der Formatspezifikation.
✇ Technology Review Blog

Die Produktwerker: Product Backlog auf neue Weise organisieren

Von heise online — 05. Februar 2024 um 10:12
Das Product Backlog muss nicht immer eine Liste sein. Die Produktwerker geben in dieser Folge einen Einblick in alternative Formen des Product Backlogs.
✇ Developer-Blog - the next big thing

Vanilla-Web: Der Frontend-Trend 2024?

Von Golo Roden — 02. Februar 2024 um 08:30
Businesswoman,Laptop,Using,,social,,Media,,Marketing,Concept,/,Blue,Tone

(Bild: FotoDuets/Shutterstock.com)

Die Entwicklung von Web-UIs erfordert zu viele Frameworks und Tools, die zudem aufwendig und komplex zu integrieren sind. Könnte sich das im Jahr 2024 ändern?

Stellen Sie sich vor, Sie planen die Entwicklung einer neuen Web- oder Cloud-basierten Anwendung. Dabei haben Sie für das Backend bereits alle Technologien festgelegt, doch bei der Auswahl für das Frontend herrscht noch Unsicherheit: Sollten Sie auf bewährte Frameworks wie React, Angular oder Vue setzen, oder wäre ein jüngeres, weniger etabliertes Framework wie Svelte oder Solid.js die bessere Wahl?

Diese Frage ist keineswegs neu, und es gibt keine eindeutige Antwort. Doch unabhängig von Ihrer Entscheidung gehen Sie stets eine Bindung ein, was einen sogenannten "Vendor-Lock-in" zur Folge hat, ohne die Garantie, dass das gewählte Framework auch in Zukunft noch unterstützt wird.

Einfachheit und Leichtigkeit

Darüber hinaus gibt es immer noch keinen allgemeingültig etablierten Ansatz für die Web-UI-Entwicklung, was die regelmäßige Veröffentlichung neuer Frameworks belegt. Zusätzlich zur Framework-Auswahl benötigen Sie allerdings auch noch eine Vielzahl von Werkzeugen: vom TypeScript-Compiler über SASS- oder LESS-Precompiler bis hin zu Package-Managern wie npm oder Yarn, Build-Tools wie Vite und eventuell speziellen Bundlern. Viele Entwicklerinnen und Entwickler verlieren angesichts dieser stetig wachsenden Komplexität und der Flut neuer Tools die Freude an der Webentwicklung, deren Merkmal vor vielen Jahren einmal Einfachheit und Leichtigkeit waren.

Angesichts dieser Entwicklung stellt sich die Frage, wohin der Trend führt und ob es nicht an der Zeit ist, innezuhalten und zu überlegen, ob die Branche möglicherweise seit Jahren in die falsche Richtung läuft. Gibt es vielleicht einen Weg, die Dinge grundlegend zu verbessern?

Tatsächlich war die Webentwicklung früher grundlegend anders als heute: Sie war unkompliziert und direkt. Ein einfacher Texteditor, ein paar Änderungen an HTML, CSS oder JavaScript und ein Speichern und Neuladen im Browser genügten, ohne jegliche Notwendigkeit für Compiler oder spezielle Werkzeuge. Diese Einfachheit, die vor etwa 25 Jahren bestand, stand im starken Kontrast zur damaligen Desktop-Entwicklung, die praktisch immer einen Compiler erforderte und dadurch Wartezeiten bis zur Ausführung mit sich brachte. Diese reduzierte und unmittelbare Art der Webentwicklung war faszinierend und stellte einen ihrer größten Reize dar.

Über die Jahre gestiegene Komplexität

Heute hat sich das Bild jedoch gewandelt. Die Entwicklung ist nicht mehr so intuitiv. Für das Schreiben von HTML ist beispielsweise oft JSX oder eine ähnliche Abstraktion erforderlich, was wiederum einen Precompiler voraussetzt. Dieser muss über npm installiert werden, wofür Node.js notwendig ist, das idealerweise über den Node Version Manager (nvm) installiert wird. Bereits diese Kette aus Technologien, die lediglich für das Schreiben von HTML benötigt wird, verdeutlicht die Komplexität. Nicht einmal berücksichtigt sind hierbei CSS oder JavaScript, geschweige denn das umfassende Ökosystem mit Tools für Linting, Formatting und weiteren Funktionen. Kurz gesagt: Die Freude an der Frontend-Webentwicklung ist durch diese Komplexitätssteigerung merklich gesunken.

Das Bedauerliche an der heutigen Webentwicklung ist, dass viele der verwendeten Praktiken und Tools eigentlich gar nicht mehr zwingend notwendig wären, da moderne Webbrowser inzwischen eine Vielzahl von Funktionen nativ unterstützen. Im Laufe der Jahre haben wir den eigentlichen Zweck hinter der Nutzung all dieser Frameworks und Werkzeuge jedoch aus den Augen verloren. Es hat sich eine Gewohnheit etabliert, bei der stets die Eignung des eingesetzten Tools hinterfragt wird, ohne je zu überprüfen, ob ein Werkzeug an sich noch erforderlich ist.

Doch zumindest mir scheint es so, als könnte sich das im Jahr 2024 allmählich ändern. Es zeichnet sich ein Momentum ab, das darauf hindeutet, dass die Webentwicklung als solche in den nächsten zwölf Monaten eine grundlegende Wandlung erfahren könnte. Das Ergebnis könnte ein wesentlich stabilerer und zuverlässiger Technologie-Stack sein, der uns langfristig begleiten wird. Im Folgenden möchte ich daher einen Ausblick darauf geben, wie diese Entwicklung aussehen könnte.

Ändert sich Webentwicklung im Jahr 2024?

Wenn man Entwicklerinnen und Entwickler nach dem Hauptgrund für die Nutzung von Frameworks wie React oder Angular fragt, beschreibt die am häufigsten gegebene Antwort die Möglichkeit, eigene Komponenten definieren und orchestrieren zu können. Dabei geht es um das Erstellen autonomer, in sich geschlossener und insbesondere wiederverwendbarer Codeeinheiten, die modular zu einer umfassenderen Einheit, sei es eine Webseite oder eine Webanwendung, zusammengesetzt werden können. Das Wesentliche dabei ist, dass das Orchestrieren dieser Elemente eigentlich eine Grundfunktion von HTML darstellt – es bedürfte also lediglich einer Methode zur Definition eigener HTML-Elemente, um die nativen Möglichkeiten von HTML um benutzerdefinierte Komponenten zu erweitern.

Genau hier kommen die sogenannten Custom Elements [2] ins Spiel. Ein Custom Element ist ein durch JavaScript definiertes, eigenständiges HTML-Element, das anschließend wie jedes standardmäßige HTML-Element genutzt werden kann. Das bedeutet, dass zur Erstellung wiederverwendbarer HTML-Komponenten grundsätzlich kein spezielles Framework erforderlich ist: HTML selbst bietet bereits diese Flexibilität.

Nun könnte der Einwand erhoben werden, dass HTML allein nicht ausreiche, da Komponenten in der Regel auch individuell gestaltet werden sollen. Dabei ist es oft ein Anliegen, sicherzustellen, dass die Stile verschiedener Komponenten sich nicht gegenseitig beeinflussen. Mit anderen Worten: Man wünscht sich für jede Komponente einen eigenen, klar abgegrenzten Bereich für CSS. In vielen Frameworks hat sich dafür das Konzept der CSS-Module durchgesetzt. Dies erfordert jedoch in der Regel einen Bundler, der diese CSS-Module auch entsprechend unterstützt.

Doch auch hier ist eine solche Komplexität nicht zwingend erforderlich, da Webbrowser nativ in der Lage sind, eigene CSS-Bereiche zu verwalten. Dies ermöglicht es, jedem Custom Element einen abgeschotteten CSS-Bereich zuzuweisen, was durch die Verwendung des Shadow DOM [3] erreicht wird. Die Kombination aus Custom Elements und dem Shadow DOM bildet die Grundlage für das, was gemeinhin als Web Components bekannt ist. Streng genommen gehört dazu auch das HTML-Template-Element [4], aber im Kern erlauben Web Components genau das, wofür häufig zusätzliche Frameworks eingesetzt werden: das Definieren von wiederverwendbaren Komponenten mit einem eigenen CSS-Bereich.

Altbacken wirkende APIs

Man könnte nun argumentieren, dass Web Components, obwohl sie bereits seit 2011 existieren und durchaus ihre Vorzüge haben, in der Praxis oft wenig Freude bereiten, da ihre APIs als altbacken empfunden werden können. Ich stimme dieser Ansicht vollkommen zu. Glücklicherweise existieren jedoch elegante Abstraktionen für Web Components, die ihre Nutzung erheblich erleichtern. Ein Beispiel hierfür ist das Framework Lit [5].

Hier könnte der Einwand folgen, dass die Verwendung solcher Abstraktionen dem eigentlichen Zweck zuwiderläuft, da man dadurch wieder auf ein Framework angewiesen ist. Das ist grundsätzlich korrekt, doch im Gegensatz zu Frameworks wie React oder Angular erzeugt man mit Lit Komponenten, die nicht an ein spezifisches Framework gebunden sind. Diese Komponenten sind universell einsetzbar, egal ob mit anderen Frameworks oder ganz ohne. Dieser Aspekt stellt für mich persönlich eine deutliche Verbesserung dar.

Lit als Abstraktionsschicht

Zu Beginn habe ich meine Vorbehalte gegenüber dem Build-Schritt in der Entwicklung erwähnt. Die Annahme, dass die Nutzung von Lit als Framework zwangsläufig einen solchen Schritt nach sich zieht, hielt ich lange für gegeben. Doch diese Annahme ist nicht korrekt: Lit kann bei Bedarf tatsächlich vollständig zur Laufzeit ausgeführt werden, ohne die Notwendigkeit eines Compilers, was den Entwicklungsprozess erheblich vereinfacht. Noch bequemer wird es, wenn man erkennt, dass Lit nicht einmal über npm installiert werden muss, sondern direkt über einen Import aus einem Content Delivery Network (CDN) eingebunden werden kann.

Gegen den Einwand, dass dies zu einer Abhängigkeit von Versionsnummern in der Import-URL führen würde, gibt es eine elegante Lösung: das Verwenden einer Import Map [6]. Dieses weitere Feature moderner Browser ermöglicht es, einmalig und zentral zu definieren, dass es beispielsweise einen Import namens "lit" geben und auf welche URL dieser verweisen soll. Anschließend kann in jedem Skript mit Lit gearbeitet werden, als wäre es lokal via npm installiert. Damit ist das Problem gelöst – ganz ohne npm und ohne Build-Schritt.

Die Möglichkeit, JavaScript-Code als ES-Module dynamisch zur Laufzeit nachzuladen, hat in den letzten Jahren die Tür für flexiblere Entwicklungsansätze geöffnet. Ein häufiger Einwand hierbei ist die Befürchtung, dass die Anwendung letztlich aus vielen kleinen Dateien bestehen und dadurch unnötiger HTTP-Overhead beim Laden entstehen könnte. Ich erkenne diesen Punkt grundsätzlich an, doch stellt sich die Frage nach der tatsächlichen Relevanz dieses Overheads (insbesondere in Zeiten von HTTP/2). Ist für die Webseite oder die Webanwendung, an der gearbeitet wird, wirklich jede Millisekunde Ladezeit entscheidend, oder spielt dies eine untergeordnete Rolle?

Sicherlich gibt es Szenarien, beispielsweise im Bereich der Suchmaschinenoptimierung (SEO), bei denen eine schnelle Ladezeit mit möglichst wenigen Requests von großer Bedeutung sein kann. Andererseits existieren auch Fälle, in denen die Performance weniger kritisch ist, etwa bei Anwendungen, die nicht öffentlich zugänglich sind und nur einem begrenzten Nutzerkreis dienen. In solchen Situationen könnte der zusätzliche Overhead vernachlässigbar sein. Es lohnt sich, diese Aspekte zumindest einmal in Betracht zu ziehen und zu überdenken.

CSS ist mächtiger denn je

Bis zu diesem Punkt haben wir gesehen, dass es möglich ist, Komponenten zu definieren und zu orchestrieren, dies mit einer benutzerfreundlichen API zu tun, CSS zu scopen, eine zentrale Importverwaltung zu haben und all das ohne einen Compile- oder Build-Schritt zu benötigen. Doch was, wenn Sie CSS nicht direkt innerhalb einer Webkomponente definieren möchten? Nicht alle Entwicklerinnen und Entwickler bevorzugen es, HTML, CSS und JavaScript in einer einzigen Datei zu kombinieren. Viele ziehen es stattdessen vor, CSS in externe Dateien auszulagern, ein Ansatz, der einer der Vorzüge von CSS-Modules ist, und der dort anstandslos funktioniert.

Das Interessante ist, dass dies mit CSS Module Scripts [7] tatsächlich auch nativ möglich ist, ohne die Notwendigkeit von CSS-Modulen und dem entsprechenden Tooling (wobei dieses Feature derzeit nur von Chrome-basierten Webbrowsern unterstützt wird). Das Konstrukt stützt sich auf die sogenannten Constructable Stylesheets [8]. Denn in Kombination bieten diese beiden Technologien genau das, was viele sich wünschen: gescopetes CSS innerhalb eines Shadow DOM, jedoch in einer separaten CSS-Datei.

Bezüglich CSS könnte man sich fragen, ob der Einsatz von Präprozessoren wie SASS oder LESS wirklich notwendig ist. Oftmals wird als Hauptgrund für deren Verwendung die Fähigkeit genannt, CSS-Anweisungen verschachteln zu können. Interessanterweise bietet CSS mittlerweile jedoch native Unterstützung für das Nesting, wodurch eine der wesentlichen Funktionen, die bisher Präprozessoren vorbehalten war, direkt verfügbar wird. Dies macht den Einsatz solcher Tools weitgehend überflüssig.

Darüber hinaus sind viele weitere Features, die einst den Einsatz von SASS oder ähnlichen erforderlich machten, nun Teil des CSS-Standards, einschließlich, aber nicht beschränkt auf, das Theming. Letzteres lässt sich effektiv mit nativen CSS-Variablen bewerkstelligen, was den Bedarf an externen Präprozessoren weiter verringert.

Eine 1:1-Alternative?

Es ist klar, dass die native Webentwicklung nicht in jeder Hinsicht eine 1:1-Alternative zu Frameworks wie React oder Angular darstellt. Diese Frameworks geben schließlich auch eine gewisse Struktur für Anwendungen vor, die allerdings je nach Framework variieren kann. Dennoch ist es bemerkenswert, wie viel mittlerweile mit den nativen Funktionen von Webbrowsern erreicht werden kann, wodurch der Bedarf an Compilern, Bundlern und ähnlichen Tools entfällt oder zumindest deutlich reduziert wird. Der vollständige Verzicht wird gelegentlich als "Buildless" bezeichnet, was den Fokus allerdings zu sehr auf den Wegfall des Kompilierungsschrittes legt.

Ich persönlich würde es vorziehen, diesen Ansatz eher als "Vanilla-Web" zu bezeichnen, in Anlehnung an "Vanilla-JavaScript". Dies impliziert die Nutzung des Webs in seiner reinsten Form, ohne externe Bibliotheken und Frameworks, und stützt sich ausschließlich auf die standardmäßig verfügbaren Funktionen.

Möglicherweise ist alles bis hierhin beschriebene für Sie nichts oder zumindest kaum Neues, da viele der angesprochenen Technologien bereits seit einigen Jahren verfügbar sind. Der entscheidende Punkt ist jedoch, dass diese Technologien zwar existieren und greifbar sind, bislang aber nicht das Gefühl aufkommt, dass sie in größerem Maßstab effektiv kombiniert und im großen Stil eingesetzt werden. Stattdessen neigen viele Entwicklerinnen und Entwickler dazu, aus Gewohnheit bei den Frameworks zu bleiben, die ihnen vertraut sind.

Mein Eindruck ist jedoch, dass eine zunehmende Bereitschaft für Veränderungen in dieser Hinsicht entsteht. Natürlich würde eine solche Anpassung eine erneute Umstellung bedeuten, aber das Besondere daran wäre, dass es sich um die möglicherweise letzte Umstellung dieser Art handeln könnte. Dieser Ansatz könnte sich als zuverlässiger und nachhaltiger erweisen als einige der Web-UI-Frameworks, mit denen wir in den letzten Jahren konfrontiert waren.

Und was ist mit TypeScript?

Ein wesentlicher Faktor, der den Übergang zu einem vollständig Build-freien Entwicklungsprozess erschwert, ist der Einsatz von TypeScript. Zwar existiert der etwas unkonventionelle Vorschlag von Microsoft, Typ-Annotationen in TypeScript als Kommentare innerhalb von JavaScript zu behandeln [9], doch in der Praxis ist ein Compiler momentan noch unumgänglich. Dies muss zwar nicht zwingend der offizielle TypeScript-Compiler sein (Tools wie esbuild können diese Aufgabe ebenfalls übernehmen), aber ein Build-Schritt ist so oder so nach wie vor erforderlich.

Eine Alternative könnte darin bestehen, auf TypeScript-spezifische Typdefinitionen zu verzichten und stattdessen auf JSDoc sowie das manuelle Erstellen von .d.ts-Dateien zurückzugreifen. Das ermöglicht es, den TypeScript-Compiler zu umgehen und dennoch eine angemessene Typsicherheit zu gewährleisten. Das Svelte-Team ist ein prominenter Befürworter dieser Methode und hat für Svelte 4 die Implementierung dieses Ansatzes mit JSDoc umgesetzt. Es bleibt spannend zu beobachten, wie sich diese Entwicklung in der Praxis bewähren wird.

Der Weg nach vorn

Für Sie bedeutet das vor allem, dass Ihr bevorzugtes JavaScript-Framework samt dem dazugehörigen Tooling möglicherweise nicht mehr so unverzichtbar ist, wie es in den vergangenen Jahren den Anschein hatte. Ich empfehle Ihnen daher, sich mit den erwähnten Technologien und Konzepten vertraut zu machen, eigene Experimente durchzuführen und kritisch zu hinterfragen, ob das von Ihnen genutzte Framework und Tooling tatsächlich den Mehrwert bietet, den Sie erwarten, oder ob es für bestimmte Aufgaben vielleicht überdimensioniert ist.

Ich vermute, dass sich im Laufe dieses Jahres in dieser Hinsicht einiges ändern könnte. Wenn Sie diesen Weg nicht allein beschreiten möchten, sondern Ihren Technologiestack gerne gemeinsam mit jemandem überprüfen und reflektieren möchten, können wir bei the native web [10] Sie dabei gerne unterstützen.


URL dieses Artikels:
https://www.heise.de/-9611002

Links in diesem Artikel:
[1] https://www.heise.de/Datenschutzerklaerung-der-Heise-Medien-GmbH-Co-KG-4860.html
[2] https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements
[3] https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM
[4] https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots
[5] https://lit.dev/
[6] https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
[7] https://web.dev/articles/css-module-scripts
[8] https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet
[9] https://www.youtube.com/watch?v=7fNFbJDdDuA
[10] https://www.thenativeweb.io/
[11] mailto:rme@ix.de

Copyright © 2024 Heise Medien

Adblock test (Why?)

✇ Technology Review Blog

Neu in .NET 8.0 [8]: Verbesserungen für nameof() in C# 12.0

Von heise online — 02. Februar 2024 um 12:30
Der in C# 6.0 eingeführte Operator, der den Namen eines Bezeichners als String liefert, hatte bisher einige Einschränkungen, die in C# 12.0 entfallen.
✇ Technology Review Blog

Vanilla-Web: Der Frontend-Trend 2024?

Von heise online — 02. Februar 2024 um 08:30
Die Entwicklung von Web-UIs erfordert zu viele Frameworks und Tools, die zudem aufwendig und komplex zu integrieren sind. Könnte sich das im Jahr 2024 ändern?
✇ Technology Review Blog

Die Produktwerker: Ausgründen im Konzern – eine persönliche Reise

Von heise online — 29. Januar 2024 um 14:02
Eine Unternehmensgründung birgt Risiken. Das Ausgründen aus einem Konzern heraus kann eine Alternative sein. Zu Gast in dieser Folge ist Christian Fahl.
✇ Technology Review Blog

Die Formatierungsbibliothek in C++20: Der Formatstring

Von heise online — 29. Januar 2024 um 11:10
Der Beitrag setzt die Serie zu Formatstrings in C++20 fort und taucht tiefer in die Formatspezifikation ein.​
✇ Technology Review Blog

Neu in .NET 8.0 [7]: Optionale Parameter in Lambda-Ausdrücken in C# 12.0​

Von heise online — 26. Januar 2024 um 14:18
Die aktuelle Version von Microsofts Programmiersprache C# erweitert sowohl reguläre Lambdas als auch Statement Lambdas.​
✇ Technology Review Blog

Wie uns Git agil macht – oder auch nicht

Von heise online — 25. Januar 2024 um 12:48
Können Tools und wie man sie verwendet beeinflussen, ob ein Team "agil" arbeitet? A fool with a tool is still a fool, meint Stefan Mintert.
✇ Technology Review Blog

Die Produktwerker: Wie agil ist eine jährliche Roadmap?

Von heise online — 24. Januar 2024 um 11:34
Der Umgang mit Projekt- und Produkt-Roadmaps birgt einige Schwierigkeiten. Wie es besser gehen kann, diskutieren die Produktwerker in dieser Folge.
✇ Technology Review Blog

Mein Scrum ist kaputt #126: Freundschaften in agilen Teams

Von heise online — 24. Januar 2024 um 09:31
Diese Folge des Scrum-Podcasts handelt von Teamkultur und der Frage, inwieweit Freundschaften innerhalb eines Teams gut für das Team oder eher hinderlich sind.
✇ Technology Review Blog

Softwareentwicklung: Die Formatierungsbibliothek in C++20

Von heise online — 22. Januar 2024 um 11:39
Die Serie zur Formatierungsbibliothek in C++20, dessen Basis das C++20-Buch des Blogautors ist, sollen als Nachschlagewerk dienen.
✇ Technology Review Blog

Neu in .NET 8.0 [6]: ref readonly in C# 12.0

Von heise online — 19. Januar 2024 um 16:07
In der aktuellen Version von C# lassen sich Methodenparameter als unveränderlich deklarieren.
✇ Developer-Blog - Neuigkeiten von der Insel

Softwareentwicklung: Die Performance von Java Logging

Von Hendrik Ebbers — 18. Januar 2024 um 10:20

(Bild: Open Elements)

Für Java gibt es eine Fülle an verschiedenen Logging-Bibliotheken und Möglichkeiten, Log-Nachrichten auszugeben. Aber welche davon sind wirklich performant?

In den vorherigen Posts zum Thema Java Logging (Best Practices [1], Logging Facades [2]) habe ich bereits erwähnt, dass es eine Fülle an Java Libraries zum Thema Logging gibt. Nachdem wir im letzten Post geklärt haben, wie man mit einer Facade verschiedene Logger vereinen kann, wollen wir uns nun die Performance von Logging-Bibliotheken anschauen.

Performance-Messung in Java

Um kleine Teile einer Java-Anwendung oder -Bibliothek mittels eines Benchmarks zu überprüfen, gibt es in Java das Tool Java Microbenchmark Harness (JMH) [3], das vom OpenJDK bereitgestellt wird, um Performance-Benchmarks durchzuführen. Es führt ähnlich wie bei Unit-Tests kleine Teile der Anwendung (Micro-Benchmarks) aus und analysiert sie. Hierbei kann man unter anderem einstellen, ob der Code zuvor mehrfach für ein paar Sekunden ohne Messung durchlaufen soll, um die JVM und JIT "warmzulaufen".

Diese und andere Parameter lassen sich bei JMH ähnlich wie bei JUnit einfach durch Annotations definieren. Ein simples Beispiel für einen Benchmark sieht folgendermaßen aus:

@Benchmark
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 4, time = 4)
@Measurement(iterations = 4, time = 4)
public void runSingleSimpleLog() {
    logger.log("Hello World");
}

Das Beispiel führt vier Durchläufe zum Aufwärmen durch, gefolgt von vier Messdurchläufen. Jeder Durchlauf dauert vier Sekunden, und das Messergebnis zeigt an, wie viele Operationen pro Sekunde durchgeführt werden konnten. Konkret bedeutet das, wie oft "Hello World" geloggt werden konnte. Das Ganze bekommt man nach dem Durchlauf tabellarisch in der Kommandozeile ausgegeben, kann es aber auch beispielsweise als JSON- oder CSV-Datei speichern.

Performance-Messung für Java Logger

Mithilfe von JMH habe ich einen Open-Source-Benchmark für Logging-Frameworks erstellt, das bei GitHub einsehbar ist [4]. Er überprüft aktuell folgende Logging-Bibliotheken beziehungsweise Set-ups auf ihre Performance:

  • JuL (java.util.logging) mit Logging auf die Konsole
  • JuL (java.util.logging) mit Logging in ein File
  • JuL (java.util.logging) mit Logging auf die Konsole und in ein File
  • SLF4J Simple mit Logging in ein File
  • Log4J2 mit Logging auf die Konsole
  • Log4J2 mit Logging in ein File
  • Log4J2 mit Logging auf die Konsole und in ein File
  • Log4J2 mit asynchronen Logging in ein File
  • Chronicle Logger mit asynchronen Logging in ein File

Für jede dieser Konstellation gibt es verschiedene Benchmarks, die die Performance vom Erstellen des Logger über das Loggen einer einfachen "Hello World"-Nachricht bis hin zu komplexen Logging-Aufrufen (Placeholder in Message, Marker, MDC Nutzung, etc.) messen.

Die Messungen zeigen, dass Logging-Frameworks generell sehr performant sind. Auf der anderen Seite führten sie aber auch ein paar Erkenntnisse zutage, die sicherlich nicht jedem direkt klar sind.

Im Folgenden findet sich eine Übersicht von Messergebnissen beim einfachen Loggen einer "Hello World" Nachricht:

Das Problem mit der Konsole

Ein erstes Ergebnis der Messungen ist, dass ein Logging auf die Konsole immer deutlich langsamer ist als ein Logging ins Dateisystem. Während man beim Logging in eine Datei 200.000 bis 300.000 Aufrufe des Loggers pro Sekunde erreichen kann, sind es bei einer Ausgabe auf die Konsolen immer deutlich unter 100.000 Operationen die Sekunde gewesen. Da alle Logging-Libraries hier mit System.out bzw. System.err arbeiten, macht es auch kaum einen Unterschied in der Performance, welche Bibliothek man nutzt. Hier wird es in Zukunft spannend zu schauen, ob man durch Tricks oder Umbauten eine bessere Performance hinbekommen kann.

Synchrones und Asynchrones Logging in Files

Einen weiteren großen Unterschied sieht man, wenn man die Messwerte von synchronen bzw. asynchronen Logging in eine Datei betrachtet. Hier wird sofort deutlich, dass asynchrones Logging deutlich schneller ist. Die folgenden Tabellen zeigen die Messwerte von asynchronen Logging im Vergleich zu synchronen Logging:

Die klar erkennbar höherer Performance liegt daran, dass die Schreiboperation der asynchronen Logger nicht blockiert. Die Logger Log4J2 und Chronicle Logger nutzen zwar intern unterschiedliche Bibliotheken intern, basieren aber beide auf einer "lock-free inter-thread communication library". Während bei Log4J hierbei LMAX Disruptor [5] als Bibliothek hinzugefügt werden muss, die intern über Ringbuffer das asynchrone Logging ermöglicht, basiert der Chronicle Logger direkt auf der Chronicle Queue Bibliothek [6].

Konkrete Beschreibung der intern genutzten Libraries und wie diese eine asynchrone Kommunikation beziehungsweise das Schreiben ins Dateisystem ermöglichen, lässt sich der Dokumentation entnehmen.

Wenn man die Performance von Log4J2 und Chronicle Logger vergleicht, kann man sehen, dass der Chronicle Logger noch einmal deutlich schneller ist. Dieser Performance-Vorteil kommt aber auch mit einem Nachteil, dem man sich bewusst sein muss: Während Log4J2 auch im asynchronen Modus weiterhin zeilenweise ein für den Menschen einfach lesbares Logging im Dateisystem erzeugt, schreibt der Chronicle Logger alle Nachrichten in einem Binärformat. Hier wird zum Lesen bzw. Parsen dann ein Tooling benötigt, das der Logger aber mitliefert. Darüber hinaus ist die Varianz der Testergebnisse des Chronicle Logger deutlich höher. Als Grund vermute ich, dass die genutzt Chronicle Queue die binären Daten zum Schreiben des Logging intern verwaltet und deren Größen immer dynamisch anpasst. Dies muss allerdings noch weiter untersucht werden. Die folgende Tabelle zeigt einmal eine Übersicht der Varianz:

Fazit

Wie man sehen kann, ist nicht nur die Wahl einer Logging Bibliothek, sondern auch deren Konfiguration extrem wichtig für die Performance. Während das Logging auf die Konsole während der Entwicklung sicherlich sehr angenehm ist, kann man sich beispielsweise überlegen, ob die Nutzung des Konsolen-Logging im Live-Betrieb wirklich immer erforderlich ist. Auch zeigt sich, dass eine Nutzung von asynchronen Loggern sinnvoll sein kann, wenn die Performance des Systems wirklich kritisch ist. Das kommt aber natürlich mit einer höheren Komplexität und zusätzlichen transitiven Abhängigkeiten einher. Letztlich muss also jedes Projekt weiterhin selbst für sich entscheiden, welcher Logger am sinnvollsten ist. Durch die hier genannten Zahlen hat man aber nun eine weitere Basis, um das festzulegen.


URL dieses Artikels:
https://www.heise.de/-9278737

Links in diesem Artikel:
[1] https://www.heise.de/blog/Best-Practices-und-Anti-Pattern-beim-Logging-in-Java-und-anderen-Sprachen-7336005.html
[2] https://www.heise.de/blog/Logging-Facades-fuer-Java-7355974.html
[3] https://github.com/openjdk/jmh
[4] https://github.com/OpenElements/java-logger-benchmark
[5] https://github.com/LMAX-Exchange/disruptor
[6] https://github.com/OpenHFT/Chronicle-Queue
[7] mailto:rme@ix.de

Copyright © 2024 Heise Medien

Adblock test (Why?)

❌