Jeśli zależy Ci tylko na wydajności, większość porad w tym wątku jest błędna i staje się coraz bardziej błędna w erze SPA, gdzie możemy założyć, że strona bez kodu JS jest bezużyteczna. Spędziłem niezliczone godziny optymalizując czasy ładowania strony SPA i weryfikując te wyniki w różnych przeglądarkach. Ogólnie wzrost wydajności poprzez zmianę orkiestracji kodu HTML może być dość dramatyczny.
Aby uzyskać najlepszą wydajność, musisz myśleć o stronach jak o dwuetapowych rakietach. Te dwa etapy z grubsza odpowiadają fazom <head>
i <body>
, ale myśl o nich jako o <static>
i <dynamic>
. Część statyczna jest w zasadzie stałą struną, którą wpychasz w dół rury odpowiedzi tak szybko, jak to tylko możliwe. Może to być trochę trudne, jeśli używasz wielu programów pośredniczących, które ustawiają pliki cookie (należy je ustawić przed wysłaniem zawartości http), ale w zasadzie jest to po prostu opróżnienie buforu odpowiedzi, miejmy nadzieję, że przed wskoczeniem do jakiegoś kodu szablonu (brzytwa, php, etc) na serwerze. Może się to wydawać trudne, ale po prostu wyjaśniam to źle, ponieważ jest prawie trywialne. Jak można się domyślić, ta statyczna część powinna zawierać wszystkie elementy javascript wbudowane i zminimalizowane. Wyglądałoby to jakoś
<!DOCTYPE html>
<html>
<head>
<script>/*...inlined jquery, angular, your code*/</script>
<style>/* ditto css */</style>
</head>
<body>
<!-- inline all your templates, if applicable -->
<script type='template-mime' id='1'></script>
<script type='template-mime' id='2'></script>
<script type='template-mime' id='3'></script>
Ponieważ wysłanie tej części przez kabel nic Cię nie kosztuje, możesz spodziewać się, że klient zacznie to odbierać gdzieś około 5 ms + opóźnienie po połączeniu z serwerem. Zakładając, że serwer jest dość blisko, opóźnienie może wynosić od 20 ms do 60 ms. Przeglądarki zaczną przetwarzać tę sekcję, gdy tylko ją otrzymają, a czas przetwarzania zwykle zdominuje czas przesyłania 20-krotnie lub więcej, co jest teraz zamortyzowanym oknem na przetwarzanie części po stronie serwera <dynamic>
.
Przetwarzanie inline jquery + signalr + angular + ng animate + ng touch + ng Routes + lodash zajmuje około 50 ms (chrome, reszta może być o 20% wolniejsza). To niesamowite samo w sobie. Większość aplikacji internetowych ma mniej kodu niż wszystkie te popularne biblioteki razem wzięte, ale powiedzmy, że masz tyle samo, więc wygralibyśmy opóźnienie + 100 ms przetwarzania na kliencie (ta wygrana pochodzi z drugiej części transferu). Zanim nadejdzie druga porcja, przetworzyliśmy cały kod js i szablony i możemy rozpocząć wykonywanie transformacji dom.
Możesz sprzeciwić się temu, że ta metoda jest ortogonalna w stosunku do koncepcji wstawiania, ale tak nie jest. Jeśli zamiast wstawiać link do cdns lub własnych serwerów, przeglądarka musiałaby otworzyć inne połączenie (a) i opóźnić wykonanie. Ponieważ to wykonanie jest w zasadzie bezpłatne (ponieważ serwer rozmawia z bazą danych), musi być jasne, że wszystkie te skoki będą kosztować więcej niż ich całkowity brak. Gdyby istniało dziwactwo przeglądarki, które mówi, że zewnętrzny js wykonuje się szybciej, moglibyśmy zmierzyć, który czynnik dominuje. Moje pomiary wskazują, że dodatkowe żądania obniżają wydajność na tym etapie.
Dużo pracuję nad optymalizacją aplikacji SPA. Ludzie często myślą, że ilość danych to wielka sprawa, podczas gdy w rzeczywistości często dominują opóźnienia i wykonanie. Zminifikowane biblioteki, które wymieniłem, dodają do 300 kb danych, a to tylko 68 kb zgzip lub 200 ms do pobrania na telefonie 2 mbit 3g / 4g, co jest dokładnie takim opóźnieniem, jakie zajęłoby ten sam telefon, aby sprawdzić, czy ma te same dane w swojej pamięci podręcznej, nawet jeśli był buforowany przez proxy, ponieważ podatek od opóźnienia telefonu komórkowego (opóźnienie telefonu do wieży) nadal obowiązuje. Tymczasem połączenia z komputerami stacjonarnymi, które mają mniejsze opóźnienie pierwszego przeskoku, i tak zazwyczaj mają większą przepustowość.
Krótko mówiąc, teraz (2014) najlepiej jest wstawić wszystkie skrypty, style i szablony.
EDYCJA (MAJ 2016)
Ponieważ aplikacje JS stale się rozwijają, a niektóre z moich ładunków składają się teraz na ponad 3 megabajty zminimalizowanego kodu, staje się oczywiste, że przynajmniej popularne biblioteki nie powinny już być wbudowane.