2012-10-12 15 views
10

To nie jest prawdziwe pytanie o kodowanie, a raczej oświadczenie z prawdziwego świata.

Mam wcześniej noted, że zdarzenia DOMReady są powolne, bardzo powolne. Tak, zauważyłem podczas przeglądania źródła jQuery, że zdarzenie domena jQuery może być wyzwalane za pomocą $.ready(). Pomyślałem wtedy, że umieszczenie tego prostego skryptu wykonania tuż przed zamknięciem ciała powinno wywołać wszystkich słuchaczy "onDomReady", do których wcześniej przywiązywano przywiązanie. I tak, to działa zgodnie z oczekiwaniami:

 <script>$.ready()</script> 
</body> 

Oto dwa przykłady, ten mierzy MS spędził czekając na domready:

http://jsbin.com/aqifon/10

Jak widać, spust domready jest bardzo natywnie powolny, użytkownik musi czekać na całe 200-300 milisekund, zanim kopie domready.

W każdym razie, jeśli umieścimy $.ready() tuż przed zamknięciem znacznika BODY otrzymamy:

http://jsbin.com/aqifon/16

Zobacz różnicę? Wywołując domready ręcznie, możemy odciąć 100-300 ms opóźnienia wykonania. To ważna sprawa, ponieważ możemy polegać na jQuery, aby zająć się manipulacjami DOM, zanim je zobaczymy.

Teraz, na pytanie, nigdy nie widziałem, aby było to zalecane lub omówione wcześniej, ale nadal wydaje się, że jest to poważny problem z wydajnością. Wszystko zależy od optymalizacji samego kodu, co oczywiście jest dobre, ale na próżno, jeśli wykonanie jest opóźnione przez tak długi czas, że użytkownik widzi "błysk" unjQueryedContent ".

Wszelkie pomysły, dlaczego tak jest nie omawiany/zalecany częściej?

+0

Wszystko, co mogę powiedzieć, jest niesamowite. Mam nadzieję, że nikt nie wymyśli dobrego powodu, aby tego nie robić! –

+0

jest gotowy do domu w IE, zanim ciało jest zamknięte? – Ibu

+0

@Ibu tak, DOM jest gotowy, gdy zamykanie 'body' występuje we wszystkich znanych mi przeglądarkach. Chociaż jestem bardzo ciekawy, aby znaleźć przypadek użycia, gdy tak nie jest ... – David

Odpowiedz

3

Jakieś pomysły, dlaczego nie jest to omawiane/zalecane częściej?

Umieszczenie JavaScript tuż przed </body> zostało omówione dużo, a jak wiadomo jest to zalecane, jeśli szukasz szybsze ładowanie stron. Ręczne wyzwalanie programów obsługi jQuery ready jest w rzeczywistości słabo omówione. Czemu?Cóż, nie sądzę, istnieje jeden cel odpowiedź na to, ale postaram się przedstawić kilka możliwości tutaj:

  1. wydajność nie jest głównym celem jQuery (anthough to zdecydowanie problemem), a maniacyki wydajności zazwyczaj szukają lżejszych bibliotek do manipulacji DOM i obsługi zdarzeń w różnych przeglądarkach lub do samodzielnego uruchamiania.

  2. To dodatkowy krok i nie wygląda na czysty. jQuery stara się być czysty i elegancki, a zalecenie dodatkowego kroku inicjowania skryptów nie brzmi jak coś, co się wydarzy. Zaleca się powiązanie z ready, dlatego zaleca się wymuszenie .ready() i zignorowanie faktycznego zdarzenia przeglądarki wygląda "źle". Ktokolwiek się tym przejmuje, prawdopodobnie wie, że inicjowanie skryptów tuż przed </body> jest szybsze.

  3. Optymalizowanie DOMContentLoaded brzmi jak zadanie dla dostawców przeglądarek. Nie jestem pewien, dlaczego jest wolniejszy, i może nie ma zbyt wiele miejsca na optymalizację – w moim rozumieniu, wywoływanie skryptów init przed </body> powinno być zawsze najszybszym sposobem na zainicjowanie rzeczy (ponieważ jest wykonywane natychmiast podczas analizowania znacznika kontenera <script>, podczas gdy przeglądarki muszą zakończyć przetwarzanie całego pliku przed wyzwoleniem DOMContentLoaded).

Prawdopodobnie pamiętasz, że nie tak dawno temu powszechną praktyką było blokowanie <script> rozproszonych wszędzie w kodzie HTML. Potem przyszedł ruch standardów sieci i zalecił rozsądniejsze i łatwiejsze w utrzymaniu sposoby robienia rzeczy. To zawierało skrypty startowe z pojedynczego miejsca – początkowo, window.onload, które następnie uznano za problematyczne ze względu na powolność, a następnie emulację dla IE8 i poniżej. Wciąż jednak widzimy spaghetti-HTML ze skrypty wszędzie na co dzień tutaj na StackOverflow. Nie jestem więc pewien, czy zalecanie umieszczania skryptów przed końcem ciała jest dziś dobrym wezwaniem, ponieważ może być interpretowane jako licencja do dodawania skryptów w dowolnym miejscu ciała.

Wreszcie, jeśli naprawdę zależy ci na szybkim załadowaniu skryptu, a twój kod nie manipuluje modelem DOM, najszybszym sposobem jego załadowania jest umieszczenie go w <head> przed jakimkolwiek arkuszem stylów. I stwierdzam, że wystarczy powiedzieć, że nie ma srebrnej kuli, nie ma optymalnego sposobu uruchamiania skryptów, które są najszybsze i najbardziej eleganckie w każdym scenariuszu. Myślę, że właśnie dlatego społeczność trzyma się z zaleceniem czegoś, co wygląda zdrowo i ma tendencję do tworzenia łatwiejszego do utrzymania kodu, zamiast innych lepiej działających alternatyw.

4

Wywołując zdarzenie samodzielnie, mówisz do swoich programów do obsługi ready(), że dom został załadowany, ALE nie był może! Nie ma krótkiego cięcia zdarzenia DOM ready. jest naprawdę długi czas oczekiwania, a następnie użyj niesamowitych narzędzi do debugowania, takich jak firebug, chrome, itp.) Sprawdź swoje zasoby i pytania dotyczące ich czasu, wszystko to w czerni i bieli i wskaże, co zajmuje tak długo (prośby , renderowanie, ile zasobów itp.)

+0

Czy możesz umieścić rzeczywistą sytuację, gdy DOM jest * nie * synchronicznie gotowy, gdy 'body' się zamyka? – David

+0

Kto powiedział, że ciało jest gotowe tylko dlatego, że dotarłeś do znacznika. W DOM jest coś więcej niż tylko ciało. Opublikuję sytuację w realnym świecie zaraz po opublikowaniu, gdzie zagwarantujesz, że DOM został W PEŁNI załadowany przez twoją technikę dla wszystkich głównych przeglądarek (i wszystkie warunki wyścigu, blokady przeglądarki itp. Zostały pomyślnie rozwiązane) przed pierwszym Gotowy() wywoływacz jest wywoływany –

+0

Ok, zacznij tutaj: http://jsbin.com/aqifon/16.Zakodowałem strony z prawdziwego świata tak długo, jak długo jQuery był w pobliżu, i zawsze wprowadzałem rodzimy wyzwalacz przed zamknięciem ciała zamiast używania DOMReady. I nigdy nie słyszałem o żadnych sytuacjach, w których to nie zadziałało. – David

3

W rzeczywistości umieszczenie wywołania funkcji przed znacznikiem </body> powoduje, że używanie JQuery'a ready() jest bezcelowe. Po prostu wstaw natywne wywołanie funkcji JS-wrapper, która zawiera wywołania wszystkich innych funkcji, które powinny być wywołane na gotowym dokumencie.

Generalnie jest to działający (choć nieco zaśmiecający kod HTML, a zatem niedopuszczalny dla perfekcjonistów) alternatywa dla sytuacji, gdy autor nie potrzebuje/nie chce w ogóle używać jQuery. W takich sytuacjach wolałbym jednak używać rodzimej obsługi zdarzeń DOMContentLoaded obsługiwanej przez większość przeglądarek, w tym IE9 + (dla IE8 możemy użyć window.load() jako akceptowalnego kreślenia awaryjnego).

+0

Zgadzam się z pierwszym zdaniem, chociaż istnieje wiele "wtyczek" i innych dodatków programistycznych, które automatycznie owijają swoje zależne od DOM manipulacje w procedurze obsługi DOMReady. Zaproponowane przeze mnie rozwiązanie spowodowałoby ich znacznie wcześniej niż zwykle. – David

Powiązane problemy