Kolumne

Enterprise Tales: Wie fit ist der Browser mittlerweile?

Sven Kölpin

Webbrowser haben sich lange Zeit nicht gerade mit Ruhm bekleckert. Inkonsistente Implementierungen, schlechtes API-Design und vor allem das Fehlen wichtiger Funktionalitäten haben Entwicklern das Leben erschwert. So waren Webapplikationen ohne die Verwendung clientseitiger Bibliotheken lange völlig undenkbar. Zum Glück hat sich aber in den letzten Jahren nicht nur die JavaScript-, sondern vor allem auch die Browserwelt stark weiterentwickelt. Aktuelle Versionen liefern umfangreiche Toolsets für die Erstellung moderner und leistungsfähiger Webanwendungen. Außerdem stehen aufgrund kurzer Releasezyklen wichtige Updates und Features immer schneller zur Verfügung.

Dass Browser zukünftig die Verwendung diverser JavaScript-Bibliotheken komplett überflüssig machen könnten, lässt sich aktuell am Beispiel von www.github.com zeigen. Hier wurde in der neuesten Version ausschließlich auf standardisierte APIs gesetzt – so konnte der Einsatz von Bibliotheken wie jQuery vollkommen vermieden werden. Der Schritt des GitHub-Teams ist eine logische Konsequenz aus der stetigen Weiterentwicklung der Browserstandards in den letzten Jahren. Die Nichtverwendung von Bibliotheken bringt selbstverständlich Vorteile für die Netzwerklast, da weniger JavaScript übertragen werden muss. Zusätzlich ist die direkte Nutzung der nativen APIs im Allgemeinen performanter.

Moderne Browser verbessern durch Standardisierung aber nicht nur die Entwicklung, sondern liefern vor allem auch viele interessante Features, die die Plattform „Web“ immer bedeutsamer machen. Der Zugriff auf diese Features erfolgt über die Browser-APIs.

Diese, auch als Web-APIs bekannt, ermöglichen es Entwicklern, bestimmte Funktionen des Browsers über ein standardisiertes JavaScript-API anzusprechen. Wie und in welcher Sprache die konkreten Schnittstellen im Browser selbst implementiert sind, ist dabei nicht festgelegt (in Chrome wird zum Beispiel größtenteils C++ verwendet).

Die APIs sind sehr vielfältig und bieten zahlreiche Funktionen. So gehört beispielsweise der Zugriff auf das Document Object Model (DOM) des Browsers genauso dazu wie Interfaces zum Senden von Ajax Requests oder Audio- und Video-APIs. In diesem Zusammenhang ist es wichtig zu verstehen, dass die verschiedenen APIs dabei nur über JavaScript angesprochen werden, aber keine Features der Sprache sind. In JavaScript gibt es also eigentlich keine HTML-Objekte und kein Ajax – diese Interfaces stellt der Browser zur Laufzeit zur Verfügung.

Grundsätzlich wird unterschieden zwischen dem Browser Object Model (BOM), das Objekte für die Interaktion mit dem Browser beinhaltet (zum Beispiel Location, History, Fetch), und dem bereits erwähnten Document Object Model (DOM), das Zugriff auf die eigentlichen HTML-Elemente bietet. Letzteres hält beispielsweise umfangreiche Funktionen für die Selektion und Manipulation des im Browser gerenderten HTML bereit. Das DOM ist dabei streng genommen ein Teil des BOM.

Ganz ohne Bibliotheken

Githubs Abwendung von clientseitigen Bibliotheken könnte ein richtungsweisender Schritt für die Zukunft der Entwicklung von Webanwendungen sein. Fanden doch in den letzten Jahren in Bezug auf clientseitige Bibliotheken so rasante Entwicklungen und permanente Veränderungen statt, dass gleichzeitig das Vertrauen in nachhaltige Weblösungen immer geringer wurde. Nun aber scheint die ausschließliche Verwendung von standardisierten APIs eine interessante Strategie zu sein.

Spannend ist in diesem Zusammenhang aber selbstverständlich die Frage, welche APIs und Browserfeatures heute überhaupt dazu beitragen, dass eine Entwicklung ganz ohne Bibliotheken möglich zu sein scheint. Laut www.github.com sind hier in erster Linie die modernen DOM-APIs (z.B. querySelectorAll), Request APIs (z.B. fetch) und Custom Elements (teil von Web Components) die treibenden Kräfte.

DOM APIs: Die Interaktion mit dem DOM ist für Webanwendungen unabdingbar. Die Selektion und die Manipulation von Elementen, Attributen und das Event Handling waren aber lange durch unzureichende APIs nicht trivial und in den Browsern teilweise auch noch unterschiedlich implementiert. Das ist im Übrigen einer der hauptsächlichen Gründe für das Aufkommen und den langjährigen Erfolg von Bibliotheken wie jQuery.

Mittlerweile hat sich das aber geändert. Die (modernen) Browser stellen mächtige DOM APIs zur Verfügung, die die Suche im DOM und dessen Manipulation vereinfachen. Zu erwähnen sind hier vor allem das querySelectorAll– und das querySelector-API, mit denen sich komplexe Selektionen im DOM realisieren lassen. Auch bei GitHub kommen diese APIs nun anstelle der jQuery-Selektoren zum Einsatz.

Request APIs: Für eine lange Zeit waren Ajax Requests im Browser ausschließlich über das XMLHttp-Request-Interface möglich. Dieses API glänzt nicht gerade durch eine schöne Syntax und wirkt, nicht zuletzt aufgrund des Namens, schon lange nicht mehr zeitgemäß. Zum Glück gibt es mittlerweile mit dem fetch-API eine viel schlankere Alternative, die von allen aktuellen Browsern unterstützt wird. Das API basiert auf JavaScript Promises und ist die Grundlage für andere neue Browser-APIs wie Service Workers. Listing 1 zeigt die Verwendung von fetch zum Senden eines einfachen GET-Requests.

Etwas weniger bekannt ist das beacon-API. Das ist zwar noch nicht vollends standardisiert, aber bereits in allen modernen Browsern verwendbar. Es ermöglicht das Senden von Requests zu einem Server, ohne dass eine Antwort erwartet wird. Deshalb kann der Browser, im Gegensatz zu herkömmlichen Request APIs, Beacon Requests im Hintergrund senden, ohne den Benutzer zu „stören“ (zum Beispiel Senden erst bei geringer CPU- oder Netzwerklast). Ein beacon Request kann zudem auch beim Verlassen einer Seite (unload-Event) versendet werden – das war bisher nicht ohne Weiteres möglich. Das beacon-API eignet sich damit speziell für Logging- oder Tracking-Anwendungsfälle.

async function fetchData() {
  const serverResponse = await fetch('http://example.com/movies.json');
  const json = await serverResponse.json();
  ...
};
function sendLogMsg(message) {
  const logData = JSON.stringify({
    location: window.location,
    message,
    time: Date.now()
  });
  navigator.sendBeacon('/analytics', logData);
}

Custom Elements: Custom Elements ermöglichen die Definition eigener, semantischer HTML-Komponenten. Sie sind Teil der Web-Components-Umbrella-Spezifikation. Deren Ziel ist es, dass Entwickler eigene, wiederverwendbare und von außen abgekapselte Komponenten für das Web erstellen können, ohne auf externe Bibliotheken wie jQuery oder Dojo angewiesen zu sein. Aktuell gehören folgende drei Kerntechniken zu Web Components:

  • Custom Elements erlauben die Implementierung eigener HTML-Komponenten auf Basis von Java-Script. Die Komponenten können Logik, Mark-up und Lifecycle-Methoden beinhalten. So ermöglichen sie eine komponentenbasierte Entwicklung von Webanwendungen mit Browser-Board-Mitteln. Listing 3 zeigt ein einfaches Beispiel für Custom Elements.
  • HTML-Templates ermöglichen die Nutzung von wiederverwendbaren Mark-up-Vorlagen für Custom Elements.
  • Shadow DOM ist ein von der eigentlichen DOMStruktur versteckter DOM-Baum, der Custom Elements dazu befähigt, Eigenschaften, Styles und Verhalten der Komponente privat zu halten und Kollisionen mit anderen Teilen des DOM-Baums zu vermeiden.

Auch bei GitHub kommen Custom Elements bereits zum Einsatz. Eine umfassende native Unterstützung ist für sie aber bislang lediglich im Chrome-Browser gegeben – in allen anderen Browsern muss auf externe Hilfsmittel zurückgegriffen werden. Trotzdem sind Web Components eine vielversprechende Spezifikation, die vor allem vom Technologiegiganten Google vorangetrieben wird. Auch andere große Webanwendungen setzen bereits auf Web Components (zum Beispiel www.youtube.com) – hier kommt dafür aber die Bibliothek polymer zum Einsatz.

//class syntax available in JS since ES 2015.
  class WordCount extends HTMLElement {
    constructor() {
      super();
      this.countWords();
    }

    countWords(){
      const numWords = this.innerHTML.split(' ').length;
      const countTitle = document.createElement('div');
      countTitle.textContent = `Words contained: ${numWords}`
      this.appendChild(countTitle);
    }
  }
  //register the element using the name ‘word-count’
  customElements.define('word-count', WordCount);
<!— usage in HTML -->
<word-count>Hello world</word-count>

Herausforderungen bleiben …

Bei www.github.com handelt es sich um eine serverseitig gerenderte Webanwendung. Bei dieser Art von Webapplikation wird das HTML auf dem Server generiert und ein Großteil des Status auch dort verwaltet. JavaScript kommt deshalb hier häufig nur für vereinzelte Funktionalitäten zum Einsatz, die mittlerweile gut mit den browsereigenen APIs implementiert werden können. Bei komplexeren JavaScript-Applikationen, wie zum Beispiel Single-Page Applications, bei denen State-Management und aufwendige Renderingmechanismen benötigt werden, ist der Einsatz von Bibliotheken und Frameworks aber wohl auch in absehbarer Zukunft noch unabdingbar.

Die modernen APIs werden außerdem oftmals nicht von älteren Browserversionen unterstützt. Beispielsweise sind fetch oder Web Components nicht im Internet Explorer implementiert. Für diese Fälle gibt es zwar Polyfills, die ein fehlendes Browserfeature mithilfe von JavaScript „simulieren“ und so die Verwendung moderner APIs auch in älteren Browsern ermöglichen. Die Verwendung der Polyfills setzt jedoch wiederum JavaScript-Bibliotheken voraus, was eine zusätzliche Netzwerklast verursacht (zumindest bei den älteren Browsern). Zudem sind die simulierten Features häufig um ein Vielfaches langsamer als die nativen Implementierungen. Ob und wie gut ein bestimmtes API von den verschiedenen Browsern unterstützt wird, lässt sich im Übrigen auf der Webseite www.caniuse.com herausfinden.

Zu guter Letzt muss festgehalten werden, dass JavaScript-Bibliotheken selbstverständlich nicht nur für die Normalisierung der APIs, sondern vor allem auch für die Verbesserung und Vereinfachung der Syntax zuständig sind. Die Verwendung vieler der browsereigenen Interfaces setzt leider noch immer vergleichsweise viel Schreibarbeit voraus, sodass ein Wrapper um diese oftmals von Vorteil ist. Ein direkter Vergleich der Browser-APIs mit denen von jQuery macht das deutlich.

Fazit

Grundsätzlich war es natürlich schon immer möglich, Webanwendungen komplett ohne Bibliotheken zu entwickeln. Die (neuen) Webstandards der letzten Jahre tragen jedoch dazu bei, die Hürde, Anforderungen im Browser ohne den Einsatz von externen Hilfsmitteln umzusetzen, zu senken. Von komplett bibliothek-, polyfill- und frameworkbefreiten Webapplikationen sind wir heute dennoch ein gutes Stück entfernt. Selbstverständlich ist GitHub ein plakatives Beispiel.

Gleichzeitig ist diese Applikation aber ein Proof of Concept der modernen Webentwicklung. Hier wird gezeigt, in welche Richtung sich die Plattform „Web“ mithilfe von Browserstandards wie Web Components und immer besseren APIs in den kommenden Jahren entwickeln könnte.

In diesem Sinne: Stay tuned.

Geschrieben von
Sven Kölpin
Sven Kölpin
Sven Kölpin ist Enterprise Developer bei der open knowledge GmbH in Oldenburg. Sein Schwerpunkt liegt auf der Entwicklung webbasierter Enterprise-Lösungen mittels Java EE.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: