Verwaltung wird fluessig: von 4,5 auf 60 Bilder pro Sekunde

Bei der Systemabnahme gemessen und fuer untragbar befunden: Die
Verwaltung lief mit 4,5 Bildern je Sekunde, sobald die Maus bewegt
wurde. Die Startseite lag bei 60. Ein Arbeitswerkzeug, das bei jeder
Mausbewegung ruckelt, ist kein Gewinn an Schoenheit.

WAS GEMESSEN WURDE, STATT GERATEN

Jeder Effekt einzeln abgeschaltet, mit echter Mausbewegung:

  alles an                6,4 Bilder/s
  ohne Glas               9,7
  ohne Lampe              9,2
  ohne Kachel-Neigung     6,4   (kostet NICHTS)
  ohne Glas UND Lampe    16,4

Kein einzelner Schuldiger -- es war die Wechselwirkung. Die Lampe
verschiebt den Untergrund, woraufhin JEDE Glasflaeche darueber ihre
Rueckseiten-Unschaerfe neu berechnen muss. Beide zusammen kosteten mehr
als beide einzeln.

Die Neigung ist gratis: Sie laeuft auf der Grafikkarte.

Ein zweiter Posten kam dazu: Solange die Kacheln durchscheinend sind,
muss das bildschirmfuellende Buehnenbild bei jeder Neuzeichnung
mitgerechnet werden. Ohne Buehnenbild stieg die Rate von 24 auf 34,6.

DREI EINGRIFFE

1. Glas nur noch auf dem Detailblatt. Davon gibt es immer genau eines,
   und es liegt gross ueber der Seite -- dort faellt die Rechenzeit
   einmal an, nicht pro Listeneintrag. Kacheln, Reiter und Knoepfe
   bekommen stattdessen eine dichte Flaeche. Optisch kaum ein
   Unterschied, weil die Struktur des Bildes ohnehin verschwindet.

2. Die Vollbild-Zeigerlampe ist abgeschaltet. Das Licht, das dem Zeiger
   folgt, gibt es weiterhin -- auf den Kacheln selbst. Das ist der
   Effekt, der zaehlt, und er ist billig: Er betrifft nur die Kachel
   unter dem Zeiger statt des ganzen Bildschirms.

3. Die Kachelflaeche ist dichter (.92/.96 statt .52/.68). Die Buehne
   bleibt rings um die Kacheln voll sichtbar, durch die Kachel selbst
   schimmert sie nur noch als Ahnung.

ERGEBNIS

  in Ruhe (lesen)        55,6 -> 60,6 Bilder/s
  beim Scrollen          54,0
  Zeiger bewegt           4,5 ->   28

DIE BILDRATE IST JETZT SELBST EIN PRUEFPUNKT

Ohne ihn kaeme jederzeit ein weiterer huebscher Effekt dazu, der die
Seite still wieder zaeh macht -- und niemand wuesste, welcher es war.
Der Durchlauf verlangt jetzt ueber 45 Bilder je Sekunde in Ruhe.

NEBENBEFUND

Die Regel fuer das Detailblatt stand unter "#vw-bereich" -- das Blatt
liegt aber in einer eigenen Ueberlagerung. Die Regel griff also nie:
Ausgerechnet die eine Flaeche, die eine Unschaerfe wirklich verdient,
hatte als einzige keine. Gefunden hat das der neue Test.

Geprueft: 1281 Pruefungen gruen (Browser 715, Server 566), i18n ohne
Fehler, WCAG ohne Fundstellen.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-25 17:34:53 +02:00
co-authored by Claude Opus 5
parent 0ef64ba222
commit bd0346f785
18 changed files with 283 additions and 39 deletions
+1 -1
View File
@@ -34,7 +34,7 @@
Start alle alten Zwischenspeicher weg. Muss bei jeder Änderung an den
Dateien unten hochgezählt werden, sonst hängen Nutzer auf einem alten
Stand fest. */
const CACHE_NAME = "dogfather-webdesign-v49";
const CACHE_NAME = "dogfather-webdesign-v50";
/* Bausteine, die die Oberfläche zum Anzeigen braucht. Bewusst KEINE
HTML-Datei in dieser Liste. */
+119 -19
View File
@@ -306,8 +306,41 @@
Deshalb ein weiter Radius mit vielen flachen Stufen: Der
Helligkeitsunterschied verteilt sich ueber die halbe Kachel und
liest sich als Schimmer statt als Kreis. */
/* Der Lichtkegel sitzt FEST in der Mitte des Elements und wird per
transform verschoben -- nicht ueber die Position des Verlaufs.
Das ist der Unterschied zwischen ruckelig und fluessig: Aendert
sich die Verlaufsposition, muss der Browser die Flaeche bei jeder
Zeigerbewegung neu zeichnen. Und weil darueber Glasflaechen mit
Rueckseiten-Unschaerfe liegen, muessen die gleich mit. Gemessen
waren es dadurch 17 Bilder pro Sekunde.
Eine Verschiebung per transform laeuft dagegen auf der
Grafikkarte: Der Verlauf wird einmal gezeichnet und danach nur
noch bewegt. */
width: 2200px;
height: 2200px;
inset: auto auto auto auto;
left: 50%;
top: 50%;
margin-left: -1100px;
margin-top: -1100px;
will-change: transform;
transform: translate3d(var(--vw-lx, 0px), var(--vw-ly, 0px), 0);
/* Die Bewegung wird vom Stilblatt geglaettet, nicht vom Skript.
Der Grund ist Rechenzeit: Jede Verschiebung der Lampe aendert den
Untergrund SAEMTLICHER Glaskacheln darueber -- und jede davon muss
daraufhin ihre Rueckseiten-Unschaerfe neu berechnen. Bei 60
Aktualisierungen je Sekunde faellt das 60-mal an.
Das Skript setzt die Position deshalb nur noch etwa 12-mal je
Sekunde. Die Uebergangszeit fuellt die Luecken dazwischen weich
auf -- fuer das Auge laeuft die Lampe unveraendert fluessig, der
Rechner macht ein Fuenftel der Arbeit. */
transition: transform .22s cubic-bezier(.25,.8,.35,1);
background: radial-gradient(
1100px circle at var(--vw-mx, 50%) var(--vw-my, 40%),
circle 1100px at 50% 50%,
rgb(var(--vw-farbe) / .34) 0%,
rgb(var(--vw-farbe) / .26) 22%,
rgb(var(--vw-farbe) / .16) 42%,
@@ -320,7 +353,20 @@
/* Erst zeigen, wenn der Zeiger wirklich da war -- sonst haengt beim
Laden ein Lichtfleck in der Bildmitte, den niemand dorthin gelegt
hat. */
.vw-lampe.vw-lampe-an { opacity: 1; }
/* Die Zeigerlampe ist ABGESCHALTET.
Sie war der zweite Teil der teuren Wechselwirkung: Ihre Bewegung
zwang jede Glasflaeche darueber zum Neurechnen. Zusammen mit dem
Glas kostete sie zwei Drittel der Bildrate.
Das Licht, das dem Zeiger folgt, gibt es weiterhin -- auf den
Kacheln selbst. Das ist der Effekt, der zaehlt, und er ist billig:
Er betrifft nur die Kachel unter dem Zeiger, nicht den ganzen
Bildschirm.
Die Regel bleibt bewusst stehen statt geloescht zu werden, damit
nachvollziehbar ist, dass es eine Entscheidung war. */
.vw-lampe { display: none; }
@media (prefers-reduced-motion: reduce) {
.vw-lampe { transition: none; }
@@ -355,6 +401,7 @@
background: rgb(var(--vw-farbe) / .75);
box-shadow: 0 0 10px 1px rgb(var(--vw-farbe) / .45);
opacity: 0;
will-change: transform, opacity;
animation: vw-schweben linear infinite;
}
@keyframes vw-schweben {
@@ -390,22 +437,49 @@
Wo der Browser backdrop-filter nicht kann, traegt die Farbe allein:
Deshalb ist der Hintergrund auch ohne Unschaerfe schon dicht genug.
Das ist kein Schoenheitsfehler, sondern der Rueckfall. */
#vw-bereich .wd-karte,
#vw-bereich .vw-karte,
#vw-bereich .vw-meld,
#vw-bereich .vw-detail-blatt,
#vw-bereich .wd-notiz,
#vw-bereich table {
-webkit-backdrop-filter: blur(22px) saturate(1.15);
backdrop-filter: blur(22px) saturate(1.15);
/* GLAS NUR AUF WENIGEN, GROSSEN FLAECHEN.
Eine Rueckseiten-Unschaerfe ist der teuerste Effekt auf dieser
Seite -- und ihre Kosten fallen pro Element an. Auf jeder Kachel
einer langen Liste bedeutet das: Bei jeder Zeigerbewegung rechnet
der Browser sie fuer jede Kachel einzeln neu.
Gemessen mit echter Mausbewegung, sechs Kacheln:
alles an 6,4 Bilder/s
ohne Glas 9,7
ohne Lampe 9,2
ohne Glas UND Lampe 16,4
Die beiden verstaerken sich gegenseitig: Die Lampe verschiebt den
Untergrund, woraufhin JEDE Glasflaeche darueber neu rechnen muss.
Die Kacheln bekommen deshalb einen dichteren Hintergrund statt
einer Unschaerfe. Der Unterschied ist gering -- die Buehne
schimmert weiterhin durch, nur ohne Weichzeichnung -- und ein
Arbeitswerkzeug, das bei jeder Mausbewegung ruckelt, ist kein
Gewinn an Schoenheit.
Das Detailblatt behaelt seine Unschaerfe: Davon gibt es immer nur
genau eines, und es liegt gross ueber der Seite. */
/* Ohne #vw-bereich davor: Das Detailblatt liegt NICHT im
Arbeitsbereich, sondern in einer eigenen Ueberlagerung
(#vw-detail). Mit dem Vorsatz griff die Regel nie -- der Test
meldete "keins", und die einzige Flaeche, die die Unschaerfe
wirklich verdient, hatte als einzige keine. */
.vw-detail-blatt {
-webkit-backdrop-filter: blur(14px) saturate(1.15);
backdrop-filter: blur(14px) saturate(1.15);
}
/* 14 statt 22 Punkte Unschaerfe. Optisch kaum zu unterscheiden --
die Struktur des Bildes ist schon bei 14 vollstaendig aufgeloest --
aber deutlich billiger: Die Rechenzeit einer solchen Unschaerfe
waechst mit dem Radius, und sie faellt bei JEDER Bewegung neu an. */
/* Die Reiter und die Bedienknoepfe schweben ebenfalls. */
#vw-bereich .vw-filter-knopf,
#vw-bereich .vw-wer {
-webkit-backdrop-filter: blur(16px) saturate(1.1);
backdrop-filter: blur(16px) saturate(1.1);
}
/* Reiter und Bedienknoepfe: dichte Flaeche statt Unschaerfe, aus
demselben Grund. Es sind sechs Reiter plus zwei Knoepfe -- also
acht Flaechen, die sonst bei jeder Bewegung mitrechnen. */
#vw-bereich .vw-filter-knopf { background: rgb(6 19 35 / .78); }
/* Meldungen wie "Wird geladen" oder "Nichts vorhanden" stehen frei
zwischen den Kacheln -- also direkt auf der Buehne. Sie bekommen
@@ -540,8 +614,21 @@
#vw-bereich .vw-meld {
background:
/* Die Flaeche: dicht genug, dass Text darauf ruhig steht. */
/* Deutlich dichter als zuvor (.52/.68).
Der Grund ist gemessen: Solange die Kachel durchscheinend ist,
muss der Browser das bildschirmfuellende Buehnenbild bei jeder
Neuzeichnung der Kachel mitrechnen. Ohne Buehnenbild stieg die
Bildrate von 24 auf 34,6 -- das Bild unter dem Glas war der
groesste verbliebene Posten.
Bei .92/.96 bleibt die Buehne rings um die Kacheln voll
sichtbar, durch die Kachel selbst schimmert sie nur noch als
Ahnung. Das kostet etwas Tiefe und bringt Fluessigkeit -- auf
einer Seite, auf der gearbeitet wird, ist das der richtige
Tausch. */
linear-gradient(180deg,
rgb(var(--wd-glas-rgb) / .52), rgb(6 19 35 / .68)) padding-box,
rgb(var(--wd-glas-rgb) / .92), rgb(6 19 35 / .96)) padding-box,
/* Die Kante: hier steckt der Zeiger drin. Der Verlauf sitzt an
der Mausposition, dadurch wandert der helle Punkt am Rand
entlang mit. */
@@ -4029,6 +4116,7 @@
if (!buehne) return;
var lampe = document.querySelector(".vw-lampe");
var lampeAn = false;
var lampeZuletzt = 0;
var offen = false, letzteX = 0, letzteY = 0;
document.addEventListener("pointermove", function (e) {
@@ -4038,6 +4126,7 @@
offen = true;
requestAnimationFrame(function () {
offen = false;
var zeit = Date.now();
/* -0,5 bis +0,5 -- der Nullpunkt liegt in der Bildschirmmitte. */
var px = (letzteX / window.innerWidth) - 0.5;
var py = (letzteY / window.innerHeight) - 0.5;
@@ -4048,9 +4137,20 @@
Anteilswert: Ein radialer Verlauf mit Prozentangaben
verschiebt sich mit der Elementgroesse und laege dann nicht
mehr unter dem Zeiger. */
if (lampe) {
lampe.style.setProperty("--vw-mx", letzteX + "px");
lampe.style.setProperty("--vw-my", letzteY + "px");
/* Die Lampe wird bewusst SELTENER nachgefuehrt als die Buehne.
Jede ihrer Bewegungen zwingt alle Glaskacheln darueber, ihre
Unschaerfe neu zu berechnen. Zwoelfmal je Sekunde reicht
voellig: Den Rest glaettet der Uebergang im Stilblatt, und
fuer das Auge bleibt die Bewegung fluessig. */
if (lampe && zeit - lampeZuletzt > 80) {
lampeZuletzt = zeit;
/* Versatz aus der Bildschirmmitte, nicht die Position selbst:
Die Lampe wird verschoben, nicht neu gezeichnet. */
lampe.style.setProperty("--vw-lx",
Math.round(letzteX - window.innerWidth / 2) + "px");
lampe.style.setProperty("--vw-ly",
Math.round(letzteY - window.innerHeight / 2) + "px");
if (!lampeAn) { lampe.classList.add("vw-lampe-an"); lampeAn = true; }
}
});