Dlaczego nie osadzić stylów / skryptów w HTML zamiast linkować?


41

Łączymy pliki CSS i JavaScript, aby zmniejszyć liczbę żądań HTTP, co poprawia wydajność. Wynik jest taki jak HTML:

<link rel="stylesheet" href="all-my-css-0fn392nf.min.css">
<!-- later... -->
<script src="all-my-js-0fn392nf.min.js"></script>

Jeśli mamy logikę po stronie serwera / kompilacji, aby zrobić to wszystko za nas, dlaczego nie posunąć się o krok dalej i osadzić te połączone style i skrypty w kodzie HTML?

<style>.all{width:100%;}.my{display:none;}.css{color:white;}</style>
<!-- later... -->
<script>var all, my, js;</script>

To dwa mniej żądań HTTP, ale nie widziałem tej techniki w praktyce. Dlaczego nie?


12
Obwiniam buforowanie.

Odpowiedzi:


98

Ponieważ zapisywanie żądań HTTP jest mało przydatne, gdy osiągniesz to przez zerwanie buforowania. Jeśli arkusze stylów i skrypty są dostarczane osobno, można je bardzo dobrze buforować i amortyzować na podstawie wielu, wielu żądań do bardzo różnych stron. Jeśli są zapisane na tej samej stronie HTML, muszą być przesyłane ponownie za każdym razem. Pojedynczy. Żądanie.

Kod HTML tej strony, na przykład teraz, ma teraz 13 KB. 180 KB CSS trafiło do bufora, podobnie jak 360 KB JS. Oba trafienia w pamięć podręczną zajmowały niewiele czasu i praktycznie nie zajmowały przepustowości. Wyjmij profil sieciowy przeglądarki i wypróbuj go na innych stronach.


1
Jeśli tworzysz witrynę z pojedynczą stroną, w której znaczna część kodu była specyficzna dla jednej strony, to może mieć to jakiś sens?
JohnB

3
John: jeśli strona jest odwiedzana tylko raz, tak. Jeśli odwiedzane wiele razy, wszystkie osadzone elementy są przesyłane wiele razy zamiast tylko raz i są buforowane.
Konerak,

Warto również zauważyć, że serwując je osobno, pozwalasz na minimalizację zasobów, aby były mniejsze.
wałek klonowy

2
@maple_shaft Proszę opracować, dlaczego nie można zminimalizować zasobów w normalny sposób, a następnie je uwzględnić?

1
@JohnB nie zapomnij o skutkach CDN lub lokalnego buforowania w ISP. Moja prośba o javascript dla Google prawdopodobnie nigdy nie dotrze do Google, nawet jeśli mam lokalną pamięć podręczną, ponieważ inna osoba, która korzysta z tego samego ISP, już spowodowała, że ​​ISP buforuje dane.

19

Po prostu dlatego, że wydajność sieci naprawdę się liczy! 99% razy daje to szybszy czas reakcji użytkownika końcowego.

Oto kilka przykładów z Velocity Conf.

  • Bing - Strona, która była o 2 sekundy wolniejsza, spowodowała 4,3% spadek przychodów / użytkownika.
  • Google - 400 milisekundowe opóźnienie spowodowało spadek wyszukiwań / użytkownika o 0,59%.
  • Yahoo ! - Spowolnienie o 400 milisekund spowodowało 5-9% spadek ruchu na całej stronie.
  • Shopzilla - Przyspieszenie witryny o 5 sekund zwiększyło współczynnik konwersji o 7-12%, podwoiło liczbę sesji z marketingu w wyszukiwarkach i zmniejszyło liczbę wymaganych serwerów o połowę.
  • Mozilla - zmniejszenie liczby stron docelowych o 2,2 sekundy zwiększyło konwersje pobrań o 15,4%, które według nich przyniosą 60 milionów dodatkowych pobrań Firefox rocznie.
  • Netflix - przyjęcie pojedynczej optymalizacji, kompresji gzip, spowodowało przyspieszenie o 13-25% i zmniejszyło wychodzący ruch sieciowy o 50%.

Steve Souders, pionier w optymalizacji wydajności sieci,

80–90% czasu reakcji użytkownika końcowego jest przeznaczane na interfejs - zacznij tutaj pierwszy.

Korzystanie z plików zewnętrznych powoduje szybsze tworzenie stron, ponieważ pliki JavaScript i CSS są buforowane przez przeglądarkę / sieci / serwery proxy (zgodnie z definicją w protokole HTTP z nagłówkami pamięci podręcznej). Pliki JavaScript i CSS wstawiane w dokumentach HTML są pobierane za każdym razem, gdy dokument HTML jest wymagany. Zmniejsza to liczbę potrzebnych żądań HTTP, ale zwiększa rozmiar dokumentu HTML. Jeśli używasz skryptów podobnych do Jquery, łatwo jest odwołać się do 300 KB skryptów i nie sądzę, że każdy ma przepustowość 100 MBits / s przy niskim opóźnieniu, uruchamiając jedną aplikację - przeglądarkę - otwartą na twojej stronie internetowej. 99% razy daje to szybszy czas reakcji użytkownika końcowego.

Ważna jest również częstotliwość, z jaką zewnętrzne komponenty JavaScript i CSS są buforowane w stosunku do liczby żądanych dokumentów HTML. Jeśli użytkownicy w Twojej witrynie mają wiele odsłon na sesję, a wiele stron ponownie korzysta z tych samych skryptów i arkuszy stylów (pakietów), potencjalne korzyści z buforowanych plików zewnętrznych są większe.

Ale wstawianie jest - czasem - lepsze w przypadku aplikacji na jednej stronie lub witryn internetowych z jednym wyświetleniem strony na sesję. Nie ma złotej zasady i na ogół zapomina się o niej, ponieważ dotyczy ona głównie bardzo konkretnych stron internetowych, które są naprawdę zaangażowane w wydajność użytkowników końcowych.

Możesz przeczytać tutaj, dlaczego wydajność ma znaczenie (Oświadczenie: Jestem autorem)


3

Najnowsza wersja HTTP została utworzona już w 1999 roku. W 1999 roku wszyscy byli połączeni z Internetem za pomocą połączenia dial-up. Internet był bardzo wolny. 16 lat później sprawy potoczyły się bardzo sprawnie, ale stosowane przez nas protokoły tak się nie zmieniły.

Odpowiedzi, których nie powinniśmy umieszczać „ponieważ przeszkadza w buforowaniu”, są nieco mylące, szczególnie w erze superszybkiego Internetu. Kiedy faktycznie wykonujesz obliczenia, często istnieje niewielka różnica między czasem ładowania w przypadku użytkowników korzystających z pamięci podręcznej i użytkowników z pamięcią podręczną, o ile wstawiono. Fakt, że nie jest mała różnica nie jest z natury, ponieważ masz inlined, ale ze względu na mało elastycznej konstrukcji HTTP / 1.1.

Protokół SPDY implementuje coś, co nazywa się push serwera . Zasadniczo pobiera się to do samego dokumentu HTML i do protokołu. Inteligentny serwer będzie wiedział, jakie zasoby ma już klient. Głupi serwer po prostu wysyła wszystko bez względu na to - nadal będzie to poprawa wydajności, ale może kosztować pod względem przepustowości. Jeśli przeglądarka ma zawartość w pamięci podręcznej, może po prostu odrzucić przychodzące kopie. Serwer czeka na załadowanie kodu HTML przed wysłaniem dodatkowych zasobów - teoretycznie przeglądarka może wysłać sygnał, aby anulować wypychanie serwera.

HTTP / 2.0 jest oparty na SPDY i najprawdopodobniej zaimplementuje push serwera, ale teoretycznie możesz zacząć używać SPDY już dziś. Tak więc prawdziwym powodem, dla którego nie jesteśmy włączeni, jest spuścizna - istniejące protokoły są stare i nie są wystarczająco elastyczne, aby osiągnąć „wstawianie na poziomie protokołu”.


2
Interesująca odpowiedź, ale zamiast „starszego” powodu, dla którego obecnie nie podajesz informacji, jest to, że najlepiej pasuje do obecnej infrastruktury protokołu internetowego. To będzie spuścizna, jeśli wszyscy będą robić to samo za n lat, kiedy HTTP / 2.0 / SPDY zostanie w pełni wdrożone ;-)
andybuckley

2
Czy mógłbyś podać cytat, naszkicować obliczenia, a przynajmniej podać numer boiska do „superszybkiego”? Ludzie w cywilizowanych krajach pierwszego świata, którzy mają znaczną sumę do wydania online (czytaj: klienci), mogą wciąż - a nawet często - przeglądać z mniejszą przepustowością niż setki megabajtów na sekundę. Dla jednego rzadko osiągam więcej niż trzy MB / s, często mniej niż 700 KB / s. Jako odrębny punkt, nie podajesz powodu, aby wstawiać w sposób sugerowany przez OP (w rzeczywistości podajesz powody, dla których nie chcesz ), podajesz powody, dla których warto zoptymalizować protokoły.

1
Moje połączenie 3G nie jest „super szybkie”, a rachunek telefoniczny nie docenia niepotrzebnych danych. Nie zapomnij - nie całe użycie danych mobilnych odbywa się przez telefon z tetheringiem i tabletami / laptopami z obsługą 3G. Esp. w przypadku laptopów zakłada się, że jest to wifi / ethernet w domowym połączeniu szerokopasmowym. Nie doceniane podczas zdalnego tetheringu ...
AnonJr

3

Oprócz problemów związanych z buforowaniem i wyszukiwaniem, które budzą inne odpowiedzi, chciałbym zwrócić uwagę na inny, bardziej niejasny problem: analizowanie .

JavaScript pojawiający się w HTML może napotykać problemy z analizą, jak w tym przykładzie:

<html>
<head>
<script>
function myfunc() {
    if ("</style> isn't a problem")
        return "but </script> is"
}
</script>
<style>
body::after {
  content: '</script> is okay, but not </style>'
}
</style>
</head>
<body>
<script>document.write(myfunc())</script>
</body>
</html>

... co oznacza, że ​​będziesz musiał przekształcić skrypt, aby uciec przed niektórymi znakami uruchamianymi w HTML. Ten problem znika, gdy podajesz CSS i JavaScript jako zasoby zewnętrzne, ponieważ nie muszą one już brać pod uwagę kontekstu analizy „nadrzędnej”.

Jeśli udostępniasz swoje treści jako XML, możesz to częściowo rozwiązać za pomocą sekcji CDATA. CDATA ma jednak podobny problem:

<?xml version="1.0" encoding="utf-8"?>
<html>
<head>
<script>
// <![CDATA[
function myfunc() {
    if ("</script> is no longer a problem")
        return "but ]]> is"
}
// ]]>
</script>
<style>
<![CDATA[
body::after {
  content: 'same ]]> issue here'
}
]]>
</style>
</head>
<body>
<script>document.write(myfunc())</script>
</body>
</html>

Uważaj na wkładki.


1

Oddzielenie treści od stylu prezentacji jest zwykle większą zaletą niż mniej żądań HTTP.

Oddzielenie wszystkich stylów umożliwia i zachęca do ponownego użycia i udostępnionych plików.

Zawartość plików będzie również bardziej statyczna i będzie dostępna do buforowania na serwerach i klientach zarówno dla tej strony, jak i innych odwiedzanych stron.

Jednak konkretne pytanie ... Jeśli serwer jest zmuszony do przeprowadzenia samej minimalizacji, utrudnia to utrzymanie zasobów i debugowanie problemów. Jednak wiele frameworków robi to teraz na poziomie pliku, np. Wszystkie cs i wszystkie js. Na przykład platforma rubin na szynach minimalizuje teraz swoje zasoby do produkcji. 5-10 dodatkowych żądań HTTP zwykle nie stanowi wąskiego gardła, tym bardziej, jeśli jest ponad 100 żądań HTTP (które często otrzymujesz ze zdjęciami).

Dodatkowy krok polegający na włączeniu kodu do samych stron miałby wadę w przypadku większych stron, ponieważ trzeba ostrożnie zarządzać sekwencją pobierania, a strona nie byłaby w stanie często wyświetlać treści bez reszty (obecnie dużej) strony jest pobierany.


Aby wyjaśnić, czy mówisz, że oddzielenie stylu i treści jest korzystne dla programistów, czy poprawia wydajność przeglądarki użytkownika końcowego?

Mówię, że ogólną korzyścią dla firmy jest zwykle większa wygrana niż redukcja żądań w kategoriach biznesowych.
Michael Durrant,

3
Czy zdajesz sobie sprawę, że OP opowiada się za tworzeniem z oddzielnymi plikami i łączeniem tylko podczas wdrażania, wraz z minimalizacją, zaciemnianiem i „regularnym” łączeniem? Możesz mieć bazę kodu, którą można utrzymać, i czerpać korzyści z wydajności. Jest to powszechna praktyka w przypadku innych optymalizacji manglingu kodu, takich jak minimalizowanie kodu źródłowego i łączenie wielu plików JS / CSS w jeden.

Nie zdaję sobie z tego sprawy. Słowa „osadzić te połączone style i skrypty w kodzie HTML?” mylić mnie.
Michael Durrant

Żeby było jasne, naprawdę chciałem zasugerować, co @delnan wyjaśnił w moim imieniu w swoim komentarzu. Przepraszam, jeśli frazowanie mojego pytania było niejednoznaczne.
GladstoneKeep

1
  1. Zminimalizuj zduplikowane kodowanie. dla zaoszczędzenia czasu (Możesz ponownie użyć stylu i funkcji JS zakodowanych dla jednej strony).
  2. Zminimalizuj wysiłek związany ze zmianą. (Jeśli twój klient poprosi cię o zmianę koloru przycisku strony internetowej. Musisz przejść jedna strona po drugiej).
  3. Skróć czas ładowania (jeśli duplikujesz CSS i JS, oznacza to, że rozmiar pojedynczych stron zwiększa się i jest czasochłonny do pobrania. Ale zwykły CSS JS nie musi pobierać ponownie).
  4. Zdalne użycie. (możesz umieścić swój wspólny JS JS CSS w zdalnym miejscu. nie na tym samym serwerze)
  5. Skróć czas naprawiania błędów. Jeśli występuje błąd w jednej funkcji, musisz przejść strona po stronie, aby naprawić błędy we wbudowanym JS i CSS.
  6. Aby zwiększyć SEO (po prostu oddziel zawartość metadanymi)
  7. Czystszy i zrozumiały kod (jeśli osadzisz wszystko w jednym debugowaniu plików i przejrzystość kodu zniknie. A każda strona będzie bardzo długa).
  8. Dodatkowo pomoże ci to zmniejszyć rozmiar produktu.
  9. Ale nadal możesz rozważyć umieszczenie najbardziej unikalnej rzeczy na tej samej stronie.

0

Nie powinniśmy osadzać stylów / skryptów w HTML, ponieważ

Osadzone style / skrypty należy pobierać przy każdym żądaniu strony:

Style te nie mogą być buforowane przez przeglądarkę i ponownie użyte na innej stronie. Z tego powodu zaleca się osadzenie minimalnej ilości CSS / JS, jak to możliwe.

zamiast tego używamy linkowania coz, gdy używamy linkowania do wiązania css / skryptów

Szybkość witryny wzrasta dla żądań wielu stron:

Gdy dana osoba po raz pierwszy odwiedza Twoją witrynę, przeglądarka pobiera kod HTML bieżącej strony oraz powiązany plik CSS i JS. Gdy przechodzą do innej strony, przeglądarka musi tylko pobrać kod HTML nowej strony, plik CSS / JS jest buforowany, więc nie trzeba go ponownie pobierać. Może to mieć duże znaczenie, szczególnie jeśli masz duży styl i plik skryptu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.