Zoptymalizuj wczytywanie i renderowanie czcionek WebFont

„Pełny” WebFont, który zawiera wszystkie warianty stylów, których możesz nie potrzebować, oraz wszystkie znaki, których możesz nie używać, może łatwo zająć kilka megabajtów. Z tego artykułu dowiesz się, jak zoptymalizować wczytywanie czcionek internetowych, aby użytkownicy pobierali tylko te, których będą używać.

Aby rozwiązać problem dużych plików zawierających wszystkie warianty, reguła @font-face CSS została zaprojektowana specjalnie po to, aby umożliwić podzielenie rodziny czcionek na kolekcję zasobów. Na przykład: podzbiory Unicode i różne warianty stylu.

Na podstawie tych deklaracji przeglądarka określa wymagane podzbiory i warianty oraz pobiera minimalny zbiór wymagany do renderowania tekstu, co jest bardzo wygodne. Jeśli jednak nie będziesz uważać, może to spowodować problemy z wydajnością na ścieżce renderowania krytycznych elementów i opóźnić renderowanie tekstu.

Domyślne zachowanie

Opóźnione wczytywanie czcionek niesie za sobą ważną ukrytą implikację, która może opóźnić renderowanie tekstu. Zanim przeglądarka będzie wiedzieć, których zasobów czcionek potrzebuje do wyrenderowania tekstu, musi utworzyć drzewo renderowania, które zależy od drzew DOM i CSSOM. W rezultacie żądania dotyczące czcionek są opóźnione w stosunku do innych ważnych zasobów, a przeglądarka może nie być w stanie renderować tekstu, dopóki nie pobierze zasobu.

Ścieżka krytyczna renderowania czcionki

  1. Przeglądarka wysyła żądanie dokumentu HTML.
  2. Przeglądarka zaczyna analizować odpowiedź HTML i tworzyć model DOM.
  3. Przeglądarka odnajduje pliki CSS, JS i inne zasoby oraz wysyła żądania.
  4. Po otrzymaniu wszystkich treści CSS przeglądarka tworzy obiekt CSSOM i łączy go z drzewem DOM, aby utworzyć drzewo renderowania.
    • Żądania dotyczące czcionek są wysyłane po tym, jak drzewo renderowania wskazuje, które warianty czcionki są potrzebne do renderowania określonego tekstu na stronie.
  5. Przeglądarka wykonuje układ i wyświetla treści na ekranie.
    • Jeśli czcionka nie jest jeszcze dostępna, przeglądarka może nie renderować żadnych pikseli tekstu.
    • Gdy czcionka będzie dostępna, przeglądarka użyje jej do wyświetlenia pikseli tekstu.

„Wyścig” między pierwszym wyrenderowaniem zawartości strony, które może nastąpić krótko po utworzeniu drzewa renderowania, a żądaniem zasobu czcionki powoduje „problem pustego tekstu”, gdzie przeglądarka może renderować układ strony, ale pomija tekst.

Dzięki wstępnemu wczytywaniu czcionek WebFonts i używaniu elementu font-display do kontrolowania działania przeglądarek w przypadku niedostępnych czcionek możesz zapobiec wyświetlaniu pustych stron i przesuniętych układów spowodowanych wczytywaniem czcionek.

Wstępne wczytywanie zasobów czcionek internetowych

Jeśli istnieje duże prawdopodobieństwo, że Twoja strona będzie potrzebować określonego czcionki internetowej hostowanej pod znanym z góry adresem URL, możesz skorzystać z priorytetyzacji zasobów. Użycie <link rel="preload"> spowoduje wysłanie żądania dotyczącego czcionki internetowej na wczesnym etapie ścieżki renderowania, bez konieczności czekania na utworzenie obiektu CSSOM.

Dostosowywanie opóźnienia renderowania tekstu

Wprawdzie w przypadku wstępnego wczytywania jest większe prawdopodobieństwo, że czcionka internetowa będzie dostępna podczas renderowania treści strony, ale nie ma to żadnej gwarancji. Nadal musisz wziąć pod uwagę, jak przeglądarki zachowują się podczas renderowania tekstu, który używa font-family, który nie jest jeszcze dostępny.

W poście Unikaj niewidocznego tekstu podczas ładowania czcionek możesz zobaczyć, że domyślne zachowanie przeglądarki nie jest spójne. Możesz jednak określić, jak mają się zachowywać nowoczesne przeglądarki, używając font-display.

Obsługa przeglądarek

  • Chrome: 60.
  • Edge: 79.
  • Firefox: 58.
  • Safari: 11.1.

Źródło

Podobnie jak w przypadku dotychczasowych zachowań dotyczących limitu czasu pobierania czcionek w niektórych przeglądarkach, font-display okres pobierania czcionek jest podzielony na 3 główne okresy:

  1. Pierwszy okres to okres bloku czcionki. Jeśli w tym czasie czcionka nie zostanie załadowana, każdy element, który próbuje jej użyć, musi zamiast niej wyświetlić niewidomego zamiennika. Jeśli czcionka zostanie wczytana w okresie blokady, będzie używana normalnie.
  2. Okres wymiany czcionek następuje bezpośrednio po okresie blokowania czcionek. Jeśli w tym czasie czcionka nie zostanie załadowana, każdy element, który próbuje jej użyć, musi zamiast niej wyświetlić czcionkę zapasową. Jeśli czcionka zostanie wczytana w okresie wymiany, będzie używana normalnie.
  3. Okres nieprawidłowego działania czcionek rozpoczyna się bezpośrednio po okresie wymiany czcionek. Jeśli w tym czasie nie uda się jeszcze załadować czcionki, zostanie ona oznaczona jako nieudane wczytanie, co spowoduje normalne użycie czcionki zastępczej. W przeciwnym razie czcionka jest używana normalnie.

Dzięki znajomości tych okresów możesz za pomocą font-display zdecydować, jak ma być renderowany Twój krój pisma w zależności od tego, czy został on pobrany i kiedy.

Aby korzystać z właściwości font-display, dodaj ją do reguł @font-face:

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  font-display: auto; /* or block, swap, fallback, optional */
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2'), /* will be preloaded */
       url('/fonts/awesome-l.woff') format('woff'),
       url('/fonts/awesome-l.ttf') format('truetype'),
       url('/fonts/awesome-l.eot') format('embedded-opentype');
  unicode-range: U+000-5FF; /* Latin glyphs */
}

font-display obsługuje obecnie ten zakres wartości:

  • auto
  • block
  • swap
  • fallback
  • optional

Więcej informacji o wstępnym wczytywaniu czcionek i właściwości font-display znajdziesz w tych wpisach:

Interfejs Font Loading API

Współpraca <link rel="preload"> i kodu CSS font-display zapewnia dużą kontrolę nad wczytywaniem i renderowaniem czcionek bez zwiększania obciążenia. Jeśli jednak potrzebujesz dodatkowych dostosowań i chcesz ponieść koszty związane z uruchamianiem kodu JavaScript, masz do dyspozycji inną opcję.

Interfejs Font Loading API udostępnia interfejs skryptowy do definiowania i modyfikowania czcionek CSS, śledzenia postępu ich pobierania oraz zastępowania ich domyślnego zachowania ładowania opóźnionego. Jeśli na przykład wiesz, że potrzebny jest konkretny wariant czcionki, możesz go zdefiniować i poinformować przeglądarkę, aby rozpoczęła natychmiastowe pobieranie zasobu czcionki:

Obsługa przeglądarek

  • Chrome: 35.
  • Edge: 79.
  • Firefox: 41.
  • Safari: 10.

Źródło

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
  style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});

// don't wait for the render tree, initiate an immediate fetch!
font.load().then(function() {
  // apply the font (which may re-render text and cause a page reflow)
  // after the font has finished downloading
  document.fonts.add(font);
  document.body.style.fontFamily = "Awesome Font, serif";

  // OR... by default the content is hidden,
  // and it's rendered after the font is available
  var content = document.getElementById("content");
  content.style.visibility = "visible";

  // OR... apply your own render strategy here...
});

Ponieważ możesz sprawdzić stan czcionki (za pomocą metody check()) i śledzić postępy pobierania, możesz też zdefiniować niestandardową strategię renderowania tekstu na stronach:

  • Możesz wstrzymać renderowanie tekstu do czasu, aż czcionka będzie dostępna.
  • Możesz wdrożyć niestandardowy limit czasu dla każdej czcionki.
  • Możesz użyć czcionki awaryjnej, aby odblokować renderowanie i wstrzyknąć nowy styl, który używa żądanej czcionki, gdy ta będzie dostępna.

Co najlepsze, możesz łączyć powyższe strategie w zależności od treści na stronie. Możesz na przykład opóźnić renderowanie tekstu w niektórych sekcjach, dopóki czcionka nie będzie dostępna, użyć czcionki zastępczej, a potem ponownie przetworzyć tekst po zakończeniu pobierania czcionki.

Prawidłowe buforowanie jest niezbędne

Zasoby czcionek to zwykle zasoby statyczne, które nie są często aktualizowane. Dlatego są one idealne do stosowania w przypadku długiego okresu ważności. Pamiętaj, aby określić warunkowy nagłówek ETag oraz optymalną politykę Cache-Control dla wszystkich zasobów czcionek.

Jeśli Twoja aplikacja internetowa korzysta ze skryptu service worker, w większości przypadków odpowiednia jest strategia preferowania pamięci podręcznej.

Nie przechowuj czcionek za pomocą localStorage ani IndexedDB, ponieważ każda z tych metod ma swoje problemy z wydajnością. Pamięć podręczna HTTP przeglądarki to najlepszy i najbardziej stabilny mechanizm dostarczania zasobów czcionek do przeglądarki.

Lista kontrolna wczytywania czcionek internetowych

  • Spersonalizuj wczytywanie i renderowanie czcionek za pomocą <link rel="preload">, font-display lub interfejsu Font Loading API: domyślne zachowanie leniwego ładowania może spowodować opóźnione renderowanie tekstu. Te funkcje platformy internetowej umożliwiają zastąpienie tego zachowania w przypadku określonych czcionek oraz określenie niestandardowych strategii renderowania i czasów oczekiwania dla różnych treści na stronie.
  • Określ zasady weryfikacji i optymalnego buforowania: czcionki to zasoby statyczne, które są rzadko aktualizowane. Upewnij się, że Twoje serwery udostępniają długotrwały znacznik czasu maksymalnego wieku i token ponownej weryfikacji, aby umożliwić efektywne ponowne użycie czcionek na różnych stronach. Jeśli używasz wątku usługi, odpowiednia jest strategia „najpierw pamięć podręczna”.

Automatyczne testowanie sposobu wczytywania czcionek internetowych za pomocą Lighthouse

Lighthouse może pomóc w zautomatyzowaniu procesu sprawdzania, czy stosujesz sprawdzone metody optymalizacji czcionek internetowych.

Dzięki tym audytom możesz mieć pewność, że Twoje strony nadal stosują sprawdzone metody optymalizacji czcionek internetowych: