Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00550 007457 13583517 na godz. na dobę w sumie
Jeszcze wydajniejsze witryny internetowe. Przyspieszanie działania serwisów WWW - książka
Jeszcze wydajniejsze witryny internetowe. Przyspieszanie działania serwisów WWW - książka
Autor: Liczba stron: 240
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-2579-6 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> webmasterstwo >> funkcjonalność stron
Porównaj ceny (książka, ebook, audiobook).

Poznaj najlepsze techniki zwiększania wydajności aplikacji internetowych!

Wydajność witryny stanowi jeden z podstawowych czynników jej sukcesu w sieci. Jednak bogactwo treści i popularność technologii Ajax w dzisiejszych aplikacjach internetowych wystawiają przeglądarki na ciężką próbę. W tej sytuacji potrzebujesz profesjonalnych informacji i skutecznych metod zwiększających wydajność Twojej strony WWW. Jeśli chcesz ją poprawić, powinieneś skorzystać z tej książki, ponieważ znajdziesz tu mnóstwo wartościowych technik, które pomogą Ci zoptymalizować działanie każdej aplikacji.

Książka 'Jeszcze wydajniejsze witryny internetowe. Przyspieszanie działania serwisów WWW' zawiera najbardziej aktualne porady, dzięki którym Twoja witryna otrzyma nowy zastrzyk energii. Z tego podręcznika dowiesz się, w jaki sposób Ajax wpływa na interakcję przeglądarek i serwerów, oraz nauczysz się wykorzystywać tę relację w celu identyfikacji elementów służących do poprawy wydajności aplikacji. Poznasz metody łączenia kodu osadzonego ze skryptami asynchronicznymi oraz kilka specyficznych technik przyspieszania JavaScriptu. Dzięki tej książce będziesz wiedział, jak zaoszczędzić cenne sekundy przez skrócenie czasu wczytywania, a także sprawisz, że Twoja witryna będzie działać jeszcze szybciej.

Szybkość ma znaczenie - zwiększ wydajność swojej strony WWW

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Jeszcze wydajniejsze witryny internetowe. Przyspieszanie dzia³ania serwisów WWW Autor: Steve Souders T³umaczenie: Leszek Sagalara ISBN: 978-83-246-2579-6 Tytu³ orygina³u: Even Faster Web Sites: Performance Best Practices for Web Developers Format: 168×237, stron: 240 Poznaj najlepsze techniki zwiêkszania wydajnoœci aplikacji internetowych! (cid:129) Jak stosowaæ technikê kodowania porcjami w celu szybszego kodowania stron? (cid:129) Jak pisaæ wydajny kod JavaScript? (cid:129) Jak rozdzielaæ zasoby na wiele domen? Wydajnoœæ witryny stanowi jeden z podstawowych czynników jej sukcesu w sieci. Jednak bogactwo treœci i popularnoœæ technologii Ajax w dzisiejszych aplikacjach internetowych wystawiaj¹ przegl¹darki na ciê¿k¹ próbê. W tej sytuacji potrzebujesz profesjonalnych informacji i skutecznych metod zwiêkszaj¹cych wydajnoœæ Twojej strony WWW. Jeœli chcesz j¹ poprawiæ, powinieneœ skorzystaæ z tej ksi¹¿ki, poniewa¿ znajdziesz tu mnóstwo wartoœciowych technik, które pomog¹ Ci zoptymalizowaæ dzia³anie ka¿dej aplikacji. Ksi¹¿ka „Jeszcze wydajniejsze witryny internetowe. Przyspieszanie dzia³ania serwisów WWW” zawiera najbardziej aktualne porady, dziêki którym Twoja witryna otrzyma nowy zastrzyk energii. Z tego podrêcznika dowiesz siê, w jaki sposób Ajax wp³ywa na interakcjê przegl¹darek i serwerów, oraz nauczysz siê wykorzystywaæ tê relacjê w celu identyfikacji elementów s³u¿¹cych do poprawy wydajnoœci aplikacji. Poznasz metody ³¹czenia kodu osadzonego ze skryptami asynchronicznymi oraz kilka specyficznych technik przyspieszania JavaScriptu. Dziêki tej ksi¹¿ce bêdziesz wiedzia³, jak zaoszczêdziæ cenne sekundy przez skrócenie czasu wczytywania, a tak¿e sprawisz, ¿e Twoja witryna bêdzie dzia³aæ jeszcze szybciej. (cid:129) Tworzenie responsywnych aplikacji WWW (cid:129) Wczytywanie skryptów bez blokowania (cid:129) £¹czenie skryptów asynchronicznych (cid:129) Pozycjonowanie skryptów osadzonych (cid:129) Pisanie wydajnego kodu JavaScript (cid:129) Skalowanie przy u¿yciu Comet (cid:129) Optymalizacja grafiki (cid:129) Rozdzielanie zasobów na wiele domen (cid:129) Upraszczanie selektorów CSS Szybkoœæ ma znaczenie – zwiêksz wydajnoœæ swojej strony WWW Spis treļci Wspóĥautorzy ...........................................................................................................................9 Jak podzielona jest ksiñĔka? Przedmowa ..............................................................................................................................11 11 13 14 15 15 16 16 Konwencje zastosowane w ksiñĔce UĔywanie przykäadowych kodów Podziökowania WydajnoĈè JavaScriptu WydajnoĈè sieci WydajnoĈè przeglñdarki 1. Wydajnoļë technologii Ajax ........................................................................................ 19 19 20 22 22 23 24 24 CoĈ za coĈ Zasady optymalizacji Ajax Przeglñdarka Fajerwerki JavaScript Podsumowanie Wñtkowanie Zapewnienie responsywnoĈci Co to znaczy „wystarczajñco szybko”? Pomiar opóĒnienia 2. Tworzenie responsywnych aplikacji WWW ...............................................................25 27 28 30 30 31 31 32 33 34 35 36 36 Web Workers Gears Timery Wpäyw zuĔycia pamiöci na czas odpowiedzi Pamiöè wirtualna Rozwiñzywanie problemów zwiñzanych z pamiöciñ Gdy opóĒnienia sñ zbyt duĔe Podsumowanie 3 3. Rozdzielanie przesyĥanej zawartoļci .........................................................................39 39 40 41 42 43 Nie wszystko naraz OszczödnoĈci z podziaäu Sposób podziaäu Niezdefiniowane symbole i sytuacje wyĈcigu Studium przypadku: Google Calendar Blokowanie skryptów Techniki pobierania skryptów XHR Eval XHR Injection Skrypt w IFrame Skrypt w elemencie DOM Skrypt odroczony Znacznik SCRIPT w instrukcji document.write 4. Wczytywanie skryptów bez blokowania ...................................................................45 45 47 47 48 49 50 50 50 51 53 54 55 WskaĒniki zajötoĈci przeglñdarki Zapewnianie (lub unikanie) wykonywania w kolejnoĈci Podsumowanie wyników Zwyciözcñ zostaje… Przykäad kodu: menu.js Sytuacja wyĈcigu Asynchroniczne zachowanie kolejnoĈci Technika 1.: Wywoäanie zwrotne ustalone Technika 2.: Window Onload Technika 3.: Timer Technika 4.: Script Onload Technika 5.: Degradujñce znaczniki skryptu 5. Ĥéczenie skryptów asynchronicznych ........................................................................59 60 62 63 64 65 66 66 67 69 70 73 76 76 77 79 79 81 Zarzñdzany kod XHR Techniki skryptu w elemencie DOM i skryptu w instrukcji document.write Google Analytics i Dojo YUI Loader Utility Wiele skryptów zewnötrznych Ogólne rozwiñzanie Pojedynczy skrypt Wiele skryptów AsynchronicznoĈè w praktyce Blokujñce dziaäanie skryptów osadzonych 6. Pozycjonowanie skryptów osadzonych .....................................................................85 85 86 87 88 89 Przeniesienie skryptów osadzonych na koniec dokumentu Asynchroniczne inicjowanie wykonywania skryptów UĔycie SCRIPT DEFER Zachowywanie kolejnoĈci wczytywania CSS i kodu JavaScript 4 _ Spis treļci Niebezpieczeþstwo: arkusz stylów przed skryptem osadzonym Skrypty osadzone nie sñ blokowane przez wiökszoĈè pobieraþ Skrypty osadzone sñ blokowane przez arkusze stylów Takie rzeczy siö zdarzajñ 90 90 91 92 Zarzñdzanie zasiögiem Sterowanie przepäywem Optymalizacja äaþcuchów znakowych Szybkie warunkowanie Szybkie pötle Stosowanie zmiennych lokalnych Powiökszanie äaþcucha zasiögu Wydajny dostöp do danych 7. Pisanie wydajnego kodu JavaScript ............................................................................95 95 97 98 100 103 103 107 112 112 114 115 116 118 120 Wprowadzanie przerw przy uĔyciu timerów Wzorce timerów do wprowadzania przerw Konkatenacja äaþcuchów Przycinanie äaþcuchów Unikaj skryptów o däugim czasie dziaäania Podsumowanie Jak dziaäa Comet? Techniki transportowe Odpytywanie WydäuĔone odpytywanie Wieczna ramka Strumieniowanie XHR Techniki transportowe przyszäoĈci 8. Skalowanie przy uŜyciu Comet ................................................................................. 123 123 125 125 125 127 128 130 130 131 131 132 132 133 Zarzñdzanie poäñczeniami Pomiar wydajnoĈci Protokoäy Rozwiñzania miödzydomenowe Efekty wdroĔenia w aplikacjach Podsumowanie Dlaczego to ma znaczenie? Co jest tego powodem? 9. Nie tylko gzip ............................................................................................................. 135 135 137 137 137 138 138 Szybki przeglñd Winowajca Przykäady popularnych Ĕóäwich podsäuchiwaczy Jak pomóc tym uĔytkownikom? Projektowanie pod kñtem zminimalizowania rozmiarów nieskompresowanych danych Edukowanie uĔytkowników BezpoĈrednie wykrywanie obsäugi gzip 139 143 144 Spis treļci _ 5 Dwa etapy upraszczajñce optymalizacjö grafiki Formaty plików graficznych Informacje wstöpne Charakterystyka róĔnych formatów graficznych Wiöcej o PNG Automatyczna bezstratna optymalizacja grafiki Optymalizacja plików PNG Usuwanie metadanych JPEG Konwersja plików GIF do formatu PNG Optymalizacja animacji GIF Smush.it Progresywna wersja formatu JPEG dla duĔych grafik 10. Optymalizacja grafiki ................................................................................................ 147 148 149 149 151 153 155 155 156 157 158 158 158 159 159 161 162 164 165 166 167 167 168 168 169 170 171 Efekty przezroczystoĈci stopniowanej AlphaImageLoader Problemy zwiñzane z filtrem AlphaImageLoader Progresywne rozszerzenie PNG8 o przezroczystoĈè stopniowanñ Unikaj skalowania grafiki Optymalizuj grafiki generowane Ikony favicon Ikona Apple touch PodejĈcie caäoĈciowe kontra podejĈcie moduäowe Wysoce zoptymalizowane obrazy CSS Sprite PrzezroczystoĈè stopniowana — unikaj AlphaImageLoader Optymalizacja Inne optymalizacje grafiki Podsumowanie ćcieĔka krytyczna Kto rozdziela zasoby? PrzejĈcie na HTTP/1.0 Rozdzielanie zasobów 11. Rozdzielanie zasobów na wiele domen ....................................................................173 173 175 177 179 179 180 180 180 Adres IP czy nazwa hosta? Ile domen? Jak podzieliè zasoby? Nowsze przeglñdarki 12. Wczeļniejsze wysyĥanie dokumentu .........................................................................181 181 183 185 186 186 187 188 188 189 Funkcja flush Buforowanie danych wyjĈciowych Kodowanie porcjami Funkcja flush i kompresja gzip Inne oprogramowanie poĈredniczñce Blokowanie domen przy uĔywaniu funkcji flush Przeglñdarki — ostatnia przeszkoda Funkcja flush poza PHP Lista kontrolna 6 _ Spis treļci Najbardziej kosztowny element DOM Elementy IFrame blokujñ zdarzenie onload Równolegäe pobierania z elementami IFrame 13. Oszczýdne wykorzystanie elementów IFrame .........................................................191 191 192 194 194 195 196 197 197 198 200 Skrypt przed elementem IFrame Arkusz stylów przed elementem IFrame Arkusz stylów za elementem IFrame Wspóädzielenie poäñczeþ w elementach IFrame Wspóädzielenie poäñczeþ w kartach i oknach Podsumowanie kosztu elementów IFrame Liczba poäñczeþ na serwer Rodzaje selektorów Selektory identyfikatora Selektory klas Selektory typu Selektory braci Selektory dziecka Selektory potomka Selektory uniwersalne Selektory atrybutu Pseudoklasy i pseudoelementy 14. Upraszczanie selektorów CSS ................................................................................... 201 201 202 202 203 203 203 203 203 204 204 204 204 205 206 206 209 211 211 Wpäyw zäoĔonych selektorów na wydajnoĈè (czasami) Selektory CSS, których naleĔy unikaè Czas dopasowywania Pomiar selektorów CSS w praktyce Od prawej do lewej Pisanie wydajnych selektorów CSS Klucz do tworzenia wydajnych selektorów CSS WydajnoĈè selektorów CSS Narzödzia nasäuchujñce HttpWatch Panel Sieè dodatku Firebug AOL Pagetest VRTA IBM Page Detailer Panel Resources narzödzia Web Inspector Fiddler Charles Wireshark Dodatek A Narzýdzia do analizy i poprawy wydajnoļci .................................................... 213 214 214 215 215 216 216 216 216 217 217 217 217 218 219 Firebug Web Inspector IE Developer Toolbar Narzödzia do analizy stron WWW Spis treļci _ 7 Narzödzia do analizy wydajnoĈci YSlow AOL Pagetest VRTA neXpert RóĔne Hammerhead Smush.it Cuzillion UA Profiler 219 220 221 223 223 224 224 225 226 227 Skorowidz .............................................................................................................................229 8 _ Spis treļci ROZDZIAĤ 2. Tworzenie responsywnych aplikacji WWW Ben Galbraith i Dion Almaer Technologia Ajax spowodowaäa, Ĕe wydajnoĈè witryn internetowych przestaäa byè traktowana tylko w kategoriach szybkiego wczytywania stron. Coraz wiöcej witryn korzysta z JavaScriptu, aby po wczytaniu strony zmieniè jej zawartoĈè i wprowadziè w locie nowñ treĈè. Tego rodzaju witryny przypominajñ tradycyjne programy komputerowe, a optymalizacja ich wydajnoĈci wymaga uĔycia innego zestawu technik niĔ w przypadku tradycyjnych witryn internetowych. Interfejsy uĔytkownika aplikacji WWW i tradycyjnych programów komputerowych majñ wspólny cel: odpowiedzieè na dziaäanie uĔytkownika tak szybko, jak to moĔliwe. W przy- padku odpowiedzi na Ĕñdanie wczytania strony WWW wiökszoĈè pracy zwiñzanej z respon- sywnoĈciñ przejmuje sama przeglñdarka. Otwiera ona poäñczenie internetowe z wybranñ wi- trynñ, analizuje kod HTML, wysyäa Ĕñdania wczytania powiñzanych zasobów itd. W oparciu o starannñ analizö tego procesu moĔemy tak zoptymalizowaè nasze strony, aby byäy szybciej wyĈwietlane, ale ostatecznie to przeglñdarka sprawuje kontrolö nad ich wczytywaniem i wy- Ĉwietlaniem. W przypadku dziaäania uĔytkownika dotyczñcego samej witryny (gdy nie powoduje ono zaäadowania nowej strony przez przeglñdarkö) mamy nad tym kontrolö. Musimy zapewniè responsywnoĈè kodu JavaScript wykonywanego w wyniku tego dziaäania. Aby lepiej zrozu- mieè, w jakim stopniu moĔemy kontrolowaè responsywnoĈè, niezbödne bödzie wyjaĈnienie sposobu dziaäania interfejsu uĔytkownika w przeglñdarce. Jak widaè na rysunku 2.1, gdy uĔytkownik pracuje z przeglñdarkñ, system operacyjny otrzymuje sygnaäy wejĈciowe z róĔnych urzñdzeþ podäñczonych do komputera, takich jak klawiatura lub mysz. System rozdziela te sygnaäy na aplikacje, do których powinny one trafiè, pakietuje je jako pojedyncze zdarzenia i umieszcza w kolejce dla danej aplikacji, zwanej kolejkñ zdarzeþ. Przeglñdarka internetowa, podobnie jak kaĔda inna aplikacja GUI, przetwarza nastöpnie po- szczególne zdarzenia umieszczone w swojej kolejce i na ich podstawie wykonuje na ogóä jed- nñ z dwóch rzeczy: sama obsäuguje dane zdarzenie (np. przez wyĈwietlenie menu, przeglñ- danie WWW, wyĈwietlenie okna preferencji itp.) lub wykonuje kod JavaScript znajdujñcy siö na stronie (np. kod JavaScript zawierajñcy procedurö obsäugi zdarzenia onclick), co przed- stawia rysunek 2.2. 25 Rysunek 2.1. System operacyjny kieruje wszystkie sygnaäy wejĈciowe uĔytkownika do kolejki zdarzeþ Rysunek 2.2. Przeglñdarka uĔywa pojedynczego wñtku do przetworzenia zdarzeþ z kolejki i wykonania kodu uĔytkownika Warto w tym miejscu wspomnieè, Ĕe jest to proces w zasadzie jednowñtkowy, tzn. przeglñ- darka uĔywa jednego wñtku, aby pobraè zdarzenie z kolejki, i albo robi coĈ sama („Przeglñ- danie WWW” na rysunku 2.2), albo wykonuje kod JavaScript. Wskutek tego przeglñdarka moĔe wykonaè tylko jedno z tych zadaþ naraz, a kaĔde z nich moĔe zapobiec wystñpieniu innego zdarzenia. 26 _ Rozdziaĥ 2. Tworzenie responsywnych aplikacji WWW KaĔda chwila spödzona przez przeglñdarkö na wykonywaniu kodu JavaScript to okres, w ciñgu którego nie moĔe ona odpowiadaè na inne zdarzenia uĔytkownika. Dlatego teĔ niezwykle istotne jest, aby kod JavaScript umieszczony na stronie byä wykonywany jak najszybciej. W prze- ciwnym razie strona WWW i sama przeglñdarka mogñ reagowaè z opóĒnieniem lub caäkiem zaprzestaè dziaäania. Trzeba tu zaznaczyè, Ĕe caäy ten wykäad o dziaäaniu przeglñdarki i systemu operacyjnego pod wzglödem obsäugi sygnaäów wejĈciowych i zdarzeþ jest tylko uogólnieniem obejmujñcym szeroki zakres przypadków, które w szczegóäach mogñ siö róĔniè. Jednak niezaleĔnie od róĔnic wszystkie przeglñdarki wykonujñ caäy kod JavaScript w jednym wñtku (chyba Ĕe uĔyjemy Web Workers, co zostanie omówione w dalszej czöĈci tego rozdziaäu), co sprawia, Ĕe z po- wodzeniem moĔna zastosowaè techniki zalecane w tym rozdziale. Co to znaczy „wystarczajéco szybko”? ãatwo powiedzieè, Ĕe kod powinien byè wykonywany „tak szybko, jak to moĔliwe”, ale cza- sami trzeba przeprowadziè operacje, które zajmujñ trochö czasu. Algorytmy szyfrujñce, zäoĔone generowanie grafiki i operacje na obrazach — to przykäady obliczeþ, które sñ czasochäonne niezaleĔnie od tego, ile wysiäku wäoĔymy w to, aby byäy one „tak szybkie, jak to moĔliwe”. JednakĔe, o czym wspomniaä Douglas w rozdziale 1., programiĈci szukajñcy sposobu na two- rzenie responsywnych, wysoko wydajnych witryn internetowych nie mogñ — i nie powinni — dñĔyè do tego celu przez optymalizowanie kaĔdego napisanego przez siebie fragmentu kodu. Prawda wyglñda inaczej: naleĔy optymalizowaè tylko to, co nie dziaäa wystarczajñco szybko. Dlatego teĔ istotne jest zdefiniowanie, co jest „wystarczajñco szybkie” w tym kontekĈcie. Na szczöĈcie ktoĈ juĔ to za nas zrobiä. Jacob Nielsen, znany i powaĔany ekspert w dziedzinie uĔytecznoĈci aplikacji WWW, w po- niĔszym cytacie1 kwestiö „wystarczajñcej szybkoĈci” przedstawia nastöpujñco: Wytyczne dotyczñce czasu reakcji dla aplikacji WWW sñ takie same jak dla wszystkich innych aplikacji. Pozostajñ one niezmienne juĔ od 37 lat i najprawdopodobniej nie zmieniñ siö bez wzglödu na to, jaka technologia zostanie zaimplementowana w przyszäoĈci. 0,1 sekundy: Ograniczenie pozwalajñce uĔytkownikom odnieĈè wraĔenie, Ĕe bezpoĈrednio operujñ obiektami w graficznym interfejsie uĔytkownika. Dla przykäadu jest to czas od zazna- czenia przez uĔytkownika kolumny w tabeli do podĈwietlenia kolumny lub zasygnalizowania w inny sposób, Ĕe zostaäa ona wybrana. Byäoby idealnie, gdyby byä to równieĔ czas reakcji na sortowanie kolumny — w takim przypadku uĔytkownik miaäby uczucie bezpoĈredniego sor- towania tabeli. 1 sekunda: Ograniczenie pozwalajñce uĔytkownikom odnieĈè wraĔenie swobodnej nawigacji w przestrzeni poleceþ bez koniecznoĈci nadmiernego oczekiwania na odpowiedĒ komputera. OpóĒnienie od 0,2 do 1 sekundy oznacza, Ĕe uĔytkownicy je zauwaĔñ i bödñ mieè wraĔenie, Ĕe komputer „pracuje” nad poleceniem, w przeciwieþstwie do sytuacji, gdy wykonanie polecenia jest bezpoĈrednim efektem dziaäania uĔytkownika. Przykäad: jeĈli nie moĔna posortowaè tabeli zgodnie z wybranñ kolumnñ w czasie krótszym niĔ 0,1 sekundy, trzeba to zrobiè w ciñgu 1 se- kundy, w przeciwnym razie uĔytkownicy odniosñ wraĔenie, Ĕe interfejs dziaäa ociöĔale, i stracñ 1 http://www.useit.com/papers/responsetime.html Co to znaczy „wystarczajéco szybko”? _ 27 poczucie päynnoĈci w wykonywaniu swojej pracy. W przypadku opóĒnieþ wiökszych niĔ 1 se- kunda naleĔy zasygnalizowaè uĔytkownikowi, Ĕe komputer pracuje nad problemem, np. przez zmianö ksztaätu kursora. 10 sekund: Ograniczenie dla uĔytkowników skupiajñcych swñ uwagö na zadaniu. Wszystko, co trwa däuĔej niĔ 10 sekund, wymaga procentowego wskaĒnika, a takĔe wyraĒnie wskazanego sposobu przerwania operacji. Trzeba zaäoĔyè, Ĕe wracajñc do interfejsu po opóĒnieniu däuĔ- szym niĔ 10 sekund, uĔytkownicy stracñ päynnoĈè wykonywania zadaþ i bödñ musieli siö „przestawiè”. OpóĒnienia däuĔsze niĔ 10 sekund sñ dopuszczalne tylko podczas naturalnych przerw w pracy uĔytkownika, np. przy przeäñczaniu zadaþ. Innymi säowy, jeĈli wykonywanie Twojego kodu JavaScript trwa däuĔej niĔ 0,1 sekundy, Twoja strona nie wywoäa wraĔenia päynnoĈci i szybkoĈci; jeĈli zajmie to däuĔej niĔ 1 sekundö, aplikacja bödzie siö wydawaè ociöĔaäa; przy opóĒnieniu przekraczajñcym 10 sekund uĔyt- kownik bödzie juĔ niezmiernie poirytowany. Takie sñ ostateczne wskazówki, jeĈli chodzi o defini- cjö „wystarczajñcej szybkoĈci”. Pomiar opóŚnienia Skoro znasz juĔ progi opóĒnieþ, nastöpnym etapem bödzie poznanie sposobów pomiaru szybkoĈci wykonywania kodu JavaScript, co pozwoli okreĈliè, czy nie przekracza ona wspo- mnianych wczeĈniej zakresów (sam musisz okreĈliè, jak szybko ma dziaäaè Twoja strona; na- szym celem jest utrzymanie wszystkich opóĒnieþ interfejsu poniĔej granicy 0,1 sekundy). Najäatwiejszym, najprostszym i prawdopodobnie najmniej precyzyjnym sposobem pomiaru opóĒnienia jest obserwacja przez czäowieka; po prostu uĔyj aplikacji na swojej docelowej platformie i sprawdĒ, czy ma wystarczajñcñ wydajnoĈè. W koþcu zapewnienie odpowiedniej wydajnoĈci interfejsu ma säuĔyè czäowiekowi, wiöc jest to wäaĈciwy sposób przeprowadzenia takich pomiarów (oczywiĈcie tylko nieliczni bödñ w stanie podaè czas opóĒnienia w sekundach lub uäamkach sekund; wiökszoĈè posäuĔy siö bardziej ogólnymi okreĈleniami, np. „szybki”, „powolny”, „zadowalajñcy” itp.). JeĈli jednak pragniesz uzyskaè bardziej precyzyjne wyniki, masz dwie moĔliwoĈci: röczne (logowanie) lub zautomatyzowane (profilowanie) oprzyrzñdowanie kodu. Röczne oprzyrzñdowanie kodu jest naprawdö proste. Powiedzmy, Ĕe mamy na stronie funk- cjö obsäugi zdarzenia, np.: div onclick= myJavaScriptFunction() ... /div Prostym sposobem dodania oprzyrzñdowania röcznego bödzie zlokalizowanie definicji funkcji myJavaScriptFunction() i dodanie do niej pomiaru czasu: function myJavaScriptFunction() { var start = new Date().getMilliseconds(); // tutaj jakiĞ skomplikowany kod var stop = new Date().getMilliseconds(); var executionTime = stop - start; alert( Wykonywanie funkcji myJavaScriptFunction() trwaĪo + executionTime + ´millisekund ); } PowyĔszy kod spowoduje otwarcie okna wyĈwietlajñcego czas wykonywania; milisekunda to 1/1000 sekundy, wiöc 100 milisekund odpowiada wspomnianemu wczeĈniej progowi 0,1 sekundy. 28 _ Rozdziaĥ 2. Tworzenie responsywnych aplikacji WWW Wiele przeglñdarek jest wyposaĔonych we wbudowanñ konsolö zapewniajñcñ funk- cjö log() (Firefox udostöpnia jñ w popularnym dodatku Firebug); osobiĈcie bardziej wolimy console.log() niĔ alert(). Istniejñ narzödzia przeprowadzajñce automatyczny pomiar czasu wykonywania kodu, ale zazwy- czaj stosuje siö je do innych celów. Zamiast do pomiaru dokäadnego czasu wykonywania funkcji narzödzia takie — zwane profilerami — sñ zwykle uĔywane do okreĈlenia wzglödnej iloĈci czasu, jaki zajmuje wykonanie zestawu funkcji; inaczej mówiñc, säuĔñ one do wy- krywania „wñskich gardeä” lub wolniej wykonywanych fragmentów kodu. Firebug (http://getfirebug.com/), popularny dodatek do przeglñdarki Firefox, zawiera profiler kodu JavaScript generujñcy komunikaty wyjĈciowe podobne do przedstawionych na rysunku 2.3. Rysunek 2.3. Profiler w dodatku Firebug Kolumna Czas przedstawia czas, jaki interpreter JavaScriptu poĈwiöciä ogóäem na wykonanie danej funkcji w okresie profilowania. Czösto zdarza siö, Ĕe jakaĈ funkcja wywoäuje inne funk- cje; kolumna Wäasny czas przedstawia iloĈè czasu poĈwiöconego na wykonywanie tylko okre- Ĉlonej funkcji, bez innych funkcji, które mogäy byè wywoäywane. MoĔna by sñdziè, Ĕe ta i inne kolumny podajñce czas przedstawiajñ precyzyjny pomiar czasu wykonywania funkcji. Okazuje siö jednak, Ĕe profilery wywoäujñ coĈ zbliĔonego do efektu obserwatora w fizyce: czynnoĈè obserwacji dziaäania kodu wpäywa na dziaäanie kodu. Profilery mogñ stosowaè jednñ z dwóch strategii: albo bödñ ingerowaè w kod bödñcy przed- miotem pomiarów przez dodanie specjalnego kodu zbierajñcego statystyki wydajnoĈci (chodzi o proste zautomatyzowanie tworzenia kodu przedstawionego na poprzednim listingu), albo pasywnie monitorowaè czas uruchamiania, sprawdzajñc, jaki fragment kodu wykonywany jest w danym momencie. Ostatnie z tych dwóch podejĈè w mniejszym stopniu wpäywa na wykonywanie profilowanego kodu, jednak odbywa siö to kosztem zebrania danych o niĔszej jakoĈci. Pomiar opóŚnienia _ 29 W dodatku Firebug wyniki ulegajñ dalszym znieksztaäceniom, poniewaĔ jego profiler wywoäuje wäasny proces wewnñtrz procesu Firebuga, co obniĔa wydajnoĈè kodu bödñcego przedmiotem pomiarów. Kolumna Procent w oknie dodatku Firebug pokazuje wzglödny czas wykonania: na interfejsie swojej strony moĔesz przeprowadziè jakieĈ wysokopoziomowe zadanie (np. kliknñè przycisk WyĈlij), a nastöpnie za pomocñ profilera dodatku Firebug sprawdziè, które funkcje zabierajñ najwiöcej czasu, i skupiè swoje wysiäki na ich optymalizacji. Gdy opóŚnienia sé zbyt duŜe Okazuje siö, Ĕe gdy Twój kod JavaScript zatrzymuje wñtek przeglñdarki na szczególnie däugi czas, wiökszoĈè przeglñdarek zainterweniuje i pozwoli uĔytkownikowi przerwaè wykonywa- nie kodu. Nie ma Ĕadnego standardu mówiñcego o tym, w jaki sposób przeglñdarki majñ okre- Ĉlaè, czy daè uĔytkownikowi takñ moĔliwoĈè (szczegóäowe informacje dotyczñce zachowania po- szczególnych przeglñdarek znajdujñ siö na stronie http://www.nczonline.net/blog/2009/01/05/ what-determines-that-a-script-is-long-running/). Wniosek jest prosty: nie wprowadzaj na swojñ stronö WWW Ēle napisanego kodu, którego wykonywanie moĔe trwaè potencjalnie bardzo däugo. Wétkowanie Po zidentyfikowaniu kodu, który zachowuje siö nieodpowiednio, nastöpnym etapem bödzie jego optymalizacja. Czasem jednak zadanie wykonywane przez taki kod moĔe wiñzaè siö z duĔym kosztem i nie da siö go w magiczny sposób zoptymalizowaè w celu jego przyspie- szenia. Czy taki scenariusz musi siö wiñzaè ze spowolnieniem dziaäania interfejsu? Czy nie ma Ĕadnego sposobu, aby zadowoliè naszych uĔytkowników? Tradycyjnym rozwiñzaniem w takich przypadkach jest skorzystanie z wñtków, aby odciñĔyè wñtek uĔywany do interakcji z uĔytkownikiem od wykonywania kodu powodujñcego duĔy koszt. W naszym scenariuszu umoĔliwi to przeglñdarce kontynuowanie przetwarzania zda- rzeþ z kolejki i zachowanie responsywnoĈci interfejsu, podczas gdy däugo dziaäajñcy kod bödzie wykonywany w innym wñtku (a system operacyjny zatroszczy siö o to, aby zarówno wñtek interfejsu uĔytkownika przeglñdarki, jak i wñtek wykonywany w tle sprawiedliwie korzy- staäy z zasobów komputera). JavaScript nie zawiera jednak obsäugi wñtków, dlatego w przypadku kodu JavaScript nie ma moĔliwoĈci utworzenia wñtku wykonujñcego w tle kod o duĔym koszcie. Co wiöcej, nie wy- glñda na to, aby ta sytuacja miaäa ulec zmianie. Brendan Eich, twórca JavaScriptu i dyrektor techniczny fundacji Mozilla, wyraziä siö doĈè jasno w tej kwestii2: ēeby pracowaè z systemami wñtkowania, musisz byè [wielki jak gracz NBA], a to oznacza, Ĕe wiökszoĈè programistów powinna uciec z päaczem. Ale tak nie zrobiñ. Zamiast tego, podobnie jak to jest w przypadku wiökszoĈci innych ostrych narzödzi, bödzie ich kusiè, Ĕeby pokazaè, jacy 2 http://weblogs.mozillazine.org/roadmap/archives/2007/02/threads_suck.html 30 _ Rozdziaĥ 2. Tworzenie responsywnych aplikacji WWW sñ wielcy. Wezmñ najbliĔszy jednowñtkowy kod i wepchnñ go w Ĉrodowisko wielowñtkowe lub w inny sposób doprowadzñ do sytuacji wyĈcigu. Sporadycznie efekty bödñ tragiczne, ale zbyt czösto skoþczy siö to tak, Ĕe mimo pokaleczenia sobie palców nikt nie wyniesie z tego nauki. Wñtki wprowadzajñ caäy szereg zakäóceþ, gäównie przez tworzenie sytuacji wyĈcigu, ryzyko zakleszczenia i pesymistycznñ blokadö obciñĔenia. I wciñĔ nie sñ na tyle skalowalne, aby mogäy w przyszäoĈci obsäuĔyè te wszystkie megardzenie i teraflopy. Dlatego moja standardowa odpowiedĒ na takie pytania, jak: „Kiedy dodasz wñtki do Java- Scriptu?”, brzmi: „Po twoim trupie!”. Biorñc pod uwagö wpäyw Brendana na branĔö i na przyszäoĈè JavaScriptu (który jest znaczny) oraz fakt, Ĕe wiele osób w duĔym stopniu podziela jego poglñdy, moĔna bezpiecznie przyjñè, Ĕe w JavaScripcie nieprödko pojawiñ siö wñtki. Istniejñ jednak inne rozwiñzania. Podstawowy problem z wñtkami polega na tym, Ĕe róĔne wñtki mogñ mieè dostöp do tych samych zmiennych i mogñ je modyfikowaè. To powoduje caäy szereg problemów, np. gdy wñtek A modyfikuje zmienne, które sñ aktywnie modyfiko- wane przez wñtek B itp. MoĔna by sñdziè, Ĕe przyzwoity programista poradzi sobie z tego rodzaju kwestiami, ale jak siö okazuje, Brendan twierdzi, Ĕe nawet najlepsi z nas popeäniajñ okropne pomyäki w tej dziedzinie. Zapewnienie responsywnoļci To, czego potrzebujemy, to odnoszenie korzyĈci z wñtków — równolegäego wykonywania zadaþ — bez ryzyka, Ĕe bödñ one sobie nawzajem wchodziè w paradö. Firma Google w swoim popularnym dodatku do przeglñdarek o nazwie Gears zaimplementowaäa wäaĈnie takie API: WorkerPool. W zasadzie umoĔliwia ono gäównemu wñtkowi JavaScript przeglñdarki two- rzenie dziaäajñcych w tle wñtków roboczych (ang. workers), które rozpoczynajñc pracö, otrzy- mujñ pewne proste komunikaty (np. stan autonomiczny, bez odniesieþ do wspólnych zmien- nych) z wñtku przeglñdarki i zwracajñ komunikat po jej zakoþczeniu. DoĈwiadczenia z dziaäania tego API w dodatku Gears sprawiäy, Ĕe w wielu przeglñdarkach (np. Safari 4, Firefox 3.13) wprowadzono bezpoĈredniñ obsäugö wñtków roboczych w oparciu o wspólne API zdefiniowane w specyfikacji HTML 5. Opcja ta jest znana pod nazwñ Web Workers. Web Workers RozwaĔmy, w jaki sposób wykorzystaè API Web Workers do odszyfrowania wartoĈci. PoniĔszy listing przedstawia sposób tworzenia i zainicjowania wñtku roboczego: // utworzenie i rozpoczĊcie wykonywania wątku roboczego var worker = new Worker( js/decrypt.js ); // zarejestrowanie procedury obsáugi zdarzenia, która zostanie wykonana, // gdy wątek roboczy wyĞle komunikat do wątku gáównego worker.onmessage = function(e) { alert( Odszyfrowana wartoŁð to + e.data); } // wysáanie komunikatu do wątku roboczego, w tym przypadku bĊdzie to wartoĞü do odszyfrowania worker.postMessage(getValueToDecrypt()); 3 Przeglñdarka Firefox nosiäa numer 3.1 w wersji beta, ostatecznie jednak zostaäa wydana jako Firefox 3.5 — przyp. täum. Zapewnienie responsywnoļci _ 31 Przyjrzyjmy siö teraz hipotetycznej zawartoĈci skryptu js/decrypt.js: // zarejestrowanie funkcji obsáugi komunikatów przekazywanych przez wątek gáówny onmessage = function(e) { // pobranie otrzymanych danych var valueToDecrypt = e.data; // Do zrobienia: zaimplementowaü w tym miejscu funkcjĊ deszyfrującą // zwrócenie wartoĞci do wątku gáównego postMessage(decryptedValue); } Wszystkie potencjalnie kosztowne (tj. o däugim czasie dziaäania) operacje JavaScriptu wyko- nywane przez Twojñ stronö powinny byè przekazywane do wñtków roboczych. Dziöki temu Twoja aplikacja bödzie dziaäaè z peänñ szybkoĈciñ. Gears JeĈli znajdziesz siö w sytuacji, Ĕe Twoja aplikacja ma dziaäaè w przeglñdarce, która nie obsäuguje API Web Workers, istnieje kilka innych rozwiñzaþ. W poprzednim rozdziale wspomnieliĈmy o dodatku Gears firmy Google; dziöki niemu moĔna uzyskaè coĈ bardzo podobnego do Web Workers w przeglñdarce Internet Explorer, w starszych wersjach Firefoksa i starszych wer- sjach Safari. API wñtków roboczych w Gears jest podobne do API Web Workers, choè nie identyczne. PoniĔej przedstawione zostaäy dwa poprzednie listingi z kodem skonwertowanym na API Gears, po- czñwszy od kodu wykonywanego w gäównym wñtku w celu zainicjowania wñtku roboczego: // utworzenie puli wątków, która zainicjuje wątki robocze var workerPool = google.gears.factory.create( beta.workerpool ); // zarejestrowanie funkcji obsáugi zdarzeĔ, która bĊdzie odbieraü komunikaty z wątków roboczych workerPool.onmessage = function(ignore1, ignore2, e) { alert( Odszyfrowana wartoŁð to + e.body); } // utworzenie wątku roboczego var workerId = workerPool.createWorkerFromUrl( js/decrypt.js ); // wysáanie komunikatu do wątku roboczego workerPool.sendMessage(getValueToDecrypt(), workerId); A tak wyglñda zawartoĈè skryptu js/decrypt.js w wersji Gears: var workerPool = google.gears.workerPool; workerPool.onmessage = function(ignore1, ignore2, e) { // pobranie przysáanych danych var valueToDecrypt = e.body; // Do zrobienia: zaimplementowaü w tym miejscu funkcjĊ deszyfrującą // zwrócenie wartoĞci do wątku gáównego workerPool.sendMessage(decryptedValue, e.sender); } 32 _ Rozdziaĥ 2. Tworzenie responsywnych aplikacji WWW Wiýcej na temat Gears Warto poznaè kilka faktów z historii powstania wñtków roboczych Gears, poniewaĔ zostaäy one wymyĈlone z bardzo praktycznych wzglödów. Dodatek Gears zostaä utworzony przez zespóä Google, który staraä siö zmusiè przeglñdarkö do wykonywania zadaþ, jakich nie byäa wtedy w stanie wykonaè (dziaäo siö to przed powstaniem Google Chrome — ale nawet majñc Chrome, Google chce, aby moĔliwie jak najwiöksza liczba uĔytkowników mogäa wy- konywaè zäoĔone zadania za pomocñ ich aplikacji WWW). WyobraĒ sobie, Ĕe chciaäbyĈ zbudowaè Gmail Offline — czego byè potrzebowaä? Po pierw- sze, musiaäbyĈ znaleĒè sposób na lokalne buforowanie dokumentów i ich przechwytywanie, aby — gdy przeglñdarka spróbuje uzyskaè dostöp do strony http://mail.google.com/ — wy- Ĉwietliäa siö Ĕñdana strona, a nie komunikat o braku poäñczenia. Po drugie, wymagaäoby to jakiejĈ metody przechowywania wiadomoĈci e-mail, zarówno tych nowych, jak i starych. MoĔna by to zrobiè na wiele sposobów, ale skoro dobrze znany SQLite jest obecny w wiök- szoĈci nowych przeglñdarek i doäñczany do wielu systemów operacyjnych, dlaczego tego nie wykorzystaè? Tutaj wäaĈnie tkwi problem. OmawialiĈmy kwestie zwiñzane z jednowñtkowñ przeglñdarkñ. WyobraĒ sobie teraz takie operacje, jak zapisywanie nowych wiadomoĈci e-mail do bazy danych lub wykonywanie däugich zapytaþ. MoĔemy zablokowaè interfejs uĔytkownika w czasie, gdy baza danych wykonuje swojñ pracö — opóĒnienia mogñ byè ogromne! Zespóä pracujñcy nad Gears musiaä sobie jakoĈ z tym poradziè. Dodatek Gears moĔe robiè, co chce, wiöc z äatwoĈciñ moĔna byäo obejĈè brak wñtków w JavaScripcie. Skoro jednak wspóäbieĔnoĈè stanowi ogól- ny problem, czemu nie udostöpniè tej moĔliwoĈci na zewnñtrz? Tak powstaäo API Worker- Pool, które doprowadziäo do powstania Web Workers w standardzie HTML 5. Te dwa API róĔniñ siö nieznacznie, ale wynika to stñd, Ĕe Web Workers jest czymĈ w rodzaju wersji 2.0 pionierskiego API Gears; niebawem Gears powinien zostaè wyposaĔony w obsäu- gö standardowego API. Powstaäy juĔ biblioteki poĈredniczñce, bödñce czymĈ w rodzaju pomostu miödzy istniejñcym API Gears a standardowym API Web Workers, których moĔna uĔywaè nawet bez Gears lub Web Workers (stosujñc setTimeout(), co zostanie omówione w dalszej czöĈci tego rozdziaäu). Timery Inne podejĈcie, popularne przed powstaniem Gears i Web Workers, polegaäo na podzieleniu däugotrwaäych operacji na mniejsze czöĈci i kontrolowaniu ich dziaäania przy uĔyciu timerów JavaScriptu. Np.: var functionState = {}; function expensiveOperation() { var startTime = new Date().getMilliseconds(); while ((new Date().getMilliseconds() - startTime) 100) { // Do zrobienia: zaimplementowaü dáugotrwaáą operacjĊ w taki sposób, // aby caáa praca byáa wykonywana w mniejszych fragmentach, // trwających krócej niĪ 100 ms, z przekazywaniem stanu do functionState // poza tą funkcją; powodzenia ;-) } if (!functionState.isFinished) { // ponownie wprowadziü dáugotrwaáą operacjĊ 10 ms po wyjĞciu; // warto poeksperymentowaü z wiĊkszymi wartoĞciami, aby zachowaü // wáaĞciwe proporcje miĊdzy responsywnoĞcią a wydajnoĞcią Zapewnienie responsywnoļci _ 33 setTimeout(expensiveOperation(), 10); } } Dzielñc operacjö w przedstawiony sposób, zachowamy responsywnoĈè interfejsu, ale — jak wskazuje komentarz w listingu — skonstruowanie takiej operacji moĔe byè trudne (a nawet niewykonalne). Wiöcej informacji na temat takiego uĔycia metody setTimeout() zawiera punkt „Wprowadzanie przerw przy uĔyciu timerów” na stronie 116. Z podejĈciem tym wiñĔe siö inna podstawowa kwestia. WiökszoĈè nowoczesnych kompute- rów wyposaĔona jest w procesory o kilku rdzeniach, co oznacza, Ĕe mogñ pracowaè napraw- dö wielowñtkowo (podczas gdy wczeĈniejsze procesory jedynie emulowaäy wielowñtkowoĈè przez szybkie przeäñczanie siö miödzy zadaniami). Röczne przeäñczanie zadaþ zaimplemen- towane za pomocñ Javascriptu, jakie miaäo miejsce w przedstawionym listingu, nie moĔe wykorzystywaè takich architektur; a wiöc nie uĔyjemy caäej mocy procesora, zmuszajñc jeden z rdzeni do wykonania caäej pracy. A zatem moĔliwe jest przeprowadzanie däugotrwaäych operacji w gäównym wñtku przeglñ- darki i zachowanie responsywnoĈci interfejsu, ale äatwiejsze i wydajniejsze bödzie uĔycie wñtków roboczych. XMLHttpRequest Caäa ta dyskusja na temat wñtkowania nie byäaby kompletna, gdybyĈmy nie wspomnieli o XMLHttpRequest (w skrócie XHR), który umoĔliwiä rewolucjö, jakñ byä Ajax. UĔywajñc XHR, strona WWW moĔe wysäaè komunikat i otrzymaè odpowiedĒ w caäoĈci w Ĉrodowisku JavaScript, co pozwala uzyskaè zäoĔonñ interaktywnoĈè bez koniecznoĈci wczytywania nowych stron. XHR ma dwa proste tryby dziaäania: synchroniczny i asynchroniczny. W trybie asynchro- nicznym XHR jest w zasadzie wñtkiem Web Worker, tyle Ĕe posiada wyspecjalizowane API; w istocie w poäñczeniu z innymi funkcjami powstajñcej specyfikacji HTML 5 moĔna odtwo- rzyè dziaäanie XHR za pomocñ wñtków roboczych. W trybie synchronicznym XHR dziaäa w taki sposób, Ĕe caäñ swñ pracö wykonuje w gäównym wñtku przeglñdarki, co sprawia, Ĕe opóĒ- nienia w interfejsie uĔytkownika trwajñ tyle czasu, ile potrzeba XHR na wysäanie jego Ĕñda- nia i przeanalizowanie odpowiedzi z serwera. Dlatego teĔ nigdy nie uĔywaj XHR w trybie synchronicznym, gdyĔ moĔe to doprowadziè do nieprzewidzianych opóĒnieþ w funkcjo- nowaniu interfejsu uĔytkownika, znacznie wykraczajñcych poza dopuszczalne granice. Wpĥyw zuŜycia pamiýci na czas odpowiedzi W tworzeniu responsywnych stron WWW wystöpuje jeszcze inny kluczowy aspekt: zarzñ- dzanie pamiöciñ. Podobnie jak w wielu nowoczesnych jözykach wysokiego poziomu, które zawierajñ elementy niskopoziomowego zarzñdzania pamiöciñ, tak i w wiökszoĈci Ĉrodowisk uruchomieniowych JavaScriptu wystöpuje mechanizm automatycznego oczyszczania pamiöci (ang. garbage collection, w skrócie GC). MoĔe to byè cudowne rozwiñzanie, uwalniajñce programi- stów od nuĔñcych detali kojarzñcych siö bardziej z ksiögowoĈciñ niĔ z programowaniem. Automatyczne zarzñdzanie pamiöciñ wiñĔe siö jednak z pewnym kosztem. Wszystkie z wyjñt- kiem najbardziej wyrafinowanych implementacji GC „zatrzymujñ caäy Ĉwiat”, przeprowa- dzajñc oczyszczanie pamiöci, tzn. „zamraĔajñ” caäe Ĉrodowisko (wäñcznie z tym, co nazwaliĈmy 34 _ Rozdziaĥ 2. Tworzenie responsywnych aplikacji WWW gäównym wñtkiem JavaScript przeglñdarki), podczas gdy same wykonujñ caäñ masö czynno- Ĉci zwiñzanych z tworzeniem obiektów oraz wyszukiwaniem tych, które nie sñ juĔ uĔywane i które moĔna zutylizowaè do nieuĔywanych obszarów pamiöci. W przypadku wiökszoĈci aplikacji proces GC jest caäkowicie przezroczysty; okresy zabloko- wania Ĉrodowiska uruchomieniowego sñ na tyle krótkie, Ĕe caäkowicie umyka to uwadze uĔyt- kownika. Jednak w miarö zajmowania przez aplikacjö coraz wiökszych obszarów pamiöci wydäu- Ĕa siö czas niezbödny do wyszukania nieuĔywanych obiektów i ostatecznie moĔe osiñgnñè poziom, który bödzie zauwaĔalny dla uĔytkownika. Gdy to nastñpi, aplikacja w doĈè regularnych odstöpach czasu bödzie dziaäaè mniej lub bar- dziej ociöĔale; w miarö narastania problemu moĔe dojĈè nawet do zablokowania przeglñdarki. Oba te efekty mogñ doprowadziè uĔytkownika do frustracji. WiökszoĈè nowoczesnych platform dostarcza wyrafinowanych narzödzi umoĔliwiajñcych monitorowanie wydajnoĈci procesu GC w Ĉrodowisku uruchomieniowym i podglñd bieĔñcego zestawu analizowanych obiektów w celu zdiagnozowania problemów zwiñzanych z oczysz- czaniem pamiöci. Niestety, Ĉrodowiska uruchomieniowe JavaScriptu nie mieszczñ siö w tej kategorii. Co gorsza, nie istniejñ Ĕadne narzödzia, które mogäyby poinformowaè programistö o tym, kiedy nastöpuje oczyszczanie pamiöci lub ile czasu trwa jego przeprowadzenie. Wykorzy- stujñc je, moĔna by sprawdziè, czy zaobserwowane opóĒnienia majñ zwiñzek z procesem oczyszczania pamiöci. Brak takich narzödzi jest powaĔnñ niedogodnoĈciñ dla twórców zäoĔonych aplikacji Java- Script dziaäajñcych w oparciu o przeglñdarki. Na razie programiĈci mogñ jedynie zgadywaè, czy za opóĒnienia interfejsu uĔytkownika odpowiada mechanizm automatycznego oczyszcza- nia pamiöci. Pamiýë wirtualna Istnieje jeszcze inne niebezpieczeþstwo zwiñzane z pamiöciñ: stronicowanie. W systemach operacyjnych mamy dwa rodzaje pamiöci udostöpnianej aplikacjom: fizyczna i wirtualna. Pamiöè fizyczna to niezwykle szybkie moduäy RAM zamontowane w komputerze; pamiöè wirtualna znajduje siö na znacznie wolniejszych urzñdzeniach pamiöci masowej (np. na dysku twardym), które swojñ stosunkowñ powolnoĈè nadrabiajñ znacznie wiökszñ dostöpnñ prze- strzeniñ pamiöci. JeĈli wymagania pamiöciowe Twojej strony WWW wzrosnñ w znacznym stopniu, system operacyjny moĔe byè zmuszony do rozpoczöcia stronicowania, niezwykle powolnego proce- su, przez co inne procesy bödñ musiaäy zwolniè zajmowanñ przez siebie pamiöè fizycznñ, aby udostöpniè miejsce na rosnñcy apetyt przeglñdarki. Proces ten nazywa siö stronicowaniem, poniewaĔ wszystkie nowoczesne systemy operacyjne dzielñ pamiöè na pojedyncze strony, tj. najmniejsze jednostki pamiöci, które sñ odwzorowywane do pamiöci fizycznej lub wirtualnej. W trakcie stronicowania strony te sñ przenoszone z pamiöci fizycznej do pamiöci wirtualnej (tj. z pamiöci RAM na dysk twardy) lub odwrotnie. Spadek wydajnoĈci spowodowany stronicowaniem róĔni siö od przerw wywoäywanych pro- cesem oczyszczania pamiöci; stronicowanie powoduje ogólne, wszechobecne spowolnienie, natomiast opóĒnienia w procesie GC przejawiajñ siö zwykle w formie dyskretnych, pojedyn- czych przerw wystöpujñcych w okreĈlonych przedziaäach czasowych — choè däugoĈè tych Zapewnienie responsywnoļci _ 35 przerw roĈnie wraz z upäywem czasu. NiezaleĔnie od tych róĔnic kaĔdy z tych problemów sta- nowi znaczñce zagroĔenie dla osiñgniöcia Twojego celu, jakim jest utworzenie responsywnego interfejsu uĔytkownika. Rozwiézywanie problemów zwiézanych z pamiýcié Jak wspomnieliĈmy wczeĈniej, nie znamy Ĕadnych dobrych narzödzi do diagnostyki pamiöci przeznaczonych dla aplikacji JavaScript uruchamianych w przeglñdarce. Póki co naleĔy ob- serwowaè zajötoĈè pamiöci procesu przeglñdarki (szczegóäowe informacje na temat pomiaru zajötoĈci pamiöci przez procesy w systemach Windows i OS X zawiera sekcja „Measuring Memory Use” pod adresem http://blog.pavlov.net/2008/03/11/firefox-3-memory-usage/). JeĈli pod- czas dziaäania aplikacji zajötoĈè pamiöci wzrasta znacznie powyĔej akceptowanych wartoĈci, sprawdĒ, czy w kodzie Twojej aplikacji sñ jakieĈ moĔliwoĈci optymalizacji zuĔycia pamiöci. JeĈli okaĔe siö, Ĕe masz problem zwiñzany z pamiöciñ, powinieneĈ poszukaè moĔliwoĈci jej oczyszczenia, jeĈli jeszcze tego nie zrobiäeĈ. MoĔesz to zrobiè przez: x uĔycie säowa kluczowego delete w celu usuniöcia z pamiöci zbödnych obiektów JavaScript, x usuniöcie zbödnych wözäów z modelu DOM strony WWW. PoniĔszy listing przedstawia sposób przeprowadzenia obu tych zadaþ: var page = { address: http://jakis/adres/url }; page.contents = getContents(page.address); ... // póĨniej zawartoĞü nie bĊdzie juĪ dáuĪej potrzebna delete page.contents; ... var nodeToDelete = document.getElementById( redundant ); // usuniecie wĊzáa z modelu DOM (co moĪna zrobiü jedynie // przez wywoáanie do removeChild() z wĊzáa nadrzĊdnego) // i równoczesne usuniĊcie wĊzáa z pamiĊci delete nodeToDelete.parent.removeChild(nodeToDelete); OczywiĈcie jest jeszcze wiele moĔliwoĈci ulepszeþ w zakresie optymalizacji zuĔycia pamiöci przez strony WWW. W fundacji Mozilla zajmujemy siö obecnie tworzeniem narzödzi przeznaczonych do rozwiñzywania tego rodzaju problemów. W chwili gdy czytasz tö ksiñĔkö, co najmniej jedno z takich narzödzi powinno byè juĔ dostöpne pod adresem http://labs.mozilla.com. Podsumowanie Ajax zapoczñtkowaä nowñ erö stron WWW dziaäajñcych w oparciu o JavaScript. Sñ one w rze- czywistoĈci aplikacjami dziaäajñcymi w przeglñdarce i jeĈli chodzi o interfejs uĔytkownika, pod- legajñ takim samym wymogom jak kaĔda inna aplikacja. Istotne jest to, aby zapewniaäy one responsywnoĈè interfejsu przez zminimalizowanie operacji wykonywanych w gäównym wñtku aplikacji. 36 _ Rozdziaĥ 2. Tworzenie responsywnych aplikacji WWW Web Workers to potöĔne nowe narzödzie, które moĔna wykorzystaè do przerzucenia skom- plikowanych operacji zagraĔajñcych responsywnoĈci interfejsu uĔytkownika. JeĈli nie moĔna uĔyè Web Workers, moĔemy wykorzystaè dodatek Gears i timery JavaScriptu. Zäe zarzñdzanie pamiöciñ moĔe doprowadziè do powstania problemów zwiñzanych z wy- dajnoĈciñ interfejsu uĔytkownika. Mimo braku dobrych narzödzi do rozwiñzywania proble- mów z pamiöciñ programiĈci mogñ obserwowaè wykorzystanie pamiöci przez przeglñdarkö i w razie wystñpienia problemów podjñè odpowiednie kroki w celu zminimalizowania zajö- toĈci pamiöci przez aplikacjö. Dobra wiadomoĈè jest taka, Ĕe trwajñ juĔ prace nad utworzeniem narzödzi do rozwiñzywania problemów z pamiöciñ. Podsumowanie _ 37
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Jeszcze wydajniejsze witryny internetowe. Przyspieszanie działania serwisów WWW
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: