Mengoptimalkan pemuatan dan rendering WebFont

WebFont "lengkap" yang menyertakan semua varian gaya, yang mungkin tidak Anda perlukan, ditambah semua glyph, yang mungkin tidak digunakan, dapat dengan mudah menghasilkan download berukuran beberapa megabyte. Dalam postingan ini, Anda akan mengetahui cara mengoptimalkan pemuatan WebFonts sehingga pengunjung hanya mendownload yang akan mereka gunakan.

Untuk mengatasi masalah file besar yang berisi semua varian, aturan CSS @font-face dirancang secara khusus agar Anda dapat membagi jenis font menjadi kumpulan resource. Misalnya, subkumpulan unicode, dan varian gaya yang berbeda.

Dengan deklarasi ini, browser akan mengetahui subset dan varian yang diperlukan, serta mendownload kumpulan minimum yang diperlukan untuk merender teks, yang sangat praktis. Namun, jika Anda tidak berhati-hati, hal ini juga dapat menyebabkan bottleneck performa di jalur rendering penting dan menunda rendering teks.

Perilaku default

Pemuatan lambat font memiliki implikasi tersembunyi yang penting dan dapat menunda rendering teks. Browser harus membuat hierarki render, yang bergantung pada hierarki DOM dan CSSOM, sebelum mengetahui resource font yang diperlukan untuk merender teks. Akibatnya, permintaan font tertunda jauh setelah resource penting lainnya, dan browser mungkin diblokir agar tidak merender teks hingga resource diambil.

Jalur rendering kritis font

  1. Browser meminta dokumen HTML.
  2. Browser mulai mengurai respons HTML dan membuat DOM.
  3. Browser menemukan CSS, JS, dan resource lainnya serta mengirim permintaan.
  4. Browser membuat CSSOM setelah semua konten CSS diterima dan menggabungkannya dengan hierarki DOM untuk membuat hierarki render.
    • Permintaan font dikirim setelah hierarki render menunjukkan varian font yang diperlukan untuk merender teks yang ditentukan di halaman.
  5. Browser melakukan tata letak dan menggambar konten ke layar.
    • Jika font belum tersedia, browser mungkin tidak merender piksel teks apa pun.
    • Setelah font tersedia, browser akan melukis piksel teks.

"Persaingan" antara proses gambar pertama konten halaman, yang dapat dilakukan segera setelah hierarki render dibuat, dan permintaan untuk resource font adalah yang menyebabkan "masalah teks kosong" saat browser mungkin merender tata letak halaman, tetapi menghapus teks apa pun.

Dengan memuat WebFonts secara otomatis dan menggunakan font-display untuk mengontrol perilaku browser dengan font yang tidak tersedia, Anda dapat mencegah halaman kosong dan pergeseran tata letak karena pemuatan font.

Memuat ulang resource WebFont

Jika ada kemungkinan besar bahwa halaman Anda akan memerlukan WebFont tertentu yang dihosting di URL yang Anda ketahui sebelumnya, Anda dapat memanfaatkan prioritasisasi resource. Penggunaan <link rel="preload"> akan memicu permintaan untuk WebFont di awal jalur rendering penting, tanpa harus menunggu CSSOM dibuat.

Menyesuaikan penundaan rendering teks

Meskipun pramuat meningkatkan kemungkinan WebFont tersedia saat konten halaman dirender, pramuat tidak memberikan jaminan. Anda masih perlu mempertimbangkan perilaku browser saat merender teks yang menggunakan font-family yang belum tersedia.

Dalam postingan Menghindari teks yang tidak terlihat selama pemuatan font, Anda dapat melihat bahwa perilaku browser default tidak konsisten. Namun, Anda dapat memberi tahu browser modern bagaimana Anda ingin browser tersebut berperilaku dengan menggunakan font-display.

Browser Support

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

Source

Serupa dengan perilaku waktu tunggu font yang ada yang diterapkan oleh beberapa browser, font-display menyegmentasikan masa aktif download font menjadi tiga periode utama:

  1. Periode pertama adalah periode blok font. Selama periode ini, jika tampilan font tidak dimuat, elemen apa pun yang mencoba menggunakannya harus dirender dengan tampilan font pengganti yang tidak terlihat. Jika jenis font berhasil dimuat selama periode pemblokiran, jenis font tersebut akan digunakan secara normal.
  2. Periode penggantian font terjadi tepat setelah periode pemblokiran font. Selama periode ini, jika tampilan font tidak dimuat, elemen apa pun yang mencoba menggunakannya harus dirender dengan tampilan font pengganti. Jika muka font berhasil dimuat selama periode swap, muka font akan digunakan secara normal.
  3. Periode kegagalan font terjadi segera setelah periode penggantian font. Jika jenis font belum dimuat saat periode ini dimulai, jenis font akan ditandai sebagai pemuatan yang gagal, sehingga menyebabkan penggantian font normal. Jika tidak, jenis font akan digunakan secara normal.

Memahami periode ini berarti Anda dapat menggunakan font-display untuk menentukan cara font dirender, bergantung pada apakah atau kapan font didownload.

Untuk menggunakan properti font-display, tambahkan ke aturan @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 saat ini mendukung rentang nilai berikut:

  • auto
  • block
  • swap
  • fallback
  • optional

Untuk informasi selengkapnya tentang pramuat font, dan properti font-display, lihat postingan berikut:

Font Loading API

Jika digunakan bersama, <link rel="preload"> dan CSS font-display memberi Anda kontrol yang besar atas pemuatan dan rendering font, tanpa menambahkan banyak overhead. Namun, jika Anda memerlukan penyesuaian tambahan, dan bersedia menerima overhead yang diperkenalkan dengan menjalankan JavaScript, ada opsi lain.

Font Loading API menyediakan antarmuka skrip untuk menentukan dan memanipulasi font face CSS, melacak progres download-nya, dan mengganti perilaku lazyload default-nya. Misalnya, jika Anda yakin bahwa varian font tertentu diperlukan, Anda dapat menentukannya dan memberi tahu browser untuk memulai pengambilan resource font secara langsung:

Browser Support

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

Source

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...
});

Selain itu, karena Anda dapat memeriksa status font (melalui metode check()) dan melacak progres download-nya, Anda juga dapat menentukan strategi kustom untuk merender teks di halaman:

  • Anda dapat menahan semua rendering teks hingga font tersedia.
  • Anda dapat menerapkan waktu tunggu kustom untuk setiap font.
  • Anda dapat menggunakan font penggantian untuk berhenti memblokir rendering dan memasukkan gaya baru yang menggunakan font yang diinginkan setelah font tersedia.

Yang terbaik, Anda juga dapat menggabungkan strategi di atas untuk konten yang berbeda di halaman. Misalnya, Anda dapat menunda rendering teks di beberapa bagian hingga font tersedia, menggunakan font penggantian, lalu merender ulang setelah download font selesai.

Caching yang tepat adalah suatu keharusan

Resource font biasanya merupakan resource statis yang tidak sering diperbarui. Oleh karena itu, font sangat cocok untuk masa berlaku max-age yang lama. Pastikan Anda menentukan header ETag bersyarat, dan kebijakan Cache-Control yang optimal untuk semua resource font.

Jika aplikasi web Anda menggunakan pekerja layanan, menayangkan resource font dengan strategi cache-first sesuai untuk sebagian besar kasus penggunaan.

Anda tidak boleh menyimpan font menggunakan localStorage atau IndexedDB; masing-masing memiliki serangkaian masalah performanya sendiri. Cache HTTP browser menyediakan mekanisme terbaik dan paling andal untuk mengirimkan resource font ke browser.

Checklist pemuatan WebFont

  • Sesuaikan pemuatan dan rendering font menggunakan <link rel="preload">, font-display, atau Font Loading API: perilaku lazyloading default dapat menyebabkan rendering teks tertunda. Fitur platform web ini memungkinkan Anda mengganti perilaku ini untuk font tertentu, dan menentukan strategi rendering dan waktu tunggu kustom untuk konten yang berbeda di halaman.
  • Menentukan kebijakan validasi ulang dan caching yang optimal: font adalah resource statis yang tidak sering diperbarui. Pastikan server Anda memberikan stempel waktu max-age yang lama dan token validasi ulang untuk memungkinkan penggunaan kembali font yang efisien di antara berbagai halaman. Jika menggunakan pekerja layanan, strategi cache-first adalah strategi yang tepat.

Pengujian otomatis untuk perilaku pemuatan WebFont dengan Lighthouse

Lighthouse dapat membantu mengotomatiskan proses untuk memastikan Anda mengikuti praktik terbaik pengoptimalan font web.

Audit berikut dapat membantu Anda memastikan bahwa halaman Anda terus mengikuti praktik terbaik pengoptimalan font web dari waktu ke waktu: