Przejdź do treści
Strony budowane z modelem

Kod z modelu w produkcji. Co sprawdzić przed wdrożeniem.

Model składa layout w kilka minut. Potem zostaje przegląd kodu, LCP, kontrast, obsługa klawiatury i pytanie, ile ta reszta kosztuje w wycenie. Piszemy o tej drugiej części: co konkretnie sprawdzić, co poprawić i jak wygląda różnica w liczbach.

poniżej: 1 komponent · 14 linijek · 5 uwag do znalezienia

Galeria.jsx · komponent wygenerowany z promptu o wyglądzie · kliknij linijkę ze znacznikiemznaleziono 0/5
  1. 2
  2. 3
  3. 4
  4. 5
  5. 6
  6. 9
  7. 12
  8. 13
  9. 14
Pięć uwag w czternastu linijkach.Komponent wygląda poprawnie i przechodzi build. Każda zaznaczona linijka ma uwagę: co jest źle, dlaczego to boli w produkcji, poprawka i reguła, którą narusza.
L1 · bezpieczeństwo

Klucz API w bundlu

co jest źle
Stała z kluczem trafia do pliku JS. Po buildzie leży na CDN pod publicznym adresem i jest serwowana każdemu, kto otworzy stronę.
dlaczego boli w produkcji
Rotacja nie cofa tego, co już zostało pobrane. Rachunek za cudze użycie API i tak przychodzi do agencji.
poprawka
// serwer: GET /api/items, klucz z process.env
fetch("/api/items")      // klient: bez klucza
CWE-798 · sekrety poza bundlem
L7 · jakość kodu

Brak walidacji odpowiedzi

co jest źle
setItems dostaje cokolwiek przyszło z sieci. Odpowiedź 500 zwraca HTML, r.json() rzuca wyjątek i nikt go nie łapie.
dlaczego boli w produkcji
Biały ekran u klienta zamiast komunikatu. Inny kształt danych wywala items.map w renderze, ze stackiem innym niż lokalnie.
poprawka
.then(r => { if (!r.ok) throw new Error(r.status); return r.json(); })
.then(d => setItems(Array.isArray(d) ? d : []))
.catch(setBlad);
CWE-20 · walidacja wejścia i odpowiedzi
L8 · wydajność

Pętla zależności useEffect

co jest źle
Efekt zależy od items, które sam ustawia. Każde setItems uruchamia efekt od nowa, a ten znów woła fetch.
dlaczego boli w produkcji
Nieskończona seria żądań: rachunek za API rośnie, główny wątek jest zajęty, INP przekracza próg, bo przeglądarka nie nadąża odpowiadać na kliknięcia.
poprawka
useEffect(() => {
  const ac = new AbortController();
  fetch("/api/items", { signal: ac.signal }) /* … */
  return () => ac.abort();
}, []);                  // raz, po montażu
INP ≤ 200 ms · zależności efektu
L10 · dostępność

Modal bez obsługi Escape i fokusu

co jest źle
hidden przełącza widoczność, ale fokus zostaje pod spodem, Escape nic nie robi, a element nie ma roli okna dialogowego.
dlaczego boli w produkcji
Osoba na klawiaturze tabuje po linkach pod przyciemnionym tłem. Czytnik ekranu czyta stronę spod okna. Wyjście: przeładowanie strony.
poprawka
<dialog ref={ref} onClose={zamknij} aria-labelledby="tytul">
  …
</dialog>   // ref.current.showModal(): Escape i pułapka fokusu
WCAG 2.1.1, 2.1.2, 2.4.3 · klawiatura i fokus
L11 · Core Web Vitals

Obraz bez wymiarów

co jest źle
img bez width i height, więc przeglądarka nie rezerwuje miejsca. alt="" ukrywa obrazy treściowe przed czytnikiem ekranu.
dlaczego boli w produkcji
Każdy załadowany obraz przesuwa układ w dół. Przy dziesięciu miniaturach nad zgięciem CLS przekracza 0,25, a osoba z czytnikiem widzi pustą galerię.
poprawka
<img src={i.url} width={i.w} height={i.h}
     alt={i.opis} loading="lazy" />
CLS ≤ 0,1 · WCAG 1.1.1 treść nietekstowa
Core Web Vitals przed i po

Wygenerowany layout wypada dobrze lokalnie i słabo w polu

Przesuń wartość po wygenerowaniu. Wynik po poprawkach liczymy z tego, co opisujemy w tekstach o hero, foncie, skryptach w head i obrazach bez wymiarów. Progi wg Google, ocena na 75. percentylu.

przykład modelowy
wartości do podmiany
profil mobilny, laboratorium

po wygenerowaniupo poprawkachdobrzewymaga poprawysłabo

LCPs

progi 2,5 / 4,0
po wygenerowaniu4,2 ssłabo
po poprawkach1,8 sdobrze

CLS

progi 0,1 / 0,25
po wygenerowaniu0,32słabo
po poprawkach0,06dobrze

INPms

progi 200 / 500
po wygenerowaniu380 mswymaga poprawy
po poprawkach171 msdobrze

Wartość „po poprawkach” to model: LCP × 0,43 (min. 1,2 s), CLS × 0,2 (min. 0,02), INP × 0,45 (min. 80 ms). W tekstach zastępujemy go pomiarem z karty pomiaru.

Lista kontrolna przed oddaniem klientowi

Piętnaście kwadratów. Model nie odhaczy żadnego sam.

Minimum, które sprawdzamy w każdym rozbiorze. Odhacz to, co masz w projekcie, a stan zostaje w przeglądarce tylko do zamknięcia karty.

każda pozycja ma tekst
z kodem przed i po

WCAG minimum

0/5

Wydajność

0/5

Bezpieczeństwo

0/5
O czym piszemy

Cztery obszary. W każdym fragment przed poprawką i po niej.

numer to linijka, od której
zaczyna się obszar w tym pliku

073

Przegląd kodu, który wyszedł z modelu

Co zatrzymać na review: zdublowany stan, zależność dorzucona bez potrzeby, brak walidacji wejścia, klucz wklejony do komponentu. Fragment przed poprawką i po niej, obok siebie.

Jakość kodu →
074

LCP i CLS po wygenerowaniu strony

Dlaczego wygenerowany layout wypada dobrze lokalnie i słabo w polu. Hero, fonty, skrypty w head, obrazy bez wymiarów - po kolei, z pomiarem przed i po zmianie.

Core Web Vitals →
075

Dostępność, której model nie dopisze sam

Kontrast, kolejność fokusu, etykiety pól, obsługa klawiatury w modalach i menu. Czego brakuje w typowym wygenerowanym komponencie i jak to sprawdzić, zamiast zgadywać.

Dostępność WCAG →
076

Wycena, utrzymanie, przekazanie projektu

Ile godzin realnie zostaje po wygenerowaniu makiety, jak zapisać to w wycenie i co oddać klientowi, żeby stronę dało się utrzymać bez autora pierwszej wersji.

Wycena i proces →
Najnowsze rozbiory

Każdy tekst kończy się linijką z pomiarem

7 tekstów w rejestrze
każdy z linijką pomiaru

Działy: Jakość kodu · Core Web Vitals · Dostępność WCAG · Wycena i proces · Bezpieczeństwo · Utrzymanie i przekazanieWszystkie teksty
Redakcja

Piszemy z kodem i z pomiarem

Redakcja, developer front-end

Profil do obsadzenia realnym developerem front-end. Każdy tekst z fragmentem kodu albo wynikiem pomiaru, nie z opinią. Ton praktyczny, bez zachwytu nad narzędziami: wynik przed i po, a nie deklaracje. Teksty powstają z pomocą modelu językowego i są oznaczone.

Piszemy z kodem i z pomiarem. Każdy tekst bierze jeden konkretny przypadek: fragment przed poprawką, fragment po, i to, co zmieniło się w wyniku. Liczby podajemy razem z warunkami pomiaru, żeby dało się je powtórzyć u siebie. Nie robimy rankingów narzędzi ani zestawień „top 10” - to samo zadanie wygląda inaczej w każdym stacku, więc opisujemy metodę, nie zwycięzcę. Jeśli czegoś nie da się sprawdzić, piszemy o tym wprost zamiast domykać tekst zgadywaniem.

Masz wygenerowany komponent, który się psuje?

Napisz, jeśli masz konkretny przypadek - wygenerowany komponent, który się psuje, słaby wynik Core Web Vitals albo problem z dostępnością - i chcesz, żeby powstał z tego rozbiór z kodem.