Strona główna / Artykuły / Wydajny frontend - optymalizacja fontów

Wydajny frontend - optymalizacja fontów

Szybkie wczytywanie fontów to temat, który jest bardzo często poruszany w kontekście optymalizacji naszych stron i aplikacji. Technik ładowania jest mnóstwo, możemy korzystać z wielu formatów, zaciągać fonty z Google Fonts lub lokalnie, opcji jest naprawdę wiele... Jak się w tym wszystkim połapać i jak wybrać odpowiednią opcję?

Olaf Sulich

2021-03-02

Szybkie wczytywanie fontów to temat, który jest bardzo często poruszany w kontekście optymalizacji naszych stron i aplikacji. Technik ładowania jest mnóstwo, możemy korzystać z wielu formatów, zaciągać fonty z Google Fonts lub lokalnie, opcji jest naprawdę wiele... Jak się w tym wszystkim połapać i jak wybrać odpowiednią opcję?

Google Fonts

Ładowanie fontów z serwerów Google jest obecnie najpopularniejszą metodą, korzysta z niej prawie 43 milionów stron!. Zanim przejdziemy do tego, czy jest to dobra metoda, zobaczmy jak obecnie ładuje się w ten sposób fonty:

<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
  href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;400&display=swap"
  rel="stylesheet"
/>

Pamiętaj żeby zawsze wybierać sposób z <link>, ładowanie Google Fonts w CSS nie jest dobrą praktyką. Fonty ładowane za pomocą @import będą miały wysoki priorytet, ale jednocześnie blokują renderowanie drzewka CSSOM, czego chcemy uniknąć. Bardzo ważną rzeczą jest wybranie tylko tych fontów, których potrzebujemy oraz dodanie display=swap, o którym jeszcze powiemy.

Dodanie tzw. preconnecta pomaga nam usprawnić cały proces, dzięki niemu rozgrzewamy połączenie z zewnętrzną domeną Google, ale nie jest to jeszcze najlepsze rozwiązanie. Tricków na poprawnę wydajności ładowania tych fontów jest wiele, w moim przypadku sprawdził się sposób Bartka z Web Dev Insider.

<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;400&display=swap"
  as="style"
  rel="preload"
/>
<link
  href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;400&display=swap"
  rel="stylesheet"
  media="print"
  onload="this.media='all'"
/>

Korzystamy tutaj ze sztuczki, dzięki której ładujemy fonty asynchronicznie i nadajemy im wysoki priorytet. Jeśli chcesz się dowiedzieć więcej o tym sposobie, to zachęcam Cię do zobaczenia filmu z wyjaśnieniem.

Self Hosting

Przez lata fonty od Google były cachowane, jednak w ubiegłym roku sytuacja się zmieniła...Obecnie znacznie lepszym sposobem jest hostowanie fontów samodzielnie. Sam Google przyznaje to już od 2018 roku. Jeśli możesz, wybieraj rozwiązania typu self hosted.

Formaty i systemowe fonty

W 2021 roku, prawdopodobnie najlepszym wyborem będzie format WOFF2. Jest on wspierany przez wszystkie nowoczesne przeglądarki. Dla tych przestarzałych możemy użyć znanego już od lat WOFF.

Przed sekundą wspominałem Ci o Google i rozwiązaniach typu self hosted, zapominając trochę o klasycznych fontach typu web-safe. Jeśli nie potrzebujesz customowego rozwiązania, zdecydowanie warto postawić na tą opcję:

font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif,
  'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';

Font display

Zanim przejdziemy do konkretnych strategii ładowania, musimy się przyjrzeć właściwości CSS, dzięki której będziemy mogli wpłynąć na sposób renderowania fontów. Właściwością o której mowa, jest właściwość font-display, znajdująca się w bloku @font-face:

@font-face {
  font-family: Lato;
  src: url('font-lato/lato-bolditalic-webfont.woff2') format('woff2')
  font-weight: 700;
  font-style: italic;
  font-display: auto|block|swap|fallback|optional;
}

W większości przypadków idealnie sprawdzi się opcja z font-display: swap. Dzięki niej fallbackowy font ładowany jest jest natychmiastowo, po upływie czasu, gdy nasz customowy font jest gotowy, tekst zostaje podmieniany. Zobaczmy jak to działa w praktyce:

@font-face {
  font-family: Lato;
  src: url('font-lato/lato-bolditalic-webfont.woff2') format('woff2')
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

body {
    font-family: 'Lato', "Helvetica", "Arial", sans-serif;
}

Chcemy użyć na naszej stronie customowego fonta Lato, podając jednocześnie trzy fallbackowe fonty w font-family. Dzięki font-display: swap, użytkownik nie będzie czekał na załadowanie Lato, a zobaczy jeden z podanych, fallbackowych fontów.

Jeśli naszym priorytetem jest poprawa metryki Cumulative Layout Shift, to warto rozważyć zastosowanie font-display: optional

Strategie ładowania

Mogłoby się wydawać, że sposób z font-display: swap będzie wystarczający, jednak tak nie jest. Poza szeregiem zalet, ten sposób posiada również wiele wad, największą z nich jest efekt FOUT (Flash of Unstyled Text).

Zach Leatherman w swoim artykule przedstawia zestawienie różnych strategii ładowania fontów. Okazuję się, że najlepszą metodą w kontekście wydajności jest metoda The Compromise. Jest ona inspirowana metodą z Ebaya, obecnie korzysta z niej Smashing Magazine.

Wykorzystujemy tutaj preloading, o którym mówiłem więcej w poprzednim wpisie. Korzystamy tutaj również z metody z font-display: swap. Jedyną różnicą jest dołączony kod JavaScript, który odpowiada za wieloetapowe ładowanie fontów.

Jeśli chcesz się dowiedzieć więcej o tym sposobie, to zapraszam Cię do dedykowanego artykułu na jego temat. Cały kod opisywanej metody jest dostępny w repozytorium na GitHubie.

Podsumowanie

Optymalizacja fontów pomaga nam w usprawnieniu metryk Time to Interactive i First Contentful Paint. Dzięki poprawie wydajności ładowania fontów Shopify zaobserwowało usprawnienie czasu ładowania strony o około 50%.

Kurs JavaScript?
Mamy coś dla ciebie!

Opanuj JavaScript

Najbardziej praktyczny polski kurs języka JavaScript. 12h lekcji video, 63 ćwiczeń, 9 projektów oraz 800+ quizów - to wszystko czeka na ciebie w Opanuj JavaScript!

Dowiedz sie więcej
App screenshot

Chcesz być na bieżąco?

Zapisz się na newsletter. Gwarantujemy zero spamu.