Zwykle się nie zdarza w 2024. Ale musiałem zaimplementować obrazki na spritach jak 20 lat temu.
Problem
Mapka z polskimi herbami https://deykun.github.io/maps/heraldyka
Herbów było 2k, każdy na absolucie każdy był w osobnym src, jak się wchodziło (o dziwo na chromie o wiele gorzej niż na firefoxie) to była zawiecha na ileś sekund (potem jak się ogarnęło to już raczej działało), raport z lighthouse 3/4 się psuł przy odpaleniu i renderował się dobre 3 minuty+ (zawierał uwagi o przesunięciach w tych setkach elementów).
Dostałem nawet 2 razy bana na IP na githubie, bo 3 otwarte karty potrafiły pobrać 8k obrazków. Wspomniane tutaj.
Raport z lighthouse jest we wpisie.
18.8 sekund blokowania wątku!
Ale w sumie ciekawy kejs, bo chcemy mieć elementy w x i y i chcemy mieć to 2k obrazków.
Oczywiste nieoczywiste rozwiązania to:
-
przenieść mapkę do canvasa pozbędziemy się wtedy 2k nodów html
-
stworzyć sprite obrazków i kadrować
Co zrobiłem:
-
Zmieniłem obrazki na webp, dodałem srcset, co poprawiło wynik delikatnie
-
Stworzyłem canvasa (ostatecznie go nie używam na tej stronie)
-
Do canvasa stworzyłem sprite 180 herbów na obrazek ->
zamiast 2000 obrazków, pobiera ~11
-
Wykorzystałem spritery na tej stronie bez canvasa (jako background-image)
Rezultat:
Strona się ładuje normalnie, skok z 52/100 punktów wydajności przy 2.1k herbów do 81/100 z 2.6k herbów.
Issue na githubie: https://github.com/Deykun/maps/issues/16
W sumie spoko przypadek, pierwszy raz używałem spritów i canvasa dla zwykłej i koniecznej optymalizacji.
Po poprawkach:
no ale css też obsługuje sprite, więc dałoby radę tego użyć
@Deykun a myślałeś o użyciu "spritesheeta" i przycięciu do odpowiedniego herbu w HTMLu?
@wombatDaiquiri
a myślałeś o użyciu "spritesheeta" i przycięciu do odpowiedniego herbu w HTMLu?
No o tym jest wpis, że tego użyłem chyba. ;D
Przykłady:
https://deykun.github.io/maps/images/heraldry/pl/web/sprites/gminy-0.webp
https://deykun.github.io/maps/images/heraldry/pl/web/sprites/gminy-1.webp
@Deykun przyznaję że przeczytałem po łebkach xD skąd limit 180 herbów?
@wombatDaiquiri
Paczka którą kleiłem obrazki robi domyślnie je jeden pod drugim, jakbym chciał grid to bym musiał jakąś pętle zrobić i kleić wiersze i kolumny (może kiedyś zrobię). Ale tak prosto bo y = index * wysokość herbu + index * odstęp i działa.
Przy 200 herbów na obrazek paczka do obrazków rzucała błędem, że wysokość 16000px to za dużo żeby zapisać webp.
@Deykun to o czym piszesz to właśnie spritesheet albo image/texture atlas.
Możesz to sobie wygenerować przy pomocy różnorakiego softu/paczek z neta (pewnie masz jakąś gównianą paczkę że nie ogarnia bin/grid packingu oraz generowania indexów/offsetów do tego, ale nie ocenię bo JS-a nie tykam).
Osobiście wykorzystałbym texture packer z libGDX ( tutaj masz GUI do tego bo można też tego stand-alone używać jeśli nie ogarniasz Java czy tam używanie tego z terminala i ręczne konfigurowanie to za dużo zachodu).
Ja tego używałem z poziomu Java do generowania na żywo przy odpalaniu gierki atlasów składających się z tysięcy obrazków z zamkniętego formatu zanim to pchałem do GPU. LibGDX używa spoko bin packera do upychania obrazków, ale jeśli z jakiegoś powodu potrzebujesz mieć grid to jest tam taka opcja.
Rozwiązanie z canvasem wykorzystuję dla mapki Europy gdzie wszystkie kraję będę renderować (obecnie z 3 mam 4.2k herbów).
https://deykun.github.io/maps/heraldry
Ale ta strona ma jeszcze swoje własne bolączki jeszcze (niezwiązane z ładowaniem).
Zaloguj się aby komentować