Vary: Service Worker
Über Monate war der Service Worker meines Kegelclubs defekt: Zwar wurden Seiten aus dem Cache geholt, wenn man offline war, aber eben nicht die Kegelspiele – und gerade für die war doch dieses tolle Feature gedacht, sitzen wir doch oft auf Kegelbahnen ohne stabiles Internet!
Wie sich herausgestellt hat, war mein Wille, HTTP-konform zu sein, Schuld daran: Ich liefere unter einer URI mehrere Ressourcen aus, je nach Accept
-Header. Die Kegelspiele können also in verschiedenen Varianten (HTML, JSON, XML, Markdown) abgefragt werden:
Accept: text/html GET https://kegelclub-tüddern.de/kegelspiele/grosse-hausnummer <!doctype html> ...
Accept: application/json GET https://kegelclub-tüddern.de/kegelspiele/grosse-hausnummer { ...
Gedacht war das mal für eine potentielle iOS-App, um direkt eine JSON-Repräsentation zu haben. Ohje … 🤷🏻♂️ Pro-Tipp: Baut keine APIs, bevor Ihr sie nicht auch braucht!
Aber nun gut. HTTP-Konformität, hm? Also ein ganz kleiner Exkurs: Wenn sich die Response einer URI aufgrund eines beliebigen Request-Headers ändern kann, so muss man diese Request-Header mit dem Vary
-Response-Header auflisten. In meinem Fall ist das:
Vary: Accept, Accept-Encoding
Den Header setzt man vor allem wegen Caching:
The Vary HTTP response header determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server. It is used by the server to indicate which headers it used when selecting a representation of a resource in a content negotiation algorithm.
Wegen Caching! Dieser Vary
-Header war der Grund für den defekten Service Worker, denn Letzterer versuchte nun immer, diese eine Ressource direkt aus dem Netz statt aus dem Cache zu holen!
Die Lösung im Service Worker ist ignoreVary
:
// cache will not be used for requests with Vary header, response is undefined const response = await caches.match(request); // cache will ignore Vary header, response is the cached ressource const response = await caches.match(request, { ignoreVary: true });
Aaaalter … Das hat mich heute Abend gute drei Stunden Ausprobier- und Suchzeit gekostet. Aber hey, wieder was gelernt! 😓
Lange Attributwerte in den Firefox Devtools
, dass lange Attributwerte in den Firefox Devtools gekürzt werden. Hat es mich auch schon einige Male.
Aber: Man kann das abschalten, wie ich erst neulich herausfand!
Der einfachste Weg geht über die Devtools-Einstellungen. „Truncate DOM attributes“ abhaken, fertig.
Wer es etwas granularer einstellen möchte, kann devtools.markup.collapse*
in about:config bemühen.
Statische Ressourcen besser cachen
Ich habe vor einigen Wochen die Website meines Musikvereins einem Relaunch unterzogen. Nicht nur das Frontend ist erneuert, auch den kompletten technischen Unterbau habe ich neu geschrieben. So ist auch das Caching statischer Ressourcen neu, also CSS, Skripte oder Bilder. Im Folgenden beschreibe ich, was ich getan habe. Vorab: Ich nutze kein CMS oder Framework.
create-launch-images ist da
Ein kleines „Abfallprodukt“ meines letzten privaten Projekts habe ich gerade auf GitHub und npm gepusht: create-launch-images
iOS erstellt für PWAs leider immer noch keine Launch-Screens auf Basis des Web App Manifests – die Bilder (und es sind nicht wenige!) muss man selber bereitstellen. Das war ich leid, darum habe ich kurzerhand ein Node-Script geschrieben, das das Manifest auswertet und mit dem größten darin hinterlegten PNG-Icon, dem name
oder short_name
und der background_color
die Launch-Screens für iPhone 6 und höher erstellt.
Der Code ist sicher nicht der Schönste, Robusteste oder gar Performanteste, funktioniert aber für meine Zwecke ganz gut. Darum habe ich das mit meow zu einem kleinen CLI-Tool verdrahtet und veröffentlicht, damit Ihr auch was davon habt. Natürlich ohne Gewähr, ist ja auch v0.0.1! 😁
Feierabend
So. 9 Stunden Code geschrubbt; es verbleiben noch zwei Kleinigkeiten, die hebe ich mir für morgen auf. Und dann endet ein Projekt, das ich laut Things am 24.03.2017 begonnen habe, dessen erster Commit laut GitHub am 03.04.2018 stattfand und das inzwischen 101.688 Changes hat.
Adressleiste im iOS-Safari einfärben
Eine nette Sache, die im mobilen Chrome (und in einer Reihe von anderen Browsern) funktioniert, ist das Einfärben der Adressleiste. Man setzt einfach dazu einfach ein Meta-Tag:
<meta name="theme-color" content="lime">
Im iOS-Safari ist das nicht möglich, auch nicht mit dem Web App Manifest.
Beim längst überfälligen Redesign der Vereinsseite bin ich aber zufällig auf einen netten Effekt gestoßen: Mittels einer background-color
auf dem body
färbt diese Farbe die Adressleiste ein. Die „normale“ Hintergrundfarbe legt man dann auf dem direkten Kind-Element des Bodys. Zum Beispiel so:
body { /* this will color the address bar in iOS/iPadOS Safari */ background-color: lime; /* reset body margin for full background-color of wrapper */ margin: 0; } body > *:first-child { /* apply default background-color and “body” padding here */ padding: 1em; background-color: white; }
Das Ergebnis wäre dieses:
Ups, der Content ist zu kurz, die Hintergrundfarbe soll so aber nicht aussehen. Der Trick ist, jetzt noch eine Hintergrundfarbe auf html
zu setzen:
html { background-color: white; }
Idealerweise ist es die gleiche Farbe wie die des ersten Kind-Elements. Aber man kann natürlich auch etwas kreativer sein und eine ganz andere Farbe nehmen:
Hinweis am Rande: Im macOS-Safari sorgt die Farbe übrigens für das Einfärben der Scrollleiste.
Tschüss, SETI@home
Nach über 20 Jahren geht SETI@home jetzt in den Winterschlaf:
Wissenschaftlich gesehen sind wir an dem Punkt angelangt, an dem die Erträge abnehmen; im Grunde haben wir alle Daten analysiert, die wir für den Moment benötigen.
Der Nerd in mir findet das natürlich sehr schade, war ich doch von Anfang an dabei – auch wenn ich meinen ursprünglichen Account „verlegt“ habe und 2006 neu startete.
Dafür stecke ich aber jetzt mehr Rechenleistung in die medizinische Forschung. Rosetta@home unterstütze ich schon einige Jahre, jetzt kommt noch IBMs World Community Grid dazu. Und wer weiß, wenn ich meine letzten SETI@home-Pakete abgearbeitet habe, vielleicht sogar noch was mehr …
Dieser Moment, wenn der Prototyp des Terminators gelenkiger ist als Du:
Reducing motion with the picture element
Brad Frost ist auf eine sehr coole Lösung für accessible GIFs gestoßen: Reducing motion with the picture element