Dwa sposoby pobierania z wyprzedzeniem: tagi <link> oraz nagłówki HTTP

W tym ćwiczeniu z programowania zaimplementujesz wstępne pobieranie na 2 sposoby: za pomocą dyrektywy <link rel="prefetch"> i nagłówka HTTP Link.

Przykładowa aplikacja to witryna z promocyjną stroną docelową, na której można uzyskać specjalny rabat na najlepiej sprzedającą się koszulkę w sklepie. Ponieważ strona docelowa zawiera link do jednego produktu, można założyć, że wielu użytkowników przejdzie na stronę ze szczegółami produktu. Dzięki temu strona produktu doskonale nadaje się do pobrania z wyprzedzeniem na stronie docelowej.

Pomiar wyników

Najpierw określ poziom bazowy:

  1. Kliknij Remix to Edit (Zmiksuj do edycji), aby umożliwić edycję projektu.
  2. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekranpełny ekran.
  3. Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
  4. Kliknij kartę Sieć.

  5. Na liście Ograniczanie wybierz Szybkie 3G, aby symulować wolne połączenie.

  6. Aby wczytać stronę produktu, kliknij Kup teraz w przykładowej aplikacji.

Wczytywanie strony product-details.html trwa około 600 ms:

Panel sieciowy z czasem wczytywania pliku product-details.html

Aby ulepszyć nawigację, na stronie docelowej umieść tag prefetch, aby pobrać w poprzednim wczytaniu stronę product-details.html:

  • Dodaj do nagłówka pliku views/index.html element <link>:
<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

      <link rel="prefetch" href="/product-details.html" as="document">
      ...
</head>

Atrybut as jest opcjonalny, ale zalecany. Pomaga przeglądarce ustawić odpowiednie nagłówki i określić, czy zasób znajduje się już w pamięci podręcznej. Przykładowe wartości tego atrybutu to: document, script, style, font, image i inne.

Aby sprawdzić, czy pobieranie w tle działa:

  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekranpełny ekran.
  2. Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
  3. Kliknij kartę Sieć.

  4. Na liście Ograniczanie wybierz Szybkie 3G, aby symulować wolne połączenie.

  5. Usuń zaznaczenie pola wyboru Wyłącz pamięć podręczną.

  6. Załaduj ponownie aplikację.

Teraz, gdy wczytuje się strona docelowa, wczytuje się też strona product-details.html, ale ma ona najniższy priorytet:

Panel sieci z wstępnie pobranymi plikami product-details.html.

Strona jest przechowywana w pamięci podręcznej HTTP przez 5 minut. Po upływie tego czasu obowiązują zwykłe reguły Cache-Control dotyczące dokumentu. W tym przypadku product-details.html ma nagłówek cache-control o wartości public, max-age=0, co oznacza, że strona jest przechowywana przez łącznie 5 minut.

Ponownie oceń skuteczność

  1. Ponownie załaduj aplikację.
  2. Aby załadować stronę produktu, w próbnej aplikacji kliknij Kup teraz.

Sprawdź panel Sieć. Występują 2 różnice w stosunku do początkowego logu czasu sieci:

  • Kolumna Rozmiar zawiera informacje „pamięć podręczna pobierania z wyprzedzeniem”, co oznacza, że zasób został pobrany z pamięci podręcznej przeglądarki, a nie z sieci.
  • Kolumna Czas pokazuje, że wczytanie dokumentu trwa teraz około 10 ms.

To około 98% mniej w porównaniu z poprzednią wersją, która zajmowała około 600 ms.

Panel sieciowy z plikiem product-details.html pobranym z pamięci podręcznej pobierania z wyprzedzeniem

Dodatkowy punkt: użyj prefetch jako stopniowego ulepszenia

Pobieranie z wyprzedzeniem najlepiej wdrażać jako stopniowe ulepszenie dla użytkowników korzystających z szybkich połączeń. Możesz użyć interfejsu Network Information API, aby sprawdzić warunki w sieci i dynamicznie wstrzyknąć tagi wstępnego pobierania na podstawie tych danych. W ten sposób możesz zminimalizować zużycie danych i zaoszczędzić na kosztach użytkowników korzystających z wolnych lub drogich planów danych.

Aby zaimplementować adaptacyjne pobieranie w poprzednim planie, najpierw usuń tag <link rel="prefetch"> z elementu views/index.html:

<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
       <link rel="prefetch" href="/product-details.html" as="document">
       ...
    </head>

Następnie do public/script.js dodaj ten kod, aby zadeklarować funkcję, która dynamicznie wstrzykiuje tag prefetch, gdy użytkownik korzysta z szybkiego połączenia:

function injectLinkPrefetchIn4g(url) {
    if (window.navigator.connection.effectiveType === '4g') {
        //generate link prefetch tag
        const linkTag = document.createElement('link');
        linkTag.rel = 'prefetch';
        linkTag.href = url;
        linkTag.as = 'document';

        //inject tag in the head of the document
        document.head.appendChild(linkTag);
    }
}

Funkcja działa w ten sposób:

  • Sprawdza ona właściwość effectiveType interfejsu Network Information API, aby określić, czy użytkownik korzysta z połączenia 4G (lub szybszego).
  • Jeśli ten warunek zostanie spełniony, generuje tag <link> z typem podpowiedzi prefetch, przekazuje adres URL, który zostanie wstępnie pobrany w atrybucie href, i wskazuje, że w atrybucie as zasób to kod HTML document.
  • Na koniec skrypt jest dynamicznie wstrzykiwany do head strony.

Następnie dodaj script.js do views/index.html tuż przed tagiem zamykającym </body>:

<body>
      ...
      <script src="/script.js"></script>
</body>

Żądanie script.js na końcu strony zapewnia, że zostanie ona wczytana i wykonana po przeanalizowaniu i załadowaniu strony.

Aby mieć pewność, że pobieranie w poprzednim ładowaniu nie zakłóci działania kluczowych zasobów bieżącej strony, dodaj ten fragment kodu, który wywołuje funkcję injectLinkPrefetchIn4g() w zdarzeniu window.load:

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

Strona docelowa pobiera teraz z wyprzedzeniem atrybut product-details.html tylko w przypadku szybkich połączeń. Aby sprawdzić, czy:

  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekranpełny ekran.
  2. Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
  3. Kliknij kartę Sieć.
  4. Na liście Ograniczanie wybierz Online.
  5. Ponownie załaduj aplikację.

W panelu Sieć powinieneś zobaczyć product-details.html:

Panel sieciowy pokazujący pobrane wcześniej dane z pliku product-details.html

Aby sprawdzić, czy strona produktu nie jest pobierana wstępnie przy wolnym połączeniu:

  1. Na liście Ograniczenie wybierz Wolne 3G.
  2. Załaduj ponownie aplikację.

Panel Sieć powinien zawierać tylko zasoby strony docelowej bez tych elementów: product-details.html:

Panel sieciowy pokazujący, że plik product-details.html nie jest pobierany wstępnie.

Nagłówka HTTP Link można używać do wstępnego pobierania tych samych zasobów co tag link. Decyzja, kiedy użyć jednej lub drugiej metody, zależy głównie od Twoich preferencji, ponieważ różnica w wydajności jest niewielka. W tym przypadku użyjesz go do wstępnego pobierania głównego pliku CSS strony produktu, aby jeszcze bardziej poprawić jego renderowanie.

Dodaj nagłówek HTTP Link dla style-product.css w odpowiedzi serwera na stronę docelową:

  1. Otwórz plik server.js i znajdź moduł obsługi get() dla adresu URL katalogu głównego: /.
  2. Dodaj ten wiersz na początku metody obsługi:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekranpełny ekran.
  2. Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
  3. Kliknij kartę Sieć.
  4. Ponownie załaduj aplikację.

style-product.css jest teraz pobierane z zapasem o najniższym priorytecie po załadowaniu strony docelowej:

Panel sieciowy pokazujący wyprzedzające pobieranie pliku style-product.css.

Aby otworzyć stronę usługi, kliknij Kup teraz. W panelu Sieć:

Panel Sieć pokazujący plik style-product.css pobrany z pamięci podręcznej pobierania z wyprzedzeniem.

Plik style-product.css jest pobierany z „pamięci podręcznej z wyprzedzeniem” i wczytanie go zajęło tylko 12 ms.