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 skorzystać ze specjalnego rabatu na najlepiej sprzedającą się koszulkę w sklepie. Strona docelowa zawiera link do jednego produktu, więc można założyć, że wielu użytkowników przejdzie na stronę ze szczegółami produktu. Dzięki temu strona produktu jest idealnym kandydatem do wstępnego pobierania na stronie docelowej.

Pomiar wyników

Najpierw określ wydajność bazową:

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

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

  6. Aby załadować stronę produktu, w próbnej aplikacji kliknij Kup teraz.

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 ekran peł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. Odznacz pole wyboru Wyłącz pamięć podręczną.

  6. Przeładuj aplikację.

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

Panel sieciowy pokazujący pobrane z zapasu pliki product-details.html

Strona jest przechowywana w pamięci podręcznej HTTP przez 5 minut, po czym obowiązują normalne 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.

Ponowna ocena skuteczności

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

Sprawdź panel Sieć. W porównaniu z pierwotnym śledzeniem sieci występują 2 różnice:

  • 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 wczytywanie dokumentu zajmuje teraz około 10 ms.

To około 98% mniej niż w poprzedniej wersji, 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 dodaj do pliku public/script.js ten kod, aby zadeklarować funkcję, która dynamicznie wstrzykuje tag prefetch, gdy użytkownik ma szybkie połączenie:

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 to warunek jest spełniony, generuje tag <link> z wartością prefetch jako typem podpowiedzi, przekazuje adres URL, który zostanie pobrany w ramach wstępnego pobierania, w atrybucie href i wskazuje, że zasób jest elementem HTML document w atrybucie as.
  • 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>

Wysłanie script.js na końcu strony zapewnia, że zostanie ona załadowana i wykonana po przeanalizowaniu i załadowaniu strony.

Aby mieć pewność, że pobieranie w poprzednim ładowaniu nie zakłóci 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 teraz pobiera product-details.html w ramach wstępnego pobierania tylko przy szybkim połączeniu. Aby sprawdzić, czy:

  1. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran peł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. Przeładuj aplikację.

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

Panel sieciowy pokazujący pobrane z zapasu pliki product-details.html

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

  1. Na liście ograniczania wybierz Wolne 3G.
  2. Przeładuj aplikację.

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

Panel sieci 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 dla strony docelowej:

  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 ekran peł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. Przeł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. Sprawdź panel 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.