Stranger Than Usual

In wissenschaftlichen Untersuchungenzur Lichtverschmutzung dient die Abkürzung ALAN häufig für nächtliches künstliches Licht (artificial light at night). Leider lesen sich deshalb viele Artikel so, als würden sie sich passiv-aggressiv gegen einen Menschen namens Alan richten […]. »ALAN kann sich auf eine große Vielfalt nachtaktiver Tiere auswirken«, heißt es in einem Aufsatz. »Schon geringe Aktivitäten von ALAN können deutliche biologische Auswirkungen haben«, behauptet ein anderer.

— Ed Yong, Die Erstaunlichen Sinne der Tiere

Stra?e

Ich habe ein Paket bestellt. Der Händler hat es nebst meiner Adresse dem DPD anvertraut. Ich wohne in einer der zahlreichen Straßen, die auf „straße“ enden.

Jetzt kriege ich eine SMS von denen, dass mein Paket bald zugestellt werden soll und ich z.B. den Zustelltermin anpassen kann oder denen erlaube, es irgendwo abzustellen.

Was steht auf der Adresse? „[Soundso]stra?e“. Es ist 2024 und der Deutsche Paketdienst kann nicht mit ß umgehen? Beim Händler kann das Problem nicht liegen: das Label auf dem Paket hat eindeutig ein ß.

Im Ernst 2024. Textencoding ist ein gelöstes Problem!

Erinnerung: Infinite Screaming Generator

In Anbetracht der Wahlergebnisse der Landtagswahl Thüringen 2024 möchte ich gerne noch einmal auf den Infinite Screaming Generator hinweisen, den ich in einem Blogpost im Juni schon erwähnt habe (es gibt den auch als Mastodon-Bot).

Wenn die CDU nicht mit der AfD koalieren möchte, müssen sie meiner Rechnung nach mit dem BSW, den und den Linken koalieren. Für die AfD würde eine Koalition mit CDU oder dem BSW reichen (oder mit der Linken und der SPD, aber das kann ich mir nun wirklich nicht vorstellen).

Das BSW hat sich bisher durch ähnlich populistische Themen wie die AfD positioniert (insbesondere im Bereich Ausländerfeindlichkeit stehen sich die beiden nahe), haben sich aber klar gegen eine Koalition mit der AfD ausgeprochen. Die CDU hingegen…

Auf der einen Seite sprechen sich viele Politiker der CDU immer wieder gegen die AfD aus. Auf der anderen Seite haben einige CDU-Mitglieder immer wieder gezeigt, dass die Brandmauer gegen Rechts aus Stroh besteht. Und die CDU hat ja auch dadurch, dass sie Themen von der AfD immer wieder aufgegriffen hat, die AfD erst gesellschaftsfähig gemacht. Und eine Koalition mit der Linkspartei wird, soweit ich das einschätzen kann, in der CDU als genau so gefährlich angesehen wie eine Koalition mit der AfD.

Meine Hypothese: Innerhalb dieser Woche wird irgendein Thüringischer CDU-Politker etwas von „wir müssen pragmatisch denken“ und „wir müssen dem Wählerwillen folgen“ reden und eine Koalition mit der AfD „nicht kategorisch ausschließen“.

Dann wird es einen riesigen Shitstorm geben und dieser Politiker wird sagen, dass das nicht so gemeint war oder dass seine Worte aus dem Zusammenhang gerissen wurden.

Darüber, wie der kommende Landtag in Thüringen aussieht, mag ich nicht spekulieren. Ich weiß nur eins: Schön wird es nicht.

Straßenlärm in Witten

Seit Ende letzten Jahres wohne ich in Witten. Eigentlich ist meine Wohnung ganz gut gelegen. Aber die kleine Straße, die an dem Haus vorbeiführt hat Tempolimit 50. Dabei ist sie nun wirklich nicht so breit.

Und obwohl meine Wohnung der Straße nicht direkt zugewandt ist und sogar eine Haushälfte entfernt von ihr sitzt, ist der Straßenlärm nachts unerträglich laut. Das war im Winter kein Problem. Jetzt, im Sommer, habe ich aber praktisch immer die Tür zu meinem Schlafzimmer offen. Und meine Güte geht mir das auf die Nerven.

Und der normale Autolärm ist schon schlimm genug. Schlimmer wird es bei nasser Fahrbahn. Dann sind die Laufgeräusche deutlich schlimmer. Auch bin ich schön öfters beim kurz vor dem Einschlafen von einem LKW geweckt worden, der mit hoher Geschwindigkeit über einen kleinen Huckel fährt, den es wohl in der Straße geben muss und dann einen lauten KNALL macht.

Am Schlimmsten sind aber die Autos und Motorräder mit kaputtem Auspuff, die hier regelmäßig mitten in der Nacht mit gefühlt viel zu hoher Geschwindigkeit über die Straße brettern. Da machen die Laufgeräusche keinen Unterschied mehr, der Motor ist hier einfach lauter als bei einem normalen Auto, wenn man das Ohr direkt daran halten würde.

Nun ist natürlich die Frage: Warum ist auf dieser Straße überhaupt 50 erlaubt? Die ist nun wirklich nicht so breit. Die könnte auch gut 30 sein. Stellt sich heraus: Die Stadt Witten hat da schon einen Plan. So 20% eines Plans. Sie wollten auch Input von Bürgern der Stadt. Dummerweise haben sie dafür nicht genug Marketing gemacht, an mir ist das glatt vorübergegangen. Von Juni bis Juli konnte man Vorschläge einreichen. Ich habe diese Seite erst ende Juli entdeckt. Immerhin scheint meine Straße so oder so im Fokus zu liegen.

Ich schaue Mal, was daraus wird. Die wollen jetzt einen Plan erarbeiten. Der nächste Plan danach kommt erst 2019, also hoffe ich stark, dass dieser hier was taugt. Und einfach nur die Höchstgeschwindigkeit runtersetzen (wobei auch auch befürchte, dass die das nur nachts machen wrden) hilf halt nicht. Man muss den Fahrern auch das Gefühl vermitteln, dass man nicht so schnell fahren kann.

Man könnte zum Beispiel einen Radweg ergänzen. Momentan ist für Fahrräder explizit erlaubt, den Gehweg zu verwenden. Ein angehobener Radweg könnte die Straße so weit verkleinern, dass die Autos nicht mehr 50 fahren können. Und besser für den Radverkehr (und die Fußgänger) wäre das auch.

Die dreifache Hölle der Nextcloud-Konfiguration

Ich betreue auch eine kleine Nextcloud-Instanz. Eigentlich ganz schön, so kommt man hier und da um große Anbieter wie Google herum.

Nextcloud hat auf der Admin-Übersichtsseite eine nette Funktion, die einem sagt, welche Konfigurationen alle falsch aussehen. Aber wenn die so falsch sind, warum kann Nextcloud die nicht selber korrigieren? Das liegt daran, dass diese Konfigurationen außerhalb von Nextclouds Einflussbereich liegen.

So beschwert es sich über einige Fehler in der nginx-Konfiguration. Da fängt es schon an. Ich brauche eine ziemlich komplizierte nginx-Konfiguration, um nextcloud überhaupt zum Laufen zu kriegen. Ein „leite einfach alles an Nextcloud weiter und lass Nextcloud entscheiden, was es macht“ reicht nicht. Ich muss einen Haufen Routen konfigurieren, Sicherheitsheader, Umleitungen, das ganze Programm.

Gut, das muss ich für z.B. dieses Blog hier auch machen. In diesem Blog gibt es aber einen wesentlichen Unterschied: Es ist nur ein Haufen Dateien, da muss man nginx halt sagen, was es damit machen soll. Und das ist auch nicht so schwierig, das läuft wesentlich einfacher als die Konfiguration für Nextcloud. Man könnte fast sagen, Nextcloud ist keine abgeschlossene Software, sondern ist für Grundfunktionalitäten von nginx (oder apache, den ich aber nicht benutze) abhängig.

Warum ist das so? Ich weiß es nicht, aber ich habe eine Vermutung. Nextcloud ist in PHP geschrieben, und PHP hat so eine seltsame Abhängigkeit zur FastCGI-Schnittstelle eines Webservers. Das ist eigentlich auch keine Entschuldigung, eigentlich müsste Nextcloud trotzdem seinen eigenen Kram regeln können. Tut es aber nicht. Stattdessen verlangt es sogar, dass ich auch noch in der PHP-Konfiguration herumschraube, damit es ordentlich läuft. Da stehen dann so Sachen drin, wie viel Arbeitsspeicher es maximal verwenden darf, oder timeouts für Requests.

Man stelle sich das mal bei einer anderen Scriptsprache vor. Wenn ich zum Beispiel bei Python erst einmal in einer globalen Konfigurationsdatei festlegen müsste, dass es mehr als 128MiB Speicher verwenden darf. Aber damit hört es natürlich nicht auf. In der PHP-Konfiguration gibt es nicht eins, nicht zwei, sondern drei Verzeichnisse mit Konfigurationsdateien. Gut, apache2 wird es nicht sein, ich nutze ja nginx. cli wohl auch nicht, das wird vermutlich nur für Kommendizeilenprogramme verwendet. Also bleibt eigentlich nur fpm.

Nur leider bringt das nichts. Nextcloud bleibt bei seinen 128MiB Speicher. Selbst wenn ich die Limits auch in den anderen Dateien anpasse. Online findet man jede Menge zu den diversen Problemen, nichts davon hilfreich. Die Dokumentation (sogar in der Warnung verlinkt) geht auf diese Details überhaupt nicht ein.

Nun will ich ja nicht sagen, dass diese Einschränkungen nicht wichtig sind. Aus Sicherheitsgründen oder so. Aber wenn es dafür notwendig ist, diese Einstellungen über drei verschiedene Programme hinweg zu machen, während es grundsätzlich auch möglich wäre, das alles in einem Programm zu machen, dann ist beim Design der ganzen Sache irgendwo etwas schief gelaufen.

Ich habe jetzt mal wieder mehrere Stunden investiert und immer noch sind diese blöden Warnungen da, und niemand kann mir auch nur erklären, was die meisten davon eigentlich bedeuten. Also bleiben die jetzt erst einmal. Und das wirklich Nervige: eigentlich wollte ich nur herausfinden, warum seit einiger Zeit Bilder nicht mehr in nextcloud selber angezeigt, sondern mit immer direkt zum Download angeboten werden, wenn ich auf sie klicke.

Der Gegenangriff gegen Single Page Applications

Ein altes Thema in diesem Blog, häufig von Rants begleitet, ist der übermäßige Einsatz von Javascript auf Websites. Insbesondere wenn Grundfunktionen der Website nicht mehr gehen, wenn man kein Javascript aktiviert hat. So habe ich mich zum Beispiel 2010 auf meinem alten Blog darüber aufgeregt, dass bei einer oder mehreren Websites Grundfunktionen wie die Seitennavigation, der Login oder das Herunterladen von Dateien nur mit Javascript. Oder die Suchfunktion Oder, im selben Jahr, ein Mini-Rant, ohne in die Details zu gehen.

Als ich dann 2012 dieses Blog in Ruby on Rails umgesetzt habe, habe ich extra darauf geachtet, überhaupt kein Javascript zu verwenden. Damals waren alle Rails-Tutorials Javascript-lastig. Nicht extrem, man hätte die Seite noch benutzen können, aber es war da. Ich wollte das nicht. 2020, als ich die auf Rails basierende Software durch einen static site generator ersetzt habe, habe ich das beibehalten.

Dazwischen habe ich eine ganze Menge über Webentwicklung gelernt. 2015 habe ich angefangen, in Hamburg zu arbeiten. Ich habe am Backend und am Frontend gearbeitet. Und musste auch selber Javascript schreiben. Zuerst für eine Website, die für das meiste an Javascript einen Fallback hatte. Später dann an React-Anwendungen, die keinen Fallback hatten. Mea culpa. Ich war Teil des Problems geworden. Aber es war mir schlicht nicht möglich, meine Kollegen zu überzeugen, dass das eigentlich Wahnsinn ist. Obwohl mir das durchaus bewusst war, wie dieser Blogpost von 2017 zeigt.

Warum so viel Javascript?

Warum? Warum hat sich übermäßiges Javascript, insbesondere Single Page Apps (SPAs) so weit durchgesetzt? Hier hat jemand letztes Jahr mal zusammengefasst, wie sich das aus seiner Perspektive entwickelt hat. Ich kann den Artikel empfehlen, und auch ein paar andere Artikel auf der Seite, auf die ich später zurückkomme. In einer Sache bin ich aber anderer Meinung als der Autor. Der geht davon aus, dass der kontinuierliche Aufstieg von SPAs auf gezieltes Marketing wider besseren Wissens passiert ist.

Ich sehe das nicht ganz so von bösen Absichten durchdrungen. Ich bin einfach der Meinung, wir, als Entwickler, sind einer Art kollektivem Stockholm-Syndrom zum Opfer gefallen (ja, ich weiß, das Stockholm-Syndrom gibt es wahrscheinlich nicht wirklich. Aber es ist eine schöne Geschichte und eine passende Metapher). Wir stecken halt bis zum Hals im JS-Code mit allen Probleme, die das bringt, wir kommen nicht ohne weiteres mehr heraus, aber hey: schaut euch dieses Tool an, das alles viel einfacher macht!

Ich will Javascript nicht die Existenzberechtigung absprechen. Eine Landkartenseite wie OpenStreetMap? Ein Videokonferenztool? Ein Spiel? Klar, das braucht Javascript? Ein Webshop? Höchstens ein bisschen, zum Beispiel um im Checkout das Leben einfacher zu machen (und auch das sollte einen Fallback haben). Aber ein Blog? Eine Newsseite? Ein Webcomic? Eine Rezepte-Seite? All das braucht kein Javascript.

A New Hope

Deswegen hat es mich sehr gefreut, dass ich in der letzten Monaten immer wieder Artikel gegen übermäßigen Einsatz von Javascript gefunden habe. Und in der letzten Woche vier Artikel vom oben erwähnten Blog, wo der Autor ordentlich mit SPAs aufräumt. Insbesondere geht es da auch um öffentliche Websites in den USA (Kalifornien, um genau zu sein), wo Leute SNAP benefits beantragen können oder so (so eine Art Sozialhilfe). Dummerweise ist die offizielle Seite dazu etwa 25 fucking Megabyte groß, der größte Teil davon… natürlich Javascript. Auch in Kalifornien gibt es Gegenden mit nur langsamem Internetzugang, und 20 Megabyte JS sind für schwachbrüstige Geräte (Leute, die auf Sozialhilfe angewiesen sind haben i.d.R. keine high-end-Smartphones) auch ein ganzer Happen. Ergebnis: Die Seite braucht knapp 30 Sekunden um zu laden, eine vergleichbare Seite einer Drittpartei kommt auf vier Sekunden.

Mir machen diese Artikel Hoffnung, dass der Wind sich so langsam dreht. Nur ein bisschen Hoffnung, nicht viel. Vor knapp neun Jahren gab des den Talk The Website Obesity Crisis. Jetzt haben wir die oben genannte 25MiB-Seite und wie dieser aktuelle Artikel über Javascript-Bloat zeigt, ist die Situation insgesamt auch nicht viel besser.

Ach ja: Bei dem Bookshop, an dem ich entwickelt habe, haben wir stets versucht, das Javascript klein zu halten. Es ist nicht wirklich gelungen, weil wir einige sehr alte Browser unterstützen mussten, aber wir sind bei um die 200kiB geblieben. Es geht nicht in meinen Kopf herein, was man machen muss, um auf 25MiB zu kommen. Wirklich nicht.

Gründe gegen SPAs (oder überflüssiges Javascript auf nicht-SPAs)

Naja, jedenfalls ist das jetzt die Gelegenheit für mich, auch mal meinen Senf dazuzugeben und zu erläutern, welche Probleme man sich mit SPAs im Speziellen oder zu viel Javascript im Allgemeinen aufhalst.

Zuerst ist da natürlich die Größe, wie schon oben genannt. Trotz aller Beteuerungen, dass SPAs viel effizienter seien, weil sie für den Inhalt ja nur JSON nachladen müssen und nicht das ganze HTML immer und immer wieder, sind SPAs in der Regel so groß, dass man tausende Seiten anschauen muss, bevor sie sich lohnen.

Dann ist da die Archivierbarkeit. SPAs können zum Beispiel vom internet archive viel schlechter archiviert werden, weil sie dynamisch Daten nachladen. Das ist den meisten Betreibern natürlich egal. Was denen aber wichtig ist: sie wollen durch Suchmaschinen gefunden werden. Das funktioniert mittlerweile auch für SPAs, aber bei weitem nicht so gut wie für Websites, die ihren Inhalt direkt ausliefern.

Dinge, die der Browser schon kann und die in SPAs mühsam erneut implementiert werden müssen

Da wäre zunächst Routing: Normalerweise ist Routing einfach: Man schreibt ein <a>-Tag, verpasst ihm ein href-Attribut, fertig. Auf SPAs muss man aber zusätzlich noch:

  • alle Klicks auf (interne, und nur interne) Links abfangen, damit der Browser die Seite nicht neu lädt
  • die URL der Seite anpassen, ohne dass der Browser die Seite neu lädt
  • den Inhalt der Seite ändern
  • nach oben scrollen, damit die User den Anfang der Seite sehen und nicht die Position, wo man bisher war
  • oder gegebenenfalls zum richtigen Anker auf der Seite springen, falls die URL ein Fragment (#) hat
  • wenn die Seite neu geladen wird, in die URL schauen um den richtigen Inhalt anzuzeigen

Bevor jemand damit kommt, dass man diese Sachen sonst serverseitig machen muss: Erstens muss man die meisten davon nicht serverseitig machen, weil sie clientseitig laufen und das normalerweise der Browser erledigt. Zweitens muss man die Teile, die man doch serverseitig machen muss (unterschiedlichen Inhalt über unterschiedliche URL-Pfade ausliefern) trotzdem machen, weil man bei SPAs üblicherweise einen API-Server im Hintergrund hat, von dem die eigentlichen Inhalte kommen.

Das ist natürlich angenommen, man möchte es den Usern ermöglichen, eine normale Website-Erfahrung zu haben, wo u.a. auch die Navigation mit den zurück/vorwärts-Buttons des Browsers funktioniert, man zu Abschnitten innerhalb der Seite springen kann und Links auf einzelne Seiten hat, die man auch mit anderen teilen kann. Wenn man sich diese Mühe nicht macht, haben die User eine erheblich eingeschränkte Version einer normalen Website. In einem Fall haben mir Kollegen in einem anderen Team auch mitgeteilt, sie könnten keine direkten Links auf Seiten machen, weil sie dafür den Webserver so einstellen müssten, dass er für verschiedene URLs genau denselben Inhalt ausliefert. Nein, wirklich!

Besonders aufgefallen sind mir auch, wie schon oben verlinkt Links, die nicht an <a>-Tags hängen.

Andere Dinge, die man nachimplementieren muss:

  • Formulare (unterschätzt das nicht, da gibt es viele Fallstricke)
  • Requests an den Server im Allgemeinen
  • eventuell eine Ladeanzeige („spinner“)

Diese Liste ist nicht vollständig, es gibt noch mehr. Routing ist aber definitiv der wichtigste und umständlichste Punkt.

Komplexität

Komplexitätssucht ist eine Art Berufskrankheit unter Softwareentwicklern. Um Rich Hickey zu zitieren:

I think programmers have become inured to incidental complexity… when they encounter complexity, they consider it a challenge to overcome, rather than an obstacle to remove. Overcoming complexity isn’t work, it’s waste.

Manche Komplexität lässt sich nicht entfernen. Manche Komplexität würde sich entfernen lassen, ist es aber Wert, mit ihr umzugehen (ich, als Rust-Fan, sehe Rust in der zweiten Kategorie). Aber vieles an Komplexität, die wir uns antun, ist unnütz, nervig und schädlich.

SPAs sind ein schönes Beispiel dafür. Der ganze Krams, den ich oben über das Reimplementieren von Browserfunktionalitäten geschrieben habe? Unnütze Komplexität. Wo kommt in SPAs sonst noch vermeidbare Komplexität her? Hier nur eine kurze Auswahl:

  • manuell geschriebene HTTP-Requests und das Parsen der Ergebnisse (und sanity-checks, ob die Antworten das enthalten was man erwartet. Kann man auch lassen, aber dann hat man halt später Spaß mit komischen Fehlern wenn mal etwas nicht passt)
  • Behandeln von Sonderfällen für ältere Browser (polyfills)
  • Abhängigkeiten auf Bibliotheken von Dritten, insbesondere Frameworks wie React (jede Abhängigkeit bedeutet einen erhöhten Wartungsaufwand. Und man sollte besser alle Updates zeitnah mitnehmen, oder man kommt irgendwann an den Punkt, wo man ein neues Update braucht, es aber nicht installieren kann, weil man vorher mehrere Jahre Update nachholen muss)
  • Fehlerbehandlung

Dazu kommt Komplexität bei den Entwicklertools. Da wären zunächst die Entwicklertools selber. Man braucht

  • NPM (für die oben genannten Abhängigkeiten)
  • einen Linter (Javascript ist so furchtbar, dass das, im Gegensatz zu anderen Sprachen, mehr als nur ein nice-to-have ist)
  • etwas wie Webpack, um das Ergebnis irgendwie zusammenzufügen
  • einen Typescript-Compiler, wenn man Typsecript verwendet (was zu empfehlen ist, weil man damit Fehler vermeiden kann, die in so einer komplexen Umgebung schnell passieren)
  • etwas wie Babel, um Polyfills für veraltete Browser einzufügen, die man unbedingt noch supporten muss

Es ist ein bisschen so, als ob man beim Hausbau beim Fundament gepfuscht hat, das Haus sich schon während des Baus zur Seite neigt, man aber einfach weiter baut und drumherum jede Menge Gerüste und Stützen hinstellt, damit das Haus nicht zusammenbricht, anstatt von vornherein für ein vernünftiges Fundament zu sorgen. So ein bisschen wie der Schiefe Turm von Pisa, wo man noch Jahrhunderte nach dem Bau mit den Folgen zu kämpfen hat. Nur dass eine Webapp nicht zu einer beliebten Touristenattraktion wird.

Was sind die Nachteile von Komplexität?

  • Wartung: mehr Komplexität macht Wartung und Weiterentwicklung schwieriger und damit teurer
  • Stabilität: mehr Komplexität macht Software anfälliger für Fehler, jeder Fehler kann größere Auswirkungen haben. Bonuspunkte: sobald auch nur eine Javascript-Datei nicht geladen werden kann, blockiert oft die ganze Seite
  • Security: was für die Stabilität gilt, gilt auch für die Sicherheit: je unübersichtlicher, desto eher schleicht sich ein Fehler ein, der ernsthafte Konsequenzen hat
  • Performance: Mehr Komplexität bedeutet mehr Code, d.h. es muss mehr heruntergeladen werden und auch die Ausführung ist langsamer

Vermeintliche Lösungen

Eine beliebte Lösung für ein paar der Probleme, insbesondere das mit der Archivierbarkeit und der Suchmaschinenfreundlichkeit: Wir rendern die Seite serverseitig und lassen sie dann clientseitig als SPA laufen. Das geht schon fast in die richtige Richtung, wird aber häufig durch zwei Probleme heruntergezogen: Erstens kann man die Seite dann ohne Javascript trotzdem nicht nutzen (bzw. muss man trotzdem eine ordentliche Menge an Javascript laden, was den vermeintlichen Größenvorteil von SPAs endgültig zunichte macht), zweitens ist das für die Entwickler eine Menge Arbeit, weil sie die Seite gleich zwei Mal entwickeln müssen.

Das Ergebnis ist, dass so etwas meist eher halbherzig gemacht und für manche Seiten auf der Website komplett vergessen wird. Die Lösung dafür wiederum ist etwas, was die Marketingabteilung „isomorphic Javascript“ genannt hat. Da soll man dann denselben Code Server- und clientseitig laufen lassen können. Der Nachteil: noch mehr Komplexität.

Mal ganz abgesehen davon, dass Javascript eine furchtbare Sprache ist, die ich nicht auch noch serverseitig sehen will, gibt es einen ganzen Haufen von Dingen, die auf dem Server grundsätzlich anders laufen als im Client. Ich habe einmal mit Nuxt gearbeitet. Das ist quasi eine isomorphic Javascript-Version von vue. Der ganze Code bestand aus Ausnahmen, wo man dann doch darauf achten musste, wo man serverseitig und wo man clientseitig arbeitete. Man musste überall höllisch aufpassen, dass man nicht aus Versehen irgendwelche serverseitigen Secrets leaked. Das ist eine Sicherheitslücke, die nur darauf wartet, implementiert zu werden.

Alternativen

Denken wir mal konstruktiv: Was sollten wir denn machen? Erst einmal: Keine SPAs, macht klassische Websites wo immer möglich. Dann gibt es da das Konzept des „unobtrusive Javascript“: Javascript, dass Funktionen ergänzt bzw. die Benutzbarkeit erhöht, wobei es aber trotzdem noch möglich sein muss, die Seite ohne Javascript zu verwenden (dann gehen halt schlimmstenfalls ein paar Komfortfunktionen verloren).

Verallgemeinert ist das im Konzept Progressive Enhancement. Das läuft auf dasselbe hinaus, bezieht aber auch das Styling (CSS) mit ein. Die Idee: Eine Seite sollte komplett ohne Styling schon benutzbar sein (z.B. auch in einem textbasierten Browser wie Links). Das Styling kommt obendrauf, um die Seite schöner und vielleicht auch ein bisschen übersichtlicher bzw. lesbarer zu machen. Erst dann kommt das Javascript obendrauf, für Komfortfunktionen.

Dazu gibt es einen schönen Artikel der britischen Regierung. Als Website-Beispiel kann ich zum Beispiel dieses Blog hier nennen. Aber es gibt auch wichtige Websites, die das richtig machen: Wie ich letzten Monat festgestellt habe funktioniert zumindest das Lesen von Wikipedia-Artikeln sehr gut auch ohne CSS. Als Negativbeispiel kann man leider fast jede größere Website nennen.

Ausklang

So, das war wieder ein Artikel der deutlich länger geworden ist als ursprünglich geplant. Also spare ich mir den anderen, nur entfernt relevante Kram, den ich sonst noch im Kopf habe. Was können wir also mitnehmen?

  • SPAs sind für die meisten Anwendungsfälle eine Scheißidee
  • macht eure Websites nach dem Progressive Enhancement-Prinzip, nutzt Javascript nur, um Komfortfunktionen hinzuzufügen oder dann, wenn ihr etwas machen wollt, was wirklich nicht ohne Javascript geht
  • hoffen wir mal, dass die Tage der SPAs gezählt sind (aber ich glaube nicht wirklich daran)

Stempel mit Photopolymer machen

1996 gab es in der Sendung mit der Maus eine Sachgeschichte, wie man selber Stempel herstellt. Und zwar mit Hilfe von lichtempfindlichen Stempelplatten. Auch bekannt als Photopolymerplatten (unter dem Namen habe ich sie dann gekriegt).

Am Ende der Sendung (nicht in dem oben verlinkten Video, sondern in der ursprünglichen Version) hat Armin Maiwald dann noch gesagt:

Und wenn ihr das jetzt mit den ganzen 16 Schritten nicht mitgekriegt habt, schreibt uns 'nen Brief […]

Offensichtlich hat mich das damals interessiert, denn meine Eltern haben einen Brief geschrieben. Das ist jetzt 28 Jahre her, und wir sind nie dazu gekommen, die Stempel zu machen. Bis zu diesem Jahr.

Vor ein paar Wochen ist mir das mit den Stempeln wieder eingefallen. Netterweise sind die meisten Sachgeschichten ja mittlerweile auch online zu finden (siehe das Video, das ich oben verlinkt habe). Den Brief von der Maus hat meine Mutter, gut organisiert wie sie ist, auch gefunden und für mich eingescannt. Also los! Ich habe hier dokumentiert, was ich gemacht habe und wo ich von der Anleitung abgewichen bin, aber die Anleitung (sowohl das Video als auch der Brief) sind auch heute noch gut zu gebrauchen.

Schritt 0: Material besorgen

Als erstes muss man das Material besorgen. Folgendes Material/Werkzeug braucht man:

  1. eine lichtempfindliche Stempelplatte (ich habe das heute unter dem Namen „Photopolymerplatte“ gefunden)
  2. eine Spezialfolie zum Einfärben von Kopien (habe ich unter dem Namen „Transferfolie“ gefunden)
  3. einen Laserdrucker oder einen klassischen Kopierer (Tintenstrahl geht nicht, und ich habe mit unterschiedlichen Laserdruckern unterschiedlich gute Erfahrungen gemacht).
  4. einen Stempelgriff oder einen Holzklotz, an dem man die Stempelplatte hinterher festmacht
  5. eine Plexiglasfläche irgendeiner Art (ich habe einen Deckel einer alten CD-Hülle genommen)
  6. ein Papp/Kartonrohr, etwa 30cm lang (kann man auch selber aus einem DIN A4-Blatt basteln)
  7. ein Bügeleisen
  8. einen Fön
  9. einen weichen Pinsel oder eine ausrangierte Zahnbürste
  10. Doppelseitiges Klebeband

Ich fand es nicht leicht, an die Photopolymerplatten und die Spezialfolie zu kommen. Der Brief von der Maus hat am Ende eine Liste wo man so etwas bekommt, aber das war vor 28 Jahren. Die meisten der Läden haben mittlerweile dicht gemacht. Klassische Läden (auf neudeutsch „brick and mortar“) habe ich bei mir in der Gegend nicht gefunden. Am Ende habe ich einen Versandladen in Österreich gefunden. Da waren die Versandkosten natürlich entsprechend hoch. Vermutlich hätte ich das auch günstiger bekommen können, wenn ich mich nicht geweigert hätte, das bei Amazon zu kaufen.

Schritt 1: Ein Motiv

Im Mausoriginal hat Armin eine Blume gemalt und die dann kopiert. Das Schöne an dem Verfahren mit dem Photopolymer ist aber, dass es ziemlich einfach ist, Computergrafiken als Stempel zu nehmen. Zum Beispiel das fliegende Spaghettimonster. Oder Napstablook, von dem ich ja letzts Jahr eine SVG-Datei gemacht habe. Im Napstablook-SVG habe ich dann noch die äußeren Linien etwas dicker gemacht. Hätte aber wahrscheinlich auch so funktioniert:

Ein traurig aussehender Geist

Eine stilisierte Darstellung des fliegenden Spaghettimonsters

Das Motiv sollte in schwarzweiß sein. Dann muss es mit einem Laserdrucker ausgedruckt werden. Der Laserdrucker-Teil ist wichtig, weil sonst die Übertragungsfolie nicht funktioniert.

Schritt 2: Die Folie

Um das Motiv auf die Transferfolie zu kriegen, muss es aufgebügelt werden. Dazu erst einmal das Bügeleisen vorheizen, auf die Temperatur für Baumwolle (kein Dampf!).

Dann ein bisschen Papier (Zeitungspapier) unterlegen, die Kopie da drauf, ein Stückchen der Folie ausschneiden und auf mit der farbigen Seie (bei mir: rot) nach oben auf das Motiv legen. Dann noch ein Papier darüber (um das Bügeleisen zu schützen). Die Folie sollte etwas größer als das Motiv sein und das Motiv ganz abdecken.

Dann Bügeln. Dabei feste drücken. Am Ende ein bisschen warten, bis sich Papier und Folie wieder abgekühlt haben. Dann die Folie vorsichtig von dem Papier trennen. jetzt sollte die Folie dort, wo der schwarze Teil von dem Motiv war, durchsichtig sein und ansonsten immer noch farbig und undurchsichtig. So sah es bei mir aus:

Links: ein rote, undurchsichtige Folie, die in er Mitte einen durchsichtigen Teil in der Form des fliegenden Spaghettimonsters hat. Rechts: ein rot gefärbter Ausdruck des fliegenden Spaghettimonsters

Schritt 3: Die Belichtung

Das Photopolymer funktioniert so: Dort, wo UV-Licht hinfällt, härtet es aus. Dann kann man den Rest wegwaschen. Um eine brauchbare Belichtung hinzukriegen, gibt es verschiedene Methoden. Ich habe im Internet einige gefunden. Wenn man eine passende UV-Lampe hat (fragt mich nicht, was genau für eine), kann man die nehmen. Andere Quellen meinen, man müsse das Werkstück für eine halbe Minute oder so direkt in die SOnne legen. Ich halte mich aber an das, was in dem Brief von der Maus steht, das hat bei mir gut funktioniert. Dafür brauchen wir erst einmal eine Belichtungsröhre.

Die Belichtungsröhre besteht aus einem Plexiglasstück (in meinem Fall der Deckel einer alten CD-Hülle) und einer Kartonröhre. Im Mausvideo haben die die Röhre selber gebastelt. Im Haus meiner Mutter, wo ich zu besuch war, weil ich keinen Drucker, Bügeleisen oder Fön habe, hat sich noch eine fertige Pappröhre gefunden. Das ist meine Belichtungsröhre:

Auf einem CD-Hüllendeckel ist mit Tesafilm eine Pappröhre aufgeklebt

Die nächsten Schritte sollten in einem eher dunklen Raum durchgeführt werden. Muss nicht stockfinster sein, aber es sollte kein direktes Sonnenlicht und nur wenig indirektes Sonnenlicht hereinscheinen. Dann die Photopolymerplatte aus der Verpackung holen, ein Stück abschneiden (geht mit Schere) dass ungefähr so groß ist wie das Folienstück. Den Rest Photopolymer wieder einpacken, die Schutzfolie vom Polymer abziehen, die Transferfolie mit der roten Seite nach unten auf die Seite der Polymerplatte legen, wo gerade eben noch die Schutzfolie war und die Belichtungsröhre drüber.

Dabei darauf achten, dass der Motivteil der Transferfolie vollständig auf der Polymerplatte liegt. Gegebenenfalls auch festkleben, damit nichts verrutscht. Wichtig ist auch, dass die rote Seite nach unten ist, sonst ist das Ergebnis am Ende seitenverkehrt. Ich habe das beim fliegenden Spaghettimonster falsch gemacht, aber da ist es auch nicht so wichtig. Bei den Stempeln, die ich vorher gemacht habe, und wo es wichtig war, habe ich es richtig gemacht.

Die Belichtungsröhre dann nach draußen stellen. Es darf dabei kein direktes Sonnenlicht auf das Polymer fallen, aber die Belichtungsröhre muss freien Blick auf den Himmel haben (z.B. sollten keine Blätter eines Baumes im Weg sein).

Die Belichtungszeit ist unterschiedlich. Im Brief der Maus ist eine ausführliche Tabelle, wie lange bei welchem Wetter zu welcher Tageszeit und zu welcher Jahreszeit mindestens belichtet werden muss. Je nach Wetter und Jahreszeit geht es auch einfach nicht.

Belichtungszeit in Minuten Frühling & Herbst Sommer Winter
Mittag früh & Nachmittag Mittag früh & Nachmittag Mittag früh & Nachmittag
strahlender Sonnenschein 25 40 15 20 35 45
heiter 35 45 20 25 45 60
wolkig 45 60 25 30 60 75
stark bewölkt und düster 90 nope 40 60 90 nope

Die Mindestzeit sollte eingehalten werden, ein bisschen länger ist nicht schlimm. Eine deutlich zu lange Belichtungszeit würde aber dafür sorgen, dass die Kanten des Stempels verschwimmen.

Schritt 4: rituelle Säuberung

Nach der Belichtung die Polymerplatte von Turm und Folie trennen und mit einer weichen Bürste und etwas Seifenwasser gründlich säubern. Dabei sollten alle nicht ausgehärteten Reste des Polymers weggewaschen werden. Das Zeug ist ungefährlich für die Hände, es sei denn, man ist allergisch. Am Ende sollte keine Schmiere mehr da sein. Die Platte ist aber vermutlich noch etwas klebrig.

Als nächstes das Teil 15 Minuten lang trockenföhnen. Ich habe es kürzer gemacht und es dafür noch ein wenig zum trocknen bzw. Nachhärten in die Sonne gelegt (andere Quellen im Internet haben das empfohlen). Was besser ist, kann ich noch nicht sagen, aber für mich hat es funktioniert. Das Ergebnis sieht bei mir so aus:

Eine Plastikplatte auf der als Relief das fliegende Spaghettimonster zu sehen ist.

Schritt 5: Der Stempelgriff

Jetzt muss der Stempel nur noch irgendwie greifbar gemacht werden. Dazu braucht man einen Stempelgriff oder ein Holfzklötzchen in passender Größe, idealerweise ein bisschen abgeschmiergelt, damit man sich keine Splitter zieht.

Doppelseitiges Klebeband auf die Stempelplatte kleben (auf der ebenen Seite offensichtlich, nicht die Seite mit dem Relief). Noch eine zweite Schicht doppelseitiges Klebeband (nicht vergessen die Schutzfolie von der ersten Schicht zu entfernen), damit der Stempel ein bisschen federt. Erst dann die Stempelplatte möglichst genau auf den eigentlichen Stempel zuschneiden (dabei insbesondere noch Ränder abschneiden, die auch belichtet wurden, obwohl sie nicht Teil des Motivs sind). Am Ende dann den Stempel an den Griff kleben. Fertig ist der Stempel:

Stempel mit fliegendes-Spaghettimonster-Motiv, mit der Stempelfläche nach oben. Es ist noch keine Farbe am Stempel.

Schritt 6: Alles stempeln, was nicht bei drei auf den Bäumen ist

Drei Stempelabdrücke des fliegenden Spaghettimonsters in schwarzer Farbe auf weißem Papier. Daneben mit dem Motiv nach oben der dazugehörige Stempel

Vier Stempelabdrücke von Napstablook in blauer Farbe auf weißem Papier. Daneben mit dem Motiv nach oben der dazugehörige Stempel

Fazit

28 Jahre, und endlich ist es was geworden. Und es hat erstaunlich gut funktioniert. Ich habe auch noch ein paar andere Stempel gemacht, z.B. einen für die Spielleiterin einer meiner Rollenspielrunden, mit dem Wappen des (mittlereile sein tausenden von Jahren untergegangenen) Elfenreiches.

Man kann die Belichtung natürlich auch anderes machen als mit dieser Transferfolie. Aber das ist halt die Methode, die bei der Maus verwendet wurde. Als ich nach dem Namen des Erfinders (der sowohl in dem Brief als auch in der Sachgeschichte genannt wurde) habe ich außerdem dieses Patent gefunden.

Das Patent ist mittlerweile abgelaufen. Warum der das überhaupt patentiert hat weiß ich nicht, weil im Patent explizit erwähnt wird:

Die Erfindung erlaubt es, auch Privat­ personen, Schulkinder, Heimwerker o. dgl. in die Lage zu versetzten, mit einem einfachen Materialsatz von einem grafischen Positiv Stempel oder andere Reliefreproduk­ tionen oder Flächenmuster herzustellen.

Also nicht gerade die Gruppe von Leuten, die Patentgebühren zahlen würde. Ich vermute mal, der hat das einfach gemacht, weil er stolz war, dass er auf die Idee gekommen ist. Gönne ich ihm.

Digitale Polychromie

Es ist ja mittlerweile allgemein bekannt, das antike griechische Statuen nicht weiß (oder welche Farbe der Stein aus dem sie gemacht waren halt hatte), sondern bunt bemalt waren. Wikipedia nennt das „antike Polychromie“. Die Farbe ging dann im Laufe der Zeit ab, kann aber von Resten heute noch rekonstruiert werden.

Später haben die Menschen dann Skultpuren im antiken Stil angefertigt und sie unbemalt gelassen, weil das ihrer Vorstellung der Antike entsprach und sie dann damit auch irgendwelche Ideale verbinden. Später dann, im 19. Jahrhundert, begannen Archäologen damit, die Farben zu rekonstruieren, heutzutage machen sie das immer noch, teils mit modernster Technologie.

Trotzdem ist das Bild der Antike in der Populärkultur geprägt von weißen Marmorstatuen und ~Fassaden. Man nehme nur Filme, die in der Antike spielen, oder auch einfach Asterix-Comics. Dass diese ganzen Sachen bunt bemalt werden, wird eher als „Fun Fact“ verwendet. Im Internet meist in Listen wie „10 misconceptions you have about ancient Rome“.

Ich frage mich, was wohl passiert, wenn die Leute in ein paar hundert Jahren unsere Webseiten wieder aus der Versenkung hervorholen. Da sind dann natürlich viele Daten verloren gegangen, die Browser von heute laufen nicht mehr, die Spezifikationen für CSS und HTML sind verloren. Alles was man hat sind Textdateischnipsel mit Markup. Und weil sich die Leute nach einer Zeit sehnen, in der Computer noch einfach waren, sehen sie, dass das wohl einfach Text war, schwarz auf weiß, mit ein paar Auszeichnungen für Überschriften, Hervorhebungen, Tabelle, Absätze etc.

Und dann bauen sie Websites im „antiken“ Stil nach, um die Ideale von damals wieder aufleben zu lassen. Bis dann jemand sich die anderen Daten drumherum anschaut. Die, die erst nur für Datenmüll gehalten wurden: „Hey Leute, diese CSS-Dateien! Das ist gar kein Datenmüll! Das sind Layout-Anweisungen! Wir haben das rekonstruiert, die meisten Websites waren nicht schwarzweiß, von oben nach unten, sondern bunt und mit kompliziertem, teils auch horizontalem Layout!“

Als Beispiel, hier einmal die Wikipedia-Seite zu antiker Polychromie mit CSS und ohne CSS (CC BY-SA 4.0 Wikimedia Foundation):

Screenshot eines Wikipedia-Artikels, oben sind Links zum Bearbeiten und ein Suchfeld, links ist ein Navigationsmenü, der restliche Platz wird vom Artikel eingenommen

Screenshot eines Wikipedia-Artikels, ohne CSS-styles. Die ganze sichtbare Seite wird vom Artikel eingenommen, oben sind aber zwei Links um zur Suche bzw. zur Navigation zu springen

Microfiction

Das Internet is ein riesiger Ort, und obwohl es eine Menge hässlicher Ecken gibt (und nicht selten sind die hässlichen Ecken die, hinter denen am meisten Geld steckt, ironischerweise), gibt es auch hin und wieder wunderschöne Edelsteine im Dreck.

So habe ich zum Beispiel vor Kurzem einen Autor (oder Autorin? Oder wasauchimmer, steht nicht dabei) entdeckt, der (die?) winzige, aber meist sehr schöne Geschichten schreibt.

Ursprünglich waren die Geschichten wohl auf Twitter, mit einer Zeichenbegrenzung von 140 Zeichen, ich habe sie aber auf Mastodon entdeckt.

Manche der Geschichten sind witzig, manche philosophisch, regen zum Nachdenken an.

Aber wie können diese Geschichten überhaupt so kurz sein? Nun, i.d.R. bauen sie auf bekannten Tropen auf, so dass der erste Satz schon die Szene setzt. Dabei gibt es ein paar Elemente, die immer wieder vorkommen, z.B.

  • die Prinzessin, der Drache und der Ritter (nicht unbedingt immer alle drei zusammen)
  • die Schwertmeisterin (oder der Schwertmeister, kann man nicht so genau sagen, ist englisch)
  • Katzen
  • Außerirdische, die landen, oder Außerirdische, die anderweitig mit Menschen kommunizieren
  • Zeitmaschinen
  • der/die Auserwählte

Nicht selten gibt es einen Twist am Ende. Manchmal sind die Geschichten geradeaus zu verstehen. Manchmal versteht man sie erst, wenn man am Ende angekommen ist. Manchmal versteht man sie erst ganz anders, bis am Ende der Twist kommt.

Ich kann nur empfehlen, sich diese Geschichten anzuschauen. Autor_in hat auch eine Website, aber dort sind nicht alle Geschichten direkt zu finden.

Turing-vollständige Schriftarten

Vor ein paar Wochen bin ich über llama.ttf gestoßen. Das ist eine Schriftart, die gleichzeitig ein Large Language Model ist und, ähnlich wie z.B. ChatGPT, Text generieren kann.

Da hatte ich natürlich einen gewissen WTF?-Moment. Wie geht das? Nun, es stellt sich heraus, dass HarfBuzz, ein verbreiteter text shaper, eine Funktion hat, die es einer Schriftart ermöglicht, beliebigen WebAssembly-Code auszuführen, um die Ausgabe zu beeinflussen.

HarfBuzz wird nun in allen möglichen Projekten verwendet, unter anderem auch in Firefox und Chrome. Damit können dann auch Schriften korrekt dargestellt werden, die etwas komplizierter darzustellen sind als die auf der lateinischen Schrift basierenden Schriften. Und damit man auch wirklich alles machen kann, gibt es da jetzt auch die Option, WebAssembly-Code direkt in die Schriftart einzubinden. Dieser Code wird dann von HarfBuzz ausgeführt.

Ich bin ja durchaus dafür, dass man jede Schrift der Welt auch im Computer korrekt darstellen können soll. Der Hauptentwickler von HarfBuzz war laut Wikipedia unglücklich mit mangeldem Support für die persische Schrift. Das war natürlich kein Zustand, und es ist gut, dass daran etwas getan wurde.

Aber bei Turing-vollständigem Code in der Schriftart hört für mich der SPaß auf. Erstens, weil natürlich genau das passieren wird, was auch mit JavaScript und Websites passiert ist: Webentwickler sind zu faul etwas richtig zu machen und fummeln dann lieber ein bisschen JS zusammen um eine Browserfunktionalität zu duplizieren und alles komplizierter zu machen. So erwarte ich, dass Designer von Schriftarten auch irgendwann nicht mehr die eigentlichen Features eines Schriftartenformats verwenden werden, sondern lieber etwas mit WebAssembly zusammenhacken, was dann das gesamte Textrendering langsamer macht und an vielen Stellen nicht funktioniert, weil dann doch nicht HarfBuzz verwendet wird.

Viel wichtiger aber: Das ist fucking code execution. Nun kann man argumentieren, dass das ja in einer Sandbox ist. Das kann nicht nach Hause telefonieren. Das kann nicht auf Dateien zugreifen oder sonst irgendwas machen. Aber wie wir wissen: Es gibt immer wieder Bugs in solchen Sandboxes, und irgendwie schafft dann jemand, daraus auszubrechen.

Bei Javascript ist das schon öfters passiert. Eine Type-confusion hier, ein Overflow dort, oder ein bisschen Rowhammern und – bahm! sitzt man nicht mehr im Sandkasten. HarfBuzz ist auch nur in C geschrieben. Egal wie gut ein Entwickler ist, früher oder später passiert irgendwo ein Fehler auf.

Meine Prognose: Irgendwann innerhalb der nächsten 10 Jahre wird uns das auf die Füße fallen. Und dann, ähnlich wie bei log4shell damals werden sich alle wundern, warum es dieses Feature überhaupt gab und ob unsere Software nicht zu komplex geworden ist.

etilqs

Ich hatte ja Anfang des Jahres mal erwähnt, das Daniel Stenberg, der cURL-entwickler, E-Mails sammelt. Unter diesen E-Mails waren viele von Leuten, die irgendwo seine Adresse in der cURL-Lizenz gefunden haben und ihn jetzt für alle möglichen Probleme verantwortlich machen, von beschwerden über Computerspiele bis hin zu angeblichen Hackerangriffen.

Heute habe ich gelernt: Sqlite hatte 2006 ein ähnliches Problem:

The default prefix used to be "sqlite_". But then Mcafee started using SQLite in their anti-virus product and it started putting files with the "sqlite" name in the c:/temp folder. This annoyed many windows users. Those users would then do a Google search for "sqlite", find the telephone numbers of the developers and call to wake them up at night and complain.

For this reason, the default name prefix is changed to be "sqlite" spelled backwards. So the temp files are still identified, but anybody smart enough to figure out the code is also likely smart enough to know that calling the developer will not help get rid of the file.