Kasse und Google-Anmeldung in der Inhaltsrichtlinie freigegeben
Fortsetzung des Musik-Fundes: PayPal und Google haetten an derselben Stelle still versagt, sobald Dogi seine Zugangsdaten eintraegt -- leerer Bereich statt Bezahlknopf, ohne Fehlermeldung, ohne Protokolleintrag. Vorgehen bewusst gemessen statt geraten: Erst die Angaben der Anbieter (PayPal "Best Practices", Google CSP-Abschnitt der Setup-Anleitung), dann im echten Browser mit PayPals offizieller Testkennung "client-id=test" nachgemessen und die Verstoesse ueber das Ereignis securitypolicyviolation eingesammelt. Die Messung hat zwei Dinge gefunden, die in keiner Anleitung standen: - www.sandbox.paypal.com (frame-src + connect-src). Beim Einrichten testet man mit Sandbox-Zugangsdaten; ohne diesen Eintrag haette die Kasse in genau dieser Phase nicht abgeschlossen werden koennen. - accounts.google.com/gsi/style (style-src). 'unsafe-inline' deckt das NICHT ab -- es erlaubt nur Stile im Dokument, keine nachgeladene Stilvorlage. Der Anmelde-Knopf waere unformatiert erschienen. Bewusst einzelne Adressen statt PayPals vorgeschlagener Platzhalter (*.paypal.com): Was die Messung nicht gebraucht hat, steht nicht drin. Skripte bleiben ohne 'unsafe-inline' -- die Pruefsummen-Loesung fuer die eigenen Inline-Bloecke bleibt unangetastet, und ein zusaetzliches 'unsafe-inline' waere neben Pruefsummen ohnehin wirkungslos. Neuer Test pruef-kasse.mjs (15 Pruefungen): laedt das echte PayPal-SDK, baut die Bezahlknoepfe wirklich auf, rendert den echten Google-Knopf und verlangt NULL Verstoesse. Bestandstest pruef-inhaltsrichtlinie.mjs (22) und pruef-musik.mjs (17) bleiben gruen -- inklusive der Gegenprobe, dass eingeschleuste Skripte weiterhin blockiert werden. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
/* =====================================================================
|
||||
Wie schwer und wie schnell sind die öffentlichen Seiten?
|
||||
|
||||
Misst je Seite die übertragene Datenmenge und die Ladezeit bis
|
||||
"fertig geladen", und sammelt die größten Einzelressourcen über alle
|
||||
Seiten. Ziel ist NICHT ein grüner Haken, sondern das Finden konkreter
|
||||
Brocken, die sich lohnen zu verkleinern -- so wie am 27.08. das 2,5-MB-
|
||||
PNG "Event des Jahres" gefunden wurde.
|
||||
|
||||
Gegen die echte Domain, mit leerem Cache (jeder Aufruf frische Seite).
|
||||
===================================================================== */
|
||||
import { chromium } from "playwright";
|
||||
|
||||
const BASIS = "https://dogfather-universe.com";
|
||||
const SEITEN = [
|
||||
"/", "/dogfather.html", "/hasidog.html", "/manager.html", "/casper.html",
|
||||
"/vanvan.html", "/tt-muddi.html", "/zeitreise.html", "/streamer.html",
|
||||
"/community.html", "/stimmen.html", "/streamplan.html", "/team-modis.html",
|
||||
"/team-scouts.html", "/creator.html", "/werte.html", "/bewerben.html",
|
||||
"/kontakt.html", "/links.html", "/supporter.html", "/abonnieren.html",
|
||||
"/medien-dogfather.html", "/medien-hasidog.html", "/medien-casper.html",
|
||||
];
|
||||
|
||||
const browser = await chromium.launch();
|
||||
const groessteJeRessource = new Map(); // url -> bytes
|
||||
const proSeite = [];
|
||||
|
||||
for (const pfad of SEITEN) {
|
||||
const seite = await browser.newPage();
|
||||
let bytes = 0;
|
||||
seite.on("response", async (r) => {
|
||||
try {
|
||||
const h = r.headers();
|
||||
const len = Number(h["content-length"] || 0);
|
||||
let b = len;
|
||||
if (!b) { try { b = (await r.body()).length; } catch { b = 0; } }
|
||||
bytes += b;
|
||||
const u = r.url();
|
||||
if (b > (groessteJeRessource.get(u) || 0)) groessteJeRessource.set(u, b);
|
||||
} catch { /* egal */ }
|
||||
});
|
||||
const start = Date.now();
|
||||
try {
|
||||
await seite.goto(BASIS + pfad, { waitUntil: "networkidle", timeout: 45000 });
|
||||
} catch { /* trotzdem messen, was da war */ }
|
||||
const dauer = Date.now() - start;
|
||||
proSeite.push({ pfad, kb: Math.round(bytes / 1024), ms: dauer });
|
||||
await seite.close();
|
||||
}
|
||||
await browser.close();
|
||||
|
||||
console.log("\n=== Pro Seite (übertragen / Ladezeit), schwerste zuerst ===");
|
||||
for (const s of proSeite.sort((a, b) => b.kb - a.kb)) {
|
||||
const warn = s.kb > 2000 ? " ⚠ schwer" : s.kb > 1000 ? " · mittel" : "";
|
||||
console.log(` ${String(s.kb).padStart(5)} KB ${String(s.ms).padStart(5)} ms ${s.pfad}${warn}`);
|
||||
}
|
||||
const schnitt = Math.round(proSeite.reduce((a, s) => a + s.kb, 0) / proSeite.length);
|
||||
console.log(` ---\n Schnitt: ${schnitt} KB / Seite`);
|
||||
|
||||
console.log("\n=== Die 12 größten Einzelressourcen (Kandidaten zum Verkleinern) ===");
|
||||
const top = [...groessteJeRessource].sort((a, b) => b[1] - a[1]).slice(0, 12);
|
||||
for (const [u, b] of top) {
|
||||
const kb = Math.round(b / 1024);
|
||||
const kurz = u.replace(BASIS, "").replace(/\?.*$/, "");
|
||||
const warn = kb > 500 ? " ⚠" : "";
|
||||
console.log(` ${String(kb).padStart(5)} KB ${kurz}${warn}`);
|
||||
}
|
||||
Reference in New Issue
Block a user