Fassung 1.4.3: Update ohne Git, Verwaltung auf dem Telefon, eigene Symbole
Vier Wuensche und ein Fund beim Nachmessen. - Farbwaehler im Designbereich. Das Textfeld bleibt massgeblich, damit "@akzent" ein Verweis auf die Palette bleibt und nicht beim ersten Klick zu einem festen Hexwert erstarrt (ADR 066). - Die Verwaltung auf dem Telefon: das Menue klappt unter 760 px zu und nennt den Bereich, in dem man steht; Ziele 44 px, kein Skript. - Eigene SVG-Symbole statt Unicode-Zeichen - ein Telefon ersetzt die sonst durch Emoji in fremdem Stil. Zwei Eintraege trugen dabei denselben Pfad; ein Test findet beides (ADR 067). - Update aus dem Releasearchiv: der Weg fuer Installationen ohne Git. Zwei Schritte, weil ein Prozess, der sich selbst ausgetauscht hat, mit dem alten Code weiterarbeitet. var/, .env, hochgeladene Schriften und das erzeugte Buendel bleiben unberuehrt; public/ wird dazu Datei fuer Datei zusammengefuehrt. Geprueft ohne Netz gegen eine Releaseseite im Speicher (ADR 068). Beim Nachmessen der echten Startseite statt einer Testseite: das groesste Element ueber der Falz ist dort kein <img>, sondern der Hintergrund des ersten Abschnitts - und der steht nur im Stylesheet. Drei Vorabverweise mit denselben Geraetegrenzen wie der Compiler holen genau die Variante, die die Regel auch nimmt. LCP 1,3 s -> 1,1 s. Dabei gefunden: dasselbe Bild wurde je Geraeteregel neu abgefragt - Startseite 19 -> 15 Abfragen (ADR 069). Geprueft: 428 Tests auf PHP 8.2 und 8.4, Editor-, Browser- und Linkpruefung, Lighthouse auf drei echten Seiten (alles ausser der Leistung der Startseite 100). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ea3dd4ddf2
commit
d6d476177a
26 files changed
+1740
-26
No files matched your search
@@ -106,6 +106,9 @@ final class PageController extends AbstractController
|
||||
// im ersten Abschnitt des Inhalts: ein Bild weiter unten waere die falsche
|
||||
// Eile, und das Logo im Kopfbereich ist klein und laedt ohnehin sofort.
|
||||
'eagerImage' => $this->firstImage(['blocks' => array_slice($page['document']['blocks'] ?? [], 0, 1)]),
|
||||
// Und das Gegenstueck fuer den haeufigeren Fall: Das grosse Bild ueber der Falz
|
||||
// ist gar kein Bild, sondern der Hintergrund des ersten Abschnitts.
|
||||
'heroBackground' => $this->heroBackground($areas['header'] ?? null, $page['document']),
|
||||
'pageStyles' => $styles,
|
||||
'googleFonts' => $googleFonts,
|
||||
'localFonts' => $localFonts,
|
||||
@@ -539,6 +542,49 @@ final class PageController extends AbstractController
|
||||
* That one must not be lazy: it is usually the largest thing above the fold, and deferring it
|
||||
* delays exactly the pixel a visitor waits for. Everything below it stays lazy.
|
||||
*/
|
||||
/**
|
||||
* Das Hintergrundbild des ersten Abschnitts, um es vorab zu holen.
|
||||
*
|
||||
* Gemessen an der Startseite des Piloten: Das groesste Element ueber der Falz ist dort kein
|
||||
* `<img>`, sondern der Hintergrund des Heros. Ein Hintergrundbild steht im Stylesheet, und
|
||||
* das kommt nach dem HTML - der Browser erfaehrt also erst vom Bild, wenn er das CSS geparst
|
||||
* hat. Lighthouse nennt das „LCP request discovery"; gemessen 1,3 s statt 0,9 s.
|
||||
*
|
||||
* Vorab geholt wird **genau die Variante, die das Stylesheet auch nimmt**: drei Verweise mit
|
||||
* denselben Grenzen wie der Compiler, nicht ein `imagesrcset`. Ein `srcset` waehlt nach
|
||||
* Breite, die Regeln waehlen nach Geraet; wo beide auseinanderlaufen, laedt der Browser zwei
|
||||
* Bilder statt einem - und dann kostet das Vorabholen mehr, als es bringt.
|
||||
*
|
||||
* @return list<array{src: string, media: string}>
|
||||
*/
|
||||
private function heroBackground(?array $header, array $document): array
|
||||
{
|
||||
// Steht ueber dem Inhalt ein Kopfbereich mit eigenem Hintergrundbild, ist dessen Bild das
|
||||
// obere. Sonst der erste Abschnitt des Dokuments.
|
||||
foreach ([$header, $document] as $kandidat) {
|
||||
$block = ($kandidat['blocks'] ?? [])[0] ?? null;
|
||||
$id = $block['style']['desktop']['backgroundImage'] ?? null;
|
||||
if (!is_string($id) || '' === $id) {
|
||||
continue;
|
||||
}
|
||||
$item = $this->media->find($id);
|
||||
if (null === $item || [] === ($item['variants'] ?? [])) {
|
||||
continue;
|
||||
}
|
||||
$verweise = [];
|
||||
foreach (StyleCompiler::PRELOAD_DEVICES as $device => $media) {
|
||||
$verweise[] = [
|
||||
'src' => StyleCompiler::variantFor($item['variants'], $device)['src'],
|
||||
'media' => $media,
|
||||
];
|
||||
}
|
||||
|
||||
return $verweise;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private function firstImage(array ...$documents): ?string
|
||||
{
|
||||
foreach ($documents as $document) {
|
||||
|
||||
Reference in new issue
Block a user