Am dat un test de viteza pe limebooth.app. Scorurile erau bune — 96 pe mobil, 100 pe desktop. Sub ele statea insa un raport pe care nu-l citeste nimeni: sase erori in consola, toate la fel.
Loading the font 'data:font/woff2;base64,…' violates the following Content Security Policy directive:
font-src 'self'. The action has been blocked.
Site-ul isi purta fonturile direct in pagina, codificate base64. Politica lui de securitate — scrisa de noi — spunea ca fonturile pot veni numai de pe propriul domeniu. Un data: nu e „propriul domeniu". Browserul le refuza pe toate cinci.
Un bug pe care nimeni nu-l vede
Fontul cerut era Archivo. Fontul desenat era Segoe UI. Luni de zile.
Asta e genul de defect care nu declanseaza nimic: nu e o pagina rupta, nu e o eroare de retea, nu e un 404 intr-un jurnal. Pagina se incarca, textul se citeste, totul pare in regula. Doar ca nu e fontul tau.
Costul tacut era si el masurabil: 74 KB de base64, 26% din document, trimisi la fiecare vizita si aruncati imediat.
De ce n-a prins-o nicio verificare
Aveam verificari. Una se uita la antetele de securitate si confirma, corect, ca exista un CSP pe fiecare gazda. Bifa era verde.
Aici e miezul: un CSP prezent nu inseamna un CSP care lasa pagina sa se vada intreaga. Verificarea raspundea la „e pusa protectia?", nu la „protectia taie ceva din ce cere pagina?". A doua intrebare n-o punea nimeni.
Reparatia
Prima varianta care-ti vine in minte e sa adaugi data: la font-src. O linie, gata. Am ales altceva: fonturile ca fisiere adevarate, servite de pe acelasi domeniu. Trec prin politica fara s-o atingem, se incarca o data pentru tot site-ul, si ies din <head>-ul pe care browserul il parseaza inainte de primul pixel.
| inainte | dupa | |
|---|---|---|
| Erori in consola | 6 | 0 |
| Best Practices | 92 | 100 |
| LCP pe mobil | 2,6 s | 2,0 s |
| Documentul | 291 KB | 218 KB |
Un singur lucru a mers invers: Speed Index a urcat. Merita spus de ce. Inainte nu exista niciun schimb de font — fonturile nu se incarcau niciodata — deci pagina se picta o data si ramanea asa. Acum textul apare cu fontul de rezerva si se repicteaza cand soseste Archivo, iar Speed Index penalizeaza exact acea repictare.
Verificarea care lipsea
Reparatia unui bug e jumatate de treaba. Cealalta jumatate e verificarea care l-ar fi prins.
Am adaugat una generica, nu una pe fonturi: pentru fiecare pagina, fiecare data: din corp se duce la directiva CSP care il guverneaza, iar aceea trebuie sa-l permita. Inainte s-o cred, am stricat-o inapoi si m-am uitat cum pica — patru pagini rosii, restul verde.
Regula care s-a platit din nou: o verificare care n-a picat niciodata pe un bug real nu e o verificare.
Daca rulezi ceva cu un CSP strans, intrebarea utila nu e „am pus politica?". E „ce cere pagina mea, si trece tot prin ea?".