Jak wykorzystać JavaScript i CSS do zwiększenia szybkości ładowania i wyświetlania strony dzięki ograniczeniu liczby połączeń i rozmiaru pobieranych danych między przeglądarką, a serwerem WWW.

Wstęp

Podczas ładowania strony serwer oraz przeglądarka odbywają szereg „rozmów”. Przy pierwszym wejściu przeglądarka prosi serwer o domyślną stronę (może to być index.php, index.html itd), a następnie prosi o treść wszystkich plików osadzonych w kodzie (obrazki,css, js, swf). Im więcej jest plików, tym więcej wiadomości krąży pomiędzy serwerem,a przeglądarką. Przy kolejnym wejściu na stronę przeglądarka po raz kolejny prosi serwer o stronę, a następnie o pliki. Tym razem prośba może zakończyć się odpowiedzią „już masz ten plik”. Przy odpowiednim ustawieniu serwera oraz zgrupowaniu plików (patrz css-sprites) można ograniczyć liczbę transmisji, a tym samym ilość pobieranych z serwera danych.

Pojedyncza wiadomość idąca z przeglądarki do serwera zawiera takie informacje jak:

  • obsługiwany format kompresji (Accept-Encoding : gzip,deflate)
  • określenie daty pliku (If-Modified-Since: Thu, 06 Oct 2005 14:41:32 GMT)

Serwer w swojej odpowiedzi umieszcza nagłówki typu:

  • data ostatniej modyfikacji (Last-Modified: Thu, 19 Nov 2009 18:21:49 GMT)
  • wygaśnięcie pliku (Expires: Thu, 19 Nov 1981 08:52:00 GMT)
  • sumę kontrolną (Etag: 9edb0c58430a61c5b32628fc4b37963e)

Javascript

Ograniczenie liczby plików js lub ich odpowiednie załadowanie pozwoli znacznie przyspieszyć ładowanie się strony, niezależnie czy będzie to pierwsze czy któreś z kolei wyświetlenie. Pliki js mają pewną szczególną właściwość, która może powodować wydłużenie czasu generowania strony.

Mianowicie są one ładowane jeden po drugim. Na powyższym rysunku przedstawione są dwie sytuacje: wiele małych plików js (ciemniejszy błękit) kontra jeden mniejszy i parę większych. Rezultat zawsze jest taki sam.

Można to obejść ładując pliki js przy pomocy odpowiedniej funkcji:

function loadScript(src) {
 var script = document.createElement("script");
 script.type = "text/java"+"script";
 document.getElementsByTagName("head")[0].appendChild(script);
 script.src = src;
}
loadScript( 'nicetitle.js' ) ;
loadScript( 'jquery.js' ) ;

Takie rozwiązanie pozwoli załadować wszystkie wymienione skrypty równolegle. Ładowane pliki niekoniecznie muszą być plikami .js. Równie dobrze mogą to być pliki .php. Sama funkcja działa w prosty sposób: tworzy ona nowy element script, ustawia w nim źródło i dokleja do nagłówka strony. Sposób ten nie jest jedyny, o pozostałych posłuchać można w YT na kanale google tech talks ( http://www.youtube.com/watch?v=52gL93S3usU ).

CSS

W przypadku plików css należy zwrócić uwagę na dwie rzeczy: długość ścieżki określającej element oraz liczbę tagów występujących w dokumencie. Idealnym rozwiązaniem jest zapisanie tak pliku css, aby występowały w nim jedynie bezpośrednie odwołania do danego elementu oraz aby nie było w nim zbędnych styli. Pierwsze zagadnienie związane jest ze sposobem przypisywania styli do poszczególnych elementów. Powiedzmy, że mamy następujący zapis:


#content table tr td span img.edit {

}

Przy takim zapisie przeglądarka musi znaleźć obrazki klasy edit. Zostawia tylko te, których rodzicem jest span. Następnie wyrzuca wszystkie elementy, których rodzicem nie jest td … Im dłuższa ścieżka „dojścia” do elementu, tym więcej roboty dla przeglądarki. Można to zmienić stosując zapis:


img.edit {

}

Trzeba tylko zadbać o to, aby styl został przypisany właściwym obrazkom.

W przypadku dużej liczby zbędnych styli, warto rozważyć wydzielenie ich do osobnego pliku. Dzięki temu ładowane będą tylko te style, które są faktycznie potrzebne w danej podstronie. Przy dużej liczbie odwiedzających pozwoli to zaoszczędzić transfer.

PHP zamiast .js/.css

Serwery www zapewniają kontrolę nad długością życia danego pliku. Wystarczy tylko odpalić mod_expires (w Apaczu), odpowiednio skonfigurować i cieszyć się mniejszym transferem ze strony powracających gości. Jeśli jednak nie ma dostępu do serwera, a admin odmawia dodania odpowiednich modułów (np. z przyczyn bezpieczeństwa), to do pracy należy zaprząc php. Przy okazji będzie można wykonać kilka innych operacji.

Na początek można wstawić w skrypcie funkcję ob_start z parametrem ob_gzhandler. Dzięki temu zabiegowi przeglądarki zgłaszające umiejętność obsługi skompresowanej treści będą w stanie pobrać mniejszy plik. Dodatkowo spakowaną treść można przechwycić przy użyciu ob_get_contents, przepuścić przez gzcompress i zapisać w odpowiednim pliku. Można także samodzielnie spakować plik i umieścić go na serwerze. Po odebraniu żądania serwer wyśle gotową treść, która nie będzie wymagała dodatkowego przetwarzania.

Wśród nagłówków wyróżnić należy te, które dotyczą czasu. Są to Expires, Last-Modified oraz If-Modified-Since. Pierwszy nagłówek określa jak długo plik będzie zawierać treść „zdatną do użytku”. Kopia pliku będzie pobierana z cache tak długo, aż data w systemie przekroczy zadany termin. Drugi oraz trzeci nagłówek są powiązane ze sobą, przy czym last-modified wysyłany jest przez serwer (wartość jest pobierana przez filemtime), a If-modified-since przez przeglądarkę. Jeżeli przeglądarka wyśle If-Modified-Since, to sprawdzamy czas i odsyłamy treść pliku (gdy się zmieniła) lub HTTP/1.1 304 Not Modified.

Na koniec

Zmniejszenie liczby plików, ograniczenie ich wielkości oraz zadbanie o czas przechowywania plików po stronie odwiedzających sprawi, że strona zacznie chodzić szybciej. Dodatkowym zyskiem będzie zmniejszenie miesięcznego transferu pochłanianego przez stronę (jest to szczególnie ważne, gdy strona „stoi” na limitowanym łączu).