Web Browser Engineering (2021)
(browser.engineering)- Web Browser Engineering ist ein Buch, das Themen von Networking bis JavaScript behandelt und in dem man mit einigen Tausend Zeilen Python selbst einen einfachen, aber vollständigen Webbrowser baut
- Der Lernpfad führt vom Laden von Seiten über die Darstellung von Dokumenten und das Ausführen von Anwendungen bis hin zu modernen Browser-Funktionen und verbindet dabei HTTP, HTML, CSS, DOM, Sicherheit und die Rendering-Pipeline Schritt für Schritt
- Der Anfang konzentriert sich auf die Implementierung der Browser-Grundlagen wie URLs und HTTP-Requests, das Erzeugen von Fenstern und Zeichnen auf einem Canvas sowie Zeilenumbruch und Zeilenabstand bei Text
- Die mittleren und späteren Kapitel umfassen den Aufbau eines HTML-Baums, Layout, das Anwenden von Styles, Formularübermittlung, Reaktionen auf Events, Cookies und Login sowie XSS und CSRF
- Der Schlussteil führt weiter zu Compositing, Event Loop, GPU-Animationen, Accessibility Tree, iframe, Invalidierung und Korrektheit beim Editieren und bietet damit einen breiten Überblick über Bausteine moderner Browser-Implementierungen
Browser-Architektur durch eigene Implementierung lernen
- Web Browser Engineering ist so aufgebaut, dass man einen einfachen, aber vollständigen Browser selbst implementiert, um zu verstehen, wie Webbrowser funktionieren
- Die Implementierungssprache ist Python, der Gesamtumfang der Implementierung liegt bei einigen Tausend Zeilen
- Der Umfang reicht von Networking bis JavaScript
- Die gedruckte Ausgabe ist bei Bookshop, B&N und Amazon erhältlich
- Übersetzungen liegen auf Koreanisch bei Hanbit und auf Japanisch bei O’Reilly vor
- Updates gibt es im blog, auf Mastodon und Twitter; außerdem existiert ein discussion forum auf GitHub
Inhaltsverlauf
-
Einführung
-
Part 1: Loading Pages
- Downloading Web Pages: URLs und HTTP-Requests
- Drawing to the Screen: Fenster erzeugen und auf dem Canvas zeichnen
- Formatting Text: Zeilenumbruch von Wörtern und Zeilenabstand
-
Part 2: Viewing Documents
- Constructing an HTML Tree: HTML parsen und korrigieren
- Laying Out Pages: Inline- und Block-Layout
- Applying Author Styles: CSS parsen und anwenden
- Handling Buttons and Links: Hyperlinks und Browser-Chrome
-
Part 3: Running Applications
- Sending Information to Servers: Formularübermittlung und Webserver
- Running Interactive Scripts: DOM-Änderungen und Reaktionen auf Events
- Keeping Data Private: Cookies, Login, XSS, CSRF
-
Part 4: Modern Browsers
- Adding Visual Effects: Blending, Clipping, Compositing
- Scheduling Tasks and Threads: Event Loop und Rendering-Pipeline
- Animating and Compositing: flüssige Animationen mithilfe der GPU
- Making Content Accessible: Tastatureingabe, Zoom, Accessibility Tree
- Supporting Embedded Content: Bilder, iframe, Scripting
- Reusing Previous Computation: Invalidierung, Editieren, Korrektheit
-
Abschluss und Anhänge
1 Kommentare
Meinungen auf Hacker News
Ein guter Punkt an diesem Buch ist, dass es einen eigenen Abschnitt zu den „Dingen, die nicht gemacht wurden“ gibt.
Layout ist wirklich schwierig, und selbst wenn man ohne CSS nur Tabellen behandelt, ist es schwer. Kommt CSS dazu, wird Layout nahezu unüberschaubar komplex.
Ich frage mich, ob es überhaupt jemanden gibt, der die gesamte CSS-Spezifikation und das dazugehörige Verhalten im Kopf behalten kann. Das heutige CSS+HTML+JavaScript ist eher zu einer dynamischen Seitenbeschreibungssprache (PDL) geworden und dürfte zu den komplexesten Software-Systemen unserer Zeit gehören.
Ergänzend: Video-Decoding wird auf Hardware ausgelagert und frisst daher nicht mehr so viel Akku wie früher.
Diese Datei implementiert zum Beispiel nur Block-/Inline-Kontexte; es gibt zwar auch etwas Rust-Boilerplate, aber der Großteil ist echte Logik, die verschiedene Teile der Spezifikation behandelt. Von solchen Dateien ist ein ganzer Ordner voll: https://github.com/servo/servo/blob/main/components/layout/f...
Trotzdem ist die Implementierung einer Layout-Engine möglich. CSS ist keine Magie, sondern hat eine Spezifikation, die sich sorgfältig in Code übertragen lässt. Wenn man Menschen, die frustriert sind, weil CSS willkürlich wirkt, solchen Code zeigt, hilft das zu verstehen, dass auch in der Laufzeitumgebung Logik steckt.
Natürlich klickt man da nicht so oft hinein wie bei der Implementierung einer Library, aber in dieser Hinsicht sehe ich keinen großen Unterschied zu etwas wie React.
Erstens sind die zentralsten Teile von Layout, etwa CSS 2, ziemlich schlampig entworfen, und merkwürdige Features interagieren auf merkwürdige Weise miteinander. Dinge wie float und clearance oder Margin Collapsing. Teile dieses Kerns waren wohl dafür gedacht, universell für alle Layout-Modi zu gelten, passen aber zu anderen Modi nicht besonders gut. Zum Beispiel haben margin und padding bei Grid-Elementen keinen klaren Zweck.
Zweitens ist es nicht so gut modularisiert wie JavaScript-APIs. JavaScript-APIs werden oft unabhängig implementiert, aber Layout-Module können auf viele Arten verschachtelt werden und beeinflussen sich daher alle gegenseitig. Neuere Spezifikationen wie Grid versuchen strenger zu sein, doch die grundlegende Schwierigkeit bleibt, dass mehrere Layout-Modi sich die gemeinsame Ressource eines realen 2D-Bildschirms teilen müssen.
Ich kann nicht der Einzige sein, der sich eine Layout-Sprache wünscht, die einfacher als CSS ist, aber die Lehren der letzten 20 Jahre berücksichtigt und das Produkt aus Einfachheit und Ausdrucksstärke maximiert. Ich frage mich, ob es Projekte gibt, die so etwas ernsthaft entwerfen, oder ob alle CSS3 akzeptiert haben und auf ein LLVM-Backend warten – oder einfach zu Plain Text zurückgekehrt sind.
https://github.com/facebook/yoga
Layout muss nicht so komplex sein. Es gibt Dutzende GUI-Frameworks mit einfacheren Layout-Systemen, und für die Anwendungen, die Menschen nutzen, reichen sie aus.
Sieht beeindruckend aus. Vor etwa 15 Jahren habe ich angefangen, einen Headless Browser zu bauen, und ihn einige Jahre lang gepflegt.
Als JavaScript-Interpreter nutzte ich SpiderMonkey, und das DOM habe ich selbst implementiert. Er führte das damals aktuelle JavaScript, AJAX usw. aus, und später habe ich auch eine eigene Flash-Runtime hinzugefügt. Es war ein Projekt, das fast alles machte außer auf den Bildschirm zu zeichnen, und es hat wirklich Spaß gemacht.
Dieses Buch möchte ich unbedingt lesen.
Es freut mich zu sehen, dass Browser-Engineering jetzt offenbar im Trend liegt.
Das Ökosystem ist faktisch ziemlich dürftig und wird nur von Google, Apple und Mozilla definiert. Für die Zukunft würde ich mir mehr unabhängige Browser-Engines wünschen.
Der interessante Bereich sind Post-HTML-UI-/Dokumenttechnologien. Typst aus einem anderen Thread ist so etwas wie ein besseres LaTeX, und auch Markdown hatte großen Einfluss. Es gibt viel Raum für „HTML, aber besser“. Es muss nicht einmal unbedingt ein Markup-Format sein. Typst und React-HTML verwischen die Grenze zwischen Code und Daten, und Jetpack Compose zeigt, wie man mit Kotlins DSL-Fähigkeiten etwas schafft, das wie eine UI-Beschreibung aussieht, tatsächlich aber Code ist.
Dafür müsste man natürlich einen „Browser“ für dieses Format ausliefern oder einen Weg finden, es in bestehenden Browsern darzustellen. Trotzdem kann man nach JavaScript/HTML/WASM kompilieren. Man könnte auch ein portables GUI-Toolkit wie JavaFX verwenden und dabei auch Barrierefreiheit bekommen. Man kann auch beides tun.
Wenn man seine eigene UI-Sprache definiert, kann man vieles ausprobieren, was HTML nicht gut kann. Ein klassisches Beispiel ist die Trennung von Inhalt und Stil. HTML hat es versucht, aber nie wirklich geschafft; XSL:T hat es noch ernsthafter versucht, war aber eine seltsame, rein funktionale Sprache mit XML-Syntax. React ist ziemlich gut darin, JSON in Boxen zu verwandeln, aber das zugrunde liegende Protokoll ist immer nur behelfsmäßig nachträglich angeflanscht, sodass es schwierig ist, darauf nützliche Werkzeuge aufzubauen.
Eine weitere Idee wäre ein Format, das standardmäßig immun gegen XSS ist.
Eine Alternative zu HTML möchte ich allerdings. Wenn ich einen Browser bauen würde, würde ich mich wohl darauf konzentrieren, HTML zu ersetzen, weil ich es nicht ertragen kann; JavaScript würde ich wegen der schweren Runtime ebenfalls ersetzen wollen.
Ein Browser zum Beispiel, der fast keine JavaScript-Runtime hat und nur WASM ausführt, wäre ziemlich witzig.
Ich bin einer der Autoren dieses Buchs. Danke für die netten Worte; wenn es Fragen gibt, kann ich sie beantworten.
Mich interessiert, wie ihr dazu gekommen seid, Python als Sprache für die Browser-Implementierung zu wählen. JavaScript über Node hätte vielleicht eine relevantere Programmiererfahrung vermittelt.
Ein Text, in dem der Autor erklärt, warum Python gewählt wurde: https://browserbook.substack.com/p/why-python
Ein Teil davon scheint Python nach JavaScript zu kompilieren und läuft jetzt auch im Browser, also „im Buch selbst“.
https://browserbook.substack.com/p/compiling-python-to-js
Ich hoffe, dass ich nach dem Lesen zurückkommen und etwas Sinnvolleres dazu sagen kann.
Es begeistert mich wirklich, dass solches Material entsteht.
Browser wirken wie mysteriöse, unentschlüsselbare Blackboxes, und vermutlich möchte auch Google, dass sie so wahrgenommen werden. Aber wenn man die Arbeit und die Ergebnisse von Projekten wie Ladybird sieht, bekommt diese Mauer Risse.
Irgendwann möchte ich selbst einsteigen und dazu beitragen, diesen Burggraben aufzubrechen; dieses Buch scheint ein hervorragender Ausgangspunkt zu sein.
Firefox gibt es bereits. Nur nutzt ihn fast niemand, und wenn Nutzer auf eine Website stoßen, die in Firefox nicht funktioniert, haben sie gelernt, einfach Chrome zu öffnen.
Es mag Spaß machen, in der Hoffnung, den Burggraben aufzubrechen, zu Browser-Engines wie Ladybird beizutragen, aber es ist schwer zu sagen, dass man allein dadurch wirklich dazu beiträgt, ihn aufzubrechen. Ich wüsste gern, was tatsächlich helfen würde.
Im Gegenteil: Die Leute, die an Chrome, Firefox, Safari und Ladybird arbeiten, scheinen alle sehr begeistert darüber zu sprechen, was Browser sind und wie sie funktionieren. Die Welt der Browserentwicklung ist kleiner, als man denkt, und Engineers wechseln auch häufig zwischen Unternehmen; daher dürfte es schwierig sein, irgendeine „Verschwörung“ aufrechtzuerhalten.
Es stimmt allerdings, dass es wirklich an Lehrmaterial fehlt. Deshalb haben wir dieses Buch geschrieben, und insbesondere fehlt auch ein gemeinsames Vokabular, um über das Innenleben von Browsern in Kernphasen wie Layout und Rasterisierung zu sprechen. Chris und ich wollten mit diesem Buch eine solche Grundlage schaffen.
Ich war auf der Suche nach einem interessanten Projekt zum Einstieg und lese dieses Buch bereits mit großer Freude. Mir gefällt besonders, dass der Text so spannend geschrieben ist.
Dieses Comicbuch darüber, wie Chrome funktioniert, ist ebenfalls ein guter Einstieg: https://www.google.com/googlebooks/chrome/med_00.html
Ich lerne gerade die interne Struktur von Browsern, und dieses Buch ist hervorragend.
Es hilft, eine Intuition dafür aufzubauen, wie Browser funktionieren, ohne sich durch Millionen Zeilen Chrome-Code graben zu müssen.
Ich frage mich, ob es einen Promo-Code für HN gibt.
Ich habe früher HTMLUnit [1] zusammen mit Jython [2] zufriedenstellend genutzt und interessiere mich sehr für eine Zukunft, in der sich Teile des Browser-Codes durch Codegenerierung und Verifikationstechniken automatisch erzeugen lassen. Tools wie Playwright/Cypress/Selenium respektiere ich, aber keines davon hat sich für mich je so bequem angefühlt wie HTMLUnit.
[1] https://htmlunit.sourceforge.io/
[2] https://www.jython.org/
Ein gutes Buch. Ich empfehle, Kapitel 9 in zwei Kapitel aufzuteilen.
Der Teil JavaScript mit Duktape ausführen sollte ein eigenes Kapitel sein, und der Teil zur Interaktion mit DOM und Events später ein separates Kapitel.
Die Kapitel werden nach hinten hin länger und behandeln fortgeschrittenere Themen; außerdem empfiehlt es sich, beim Lesen des Buchs auch den Code mitzuverfolgen.