Koncepcja optymalizacyjna...

28 października, 2007

Dawno już nie pisałem na tematy związane z webmasteringiem, a dzisiejszy wpis powstał w sumie dlatego, że doznałem (tak mi się wydaje) małego olśnienia w kwestii optymalizacji. Nie wiem czy ktoś już podobny temat poruszał, przynajmniej ja się nie spotkałem z takim rozwiązaniem wcześniej, a opisywana koncepcja może mieć duże znaczenie dla moich projektów - pod warunkiem, że nikt nie obali mojej tezy, którą niedługo przedstawię ;)

No ale do rzeczy - często zdarza się, że musimy ładować na stronie jakieś małe obrazki, zwłaszcza przy wciąż modnych zaokrągleniach - są one ustawiane jako tło danego elementu... Przeszło mi przez myśl, że zamiast ładować cztery malutkie obrazki dla każdego rogu tak jak ma to miejsce w tym przykładzie można by do tego podejść inaczej - stworzyć jeden obrazek zawierający wszystkie cztery rogi i umieścić w odpowiednich elementach odpowiednie fragmenty obrazka poprzez właściwość background-position.

Efekt takiej operacji wygląda identycznie, ale jeżeli chodzi o rozmiary plików itd. sytuacja jest zupełnie inna.

W standardowej wersji przeglądarka wykonuje 10 zapytań. 4 pliki będące rogami mają rozmiar 994 bajtów, a plik styli zajmuje 1.07kB.

W wersji zoptymalizowanej przeglądarka wykonuje 7 zapytań, bo pobiera jeden plik zamiast czterech. Jeden plik z rogami zajmuje 418 bajtów, a plik styli zajmuje 1.13kB.

Jak widzimy mimo dodania 3 reguł w pliku styli nadal wersja zoptymalizowana jest lżejsza od oryginału, a ponadto przeglądarka wykonuje mniej zapytań do serwera. Oczywiście prezentowany przykład to tylko idea działania. Warto jednak pomyśleć co można dzięki niej zyskać przy większych projektach...

Teraz moja teza ;) Gdy mamy stronę gdzie musimy załadować kilkanaście ikonek, wydaje mi się, że bardziej optymalne będzie zebranie ich w jeden większy (lub kilka większych plików) tak by zminimalizować ilość zapytań do serwera i jednocześnie rozmiar pobieranych plików (przy odpowiednio dobranym stosunku dużego obrazka do małych obrazków można sporo zyskać). Dzięki temu strona powinna ładować się o wiele szybciej, a i serwer mógłby trochę odetchnąć bo zamiast powiedzmy 64 małych plików wysyłałby jeden większy.

Oczywiście takie rozwiązanie można by ulepszyć poprzez stworzenie skryptu automatycznie generującego duży plik z kilku małych i automatycznie generującego wartości pozycji tła w pliku stylów....

Wszelkie za i przeciw tej koncepcji mile widziane ;)

Komentarze do wpisu "Koncepcja optymalizacyjna...":

1. adamka napisał(a):
28 października 2007, 20:29:21

Rozwiązanie jest bardzo dobre, jedynym problemem może być późniejsza zmiana w zestawie ikonek – gdy powiedzmy jedna ze środkowych ikon ma zostać podmieniona na szerszą – wtedy trzeba zmienić grafikę oraz CSSa. Choć gdyby dostępne było odpowiednie narzędzie (najlepiej online) to zapewne Twoje rozwiązanie znalazło by wielu amatorów (including me). Więc jak, zajmiesz się tym? :)

2. Dziudek napisał(a):
28 października 2007, 20:39:39

@adamka – no ja już powoli widzę taką webaplikację przed oczyma :D Muszę tylko nad tym dokładnie pomyśleć i znaleźć troszkę czasu ;) No i przeprowadzić sporo analiz, które dadzą odpowiedź na pytanie – kiedy taka operacja się opłaca, a kiedy nie ;) Bo jak stworzę ogromny plik to może się okazać większy niż kilkanaście mniejszych :) Ale sprawa do przemyślenia i obadania ;)

3. przecietny napisał(a):
28 października 2007, 20:44:37

Za: faktyczna optymalizacja liczby zapytań do serwera. Przy witrynach obleganych przez tysiące można odczuć, przy mniejszych – sztuka dla sztuki.
Przeciw: Komplikacja zwłaszcza przy automatycznym generowaniu, przyrost kodu i konieczność optymalizacji algoli do generowania by faktycznie pomagały, a nie szkodziły przez przeładowanie liczbą ikonek na jeden plik bo nagle zysk może przerodzić się w stratę.
Ogólnie temat do praktycznego przetestowania na jakimś żywym organizmie. Potencjalne korzyści i straty oraz wnioski ogólne do zaprezentowania.

4. Dziudek napisał(a):
28 października 2007, 20:47:26

@przecietny – no właśnie dlatego muszę pomyśleć nad jakimś narzędziem, które rozwiąże wszystkie Twoje „przeciw” – bo algorytm musi działać inteligentnie, tak by decydował czy opłaca się generować jeden plik czy nie :)

5. przecietny napisał(a):
28 października 2007, 20:53:09

No to dajesz kochany, dajesz. :P Potem jakiś solidny benchmark na 10k zapytań do strony i już wiemy na czym stoimy, ;) a bez dobrej optymalizacji i cachowania grafik stać będziemy kruchutko bo okaże się, że nagle wzrósł drastycznie czas oczekiwania na stronę mimo, że spadła liczba wywołań i potencjalnie ogólna wielkość plików ssanych z serwera.

6. Dziudek napisał(a):
28 października 2007, 20:59:03

@przecietny – tu cała sprawa według mnie rozbija się o to by statystycznie zbadać gdzie znajduje się swoisty „punkt krytyczny” takiej operacji – w tym wypadku jest to sytuacja kiedy ciężar generowanego obrazka i kodu CSS zrównuje się z ciężarem małych obrazków i zwykłego kodu CSS – wtedy i tak jesteśmy na plus bo ciągle ilość zapytań jest mniejsza. Ale jeżeli jest więcej do pobrania niż przed optymalizacją to operacja traci sens.

Dodatkowo warto zauważyć, że to rozwiązanie nadaje się raczej do stron ze „stałym” layoutem – bo generowanie dla każdego wywołania strony pliku nie ma sensu – serwer jeszcze bardziej dostanie w kość. Ale na przykład przy interfejsach jakichś aplikacji online, gdzie jest mnóstwo małych ikonek myślę, że by się to sprawdziło, a plik wystarczyło by generować raz i potem zapomnieć ;)

7. przecietny napisał(a):
28 października 2007, 21:06:47

Ale na plus możesz być nawet gdy wielkość tego jednego przekroczy wielkość wielu, sprawa rozbije się wtedy o czas odpowiedzi serwera na zapytanie i mimo sumarycznej przewagi wielkości wielu czas całkowity ładowania strony będzie mniejszy przy jednym zakładając całkowitą statyczność czyli żadnego algorytmu decydującego czy wiele czy jeden po drodze.

8. Dziudek napisał(a):
28 października 2007, 21:09:17

@przecietny – no w sumie tak… Jak widać problem jest nietrywialny ;) Muszę z tym zagadnieniem posiedzieć – może nie jest to uniwersalne rozwiązanie, ale w wielu przypadkach ma szanse się sprawdzić ;) W środę mam nudny wykład z TPI to pokombinuję >XD

9. przecietny napisał(a):
28 października 2007, 21:12:57

Zdecydowanie o uniwersalności w tym wypadku można zapomnieć, a w serwisach umożliwiających zmianę laya już w ogóle. Rozwiązanie i decyzja o jego zastosowaniu zależne będą również od testów serwera produkcyjnego i jego reakcji na takie rozwiązanie bo zbyt wiele tutaj jest czynników decydujących o efektywności takiego pomysłu.

10. Dziudek napisał(a):
28 października 2007, 21:15:15

@przecietny – no trzeba pokombinować, ale nawet jeżeli sprawdzi się to tylko w jednym (ale jakimś sensownym) wypadku, to warto nad tym posiedzieć ;) Mam cichą nadzieję, że jest o wiele więcej niż jeden wypadek kiedy to rozwiązanie się sprawdzi ;)

11. przecietny napisał(a):
28 października 2007, 21:19:20

No w kilku miejscach może mieć to sens to fakt ale zastosowanie zależeć będzie od indywidualnych decyzji przy wdrażaniu konkretnego projektu. Nie sądzę by dało się ten pomysł w jakikolwiek sposób zautomatyzować i pozwolić na szersze wykorzystanie gotowych skryptów do implementacji na dowolnej stronie.
BTW nie strasz mnie TPI do cholerki jasnej. Chciałbym zapomnieć o tej strasznej kobiecie, która nas biła ale nie mogę bo na każdym kroku przypominają mi tę traumę.

12. Dziudek napisał(a):
28 października 2007, 21:23:19

@przecietny – co do automatyzacji procesu – myślę nad aplikacją, która pozwoli takowy plik i style CSS wygenerować i oceni czy w ogóle jest to opłacalne – dzięki temu z tego rozwiązania mogłyby skorzystać osoby, którym by się to opłacało, a sama operacja wymagałaby tylko podania ID/klas elementów i grafik…

Co do TPI – nie wiem z kim miałeś, ale ja mam chyba z najnudniejszym wykładowcą na PŁ >XD Bez kofeiny przetrwać nie idzie… Zresztą mnie chyba wszystkie wykłady usypiają >XD

13. Witia napisał(a):
28 października 2007, 21:25:42

Nie żebym chciał umniejszać Twoją kreatywność :)
Takie rozwiązania można spotkać. Np. wszystkie pozycje menu w różnych stanach umieszczone na jednym obrazku:
http://superfluousbanter.org/archives/2004/05/navigation-matrix-reloaded/
(uwaga: jeśli ktoś używa AdBlocka, to może mu na tej stronie co nieco przyblokować).
Powyższy przykład jest dość skrajny. W praktyce częściej można spotkać przypadki, gdzie jeden obrazek jest zrobiony dla jednej pozycji menu i zawiera np. wersje dla :link, :hover i wyróżnienie aktualnego działu. Ma to tę zaletę, że użytkownik nie czeka na ściągnięcie kolejnej grafiki, gdy najedzie kursorem na pozycję menu i nie straszy go chwilowe puste miejsce w menu.

14. przecietny napisał(a):
28 października 2007, 21:28:44

Tak aplikacja, która ma zająć się tylko oceną i generowaniem statycznych rozwiązań to jest właściwe podejście, bo generowanie w locie tego to już przegięcie.
Co się zaś tyczy zasypiania na wykładach to cały mój rok podziwiał moje zdolności adaptacyjne do zasypiania w skrajnie trudnych warunkach na wykładach z fizyki u Wesołka. :P

15. Dziudek napisał(a):
28 października 2007, 21:37:20

@Witia – wiesz w sumie bym się zdziwił gdybym pierwszy wpadł na ten pomysł :D Ale i tak wykorzystanie w menu ma raczej rolę estetyczną – by tak jak piszesz nie pojawiało się to puste miejsce, a ja chcę optymalizacji ilości zapytań do serwera + ewentualnie rozmiaru pobieranych danych ;)

@przecietny – no teraz ją tylko napisać >XD Co do spania na wykładach to widzę jesteś mocny zawodnik >XD

16. jam łasica napisał(a):
28 października 2007, 22:27:15

„bo zamiast powiedzmy 64 małych plików wysyłałby jeden większy”

Pomysł chyba dobry, ale nie ładowałbym aż 60 obrazków w jeden ;) Jeden wielki plik mógłby pochłaniać dużo RAMu (zakładając, że używamy tylko parę obrazków z tych 64). Dodatkowo zmiana jednego małego obrazka, wymaga ponownego wysłania tego większego.

17. Dziudek napisał(a):
28 października 2007, 23:53:48

@jam łasica – generalnie koncepcja jest taka by wszystkie, a przynajmniej większość obrazków była używana… Bo inaczej to to bezsensowne, skoro i tak większość obrazków nie zostanie użyta… Sam „duży” plik nie byłby taki duży znowu, bo nie zapominajmy, że chodzi mi głównie o małe obrazki takie jak te narożniki z przykładu – więc obrazek złożony z 64 grafik 16 na 16 miałby rozmiar 128 na 128 pikseli… (Nie zapominajmy, że pomysł powstał dlatego, że potrzebuję obrazki 16 na 16 zaserwować tak by nie zamordować przeglądarki zapytaniami do serwera ;) ). Co do zmiany małego obrazka – ten problem będzie należał do aplikacji, którą chciałbym kiedyś (w domyśle – jak znajdę czas) napisać ;)

18. teamon napisał(a):
29 października 2007, 07:26:45

A mozeby tak, narzedzie ktoreby sie instalowalo na serwerze, konfigurowalo, wysylalo na serwer male obrazki, wpisujemy adres w przegldarce – skrypt tworzy nam duzy obrazek i tyle. Caly system uzywa duzego. W momencie potrzeby zmiany jakiegos malego obrazka, podmieniamy tylko malo, odpalamy skrypt a on podmienia tez duzo i plik css

19. rozie napisał(a):
29 października 2007, 08:26:48

Pomysł dobry i IMO ma sens także wtedy, gdy wykorzystasz tylko kilka ze ściągniętych obrazków. Uzasadnienie: kompresja dla wielu małych, podobnych plików połączonych w jeden zwykle lepsza niż suma dla każdego z osobna, masz większą szansę, że taki często używany obrazek będzie w cache’u serwera (niż wszystkie małe). Poza tym, z grafiki korzystają raczej ludzie na sensownych łączach, więc ich parę więcej nie zaboli (a na odpowiedź serwera czekać będą niezależnie od łącza). Taki prefetch będzie. ;) Zajętością ramu bym się nie przejmował – rozmawiamy o obrazkach rzędu kilobajtów… Na początek ładowałbym ‘suma oryginalnych obrazków + css, nie więcej jak 32kB’. Oczywiście najlepiej byłoby łączyć obrazki pod względem faktycznej ich używalności (jeśli klient przechodzi zwykle z podstrony A na podstronę B, to obrazki dla tych podstron trzymamy razem), ale to raczej trudno zmontować. Natomiast łączenie grafik per strona i/lub per częstotliwość wywołań dałoby się spokojnie optymalizować.

20. Zboczuch napisał(a):
29 października 2007, 12:31:40

Na listaparcie pisali o tym już ponad trzy lata temu:

http://www.alistapart.com/articles/sprites

21. cimlik napisał(a):
29 października 2007, 12:59:11

Oszczędność jest dosyć spora, bo jakieś 25 %.
Mimo to uważam, że takie rozwiązanie ma sens tylko w przypadku bardzo obciążonych stron. Webmasterzy muszą wtedy optymalizować wszystkie aspekty działania witryny.

22. Dziudek napisał(a):
29 października 2007, 18:06:49

@teamon – no dokładnie o tego rodzaju aplikacji myślałem ;)

@rozie – no to już są kwestie dostosowywania rozwiązania pod szersze zastosowania ;)

@Zboczuch – no pisali, ale po pobieżnej lekturze artykułu widzę, że chodzi raczej o to by efekt hover sprawnie działał, a to optymalizacji ilości zapytań do serwera jest moim głównym celem ;)

@cimlik – nie tylko bardzo obciążone strony tego potrzebują. Według mnie warto by każda strona miała sensowną ilość zapytań do serwera – jak już wspominałem chodzi mi po głowie projekt, który przy normalnym podejściu generowałby mnóstwo zapytań o malutkie pliki – a dzięki tej koncepcji, jeżeli moja teza się potwierdzi będę mógł zminimalizować ilość zapytań. Cierpliwość usera też ma swoje granice przy ładowaniu strony, a jak strona wykonuje 200 zapytań do serwera (mimo, że sama waży niewiele, bo pliki w większości po kilkaset bajtów) to to ssie ;)

23. MAX napisał(a):
30 października 2007, 13:47:57

zobacz na to: http://spritegen.website-performance.org/ ;))

CSS sprites are a way to reduce the number of HTTP requests made for image resources referenced by your site. Images are combined into one larger image at defined X and Y coorindates. Having assigned this generated image to relevant page elements the background-position CSS property can then be used to shift the visible area to the required component image.”

I jeszcze trochę do poczytania w temacie:
http://www.digital-web.com/articles/high_performance_websites/
http://www.digital-web.com/news/2007/10/What_are_you_doing_to_improve_your_websites_performance

24. Dziudek napisał(a):
30 października 2007, 17:18:07

@MAX – o fajnie widzieć taką aplikację ;) Więc odpada mi pisanie czegoś uniwersalnego ;D Ale i tak napiszę aplikację tego typu dla siebie :D Bo ja potrzebuję czegoś z zupełnie innym interfejsem ;)

Dodaj komentarz:

Textile Lite włączony ( szczegółowy opis znaczników ):
*strong* | # lista numerowana | * lista wypunktowana | _em_ | __italic__ | "link":http:// | bq. cytat.