Mengoptimalkan pemuatan dan rendering WebFont

WebFont "lengkap" yang mencakup semua varian gaya, yang mungkin tidak Anda perlukan, serta semua glyph, yang mungkin tidak digunakan, dapat dengan mudah menghasilkan download multi-megabyte. Dalam postingan ini, Anda akan mengetahui cara mengoptimalkan pemuatan WebFont sehingga pengunjung hanya mendownload font yang akan mereka gunakan.

Untuk mengatasi masalah file besar yang berisi semua varian, aturan CSS @font-face dirancang khusus untuk memungkinkan Anda membagi jenis font ke dalam koleksi resource. Misalnya, subset unicode, dan varian gaya yang berbeda.

Mengingat deklarasi ini, browser menghitung subset dan varian yang diperlukan serta mendownload set minimal yang diperlukan untuk merender teks, yang sangat praktis. Namun, jika tidak berhati-hati, hal ini juga dapat menciptakan bottleneck performa dalam jalur rendering penting dan menunda rendering teks.

Perilaku default

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

Jalur rendering penting font

  1. Browser meminta dokumen HTML.
  2. Browser mulai mengurai respons HTML dan mengonstruksikan DOM.
  3. Browser akan menemukan CSS, JS, dan resource lainnya lalu mengirim permintaan.
  4. Browser mengonstruksikan WebView setelah semua konten CSS diterima dan menggabungkannya dengan hierarki DOM untuk mengonstruksikan hierarki render.
    • Permintaan font dikirimkan setelah hierarki render menunjukkan varian font mana yang diperlukan untuk merender teks yang ditentukan pada halaman.
  5. Browser melakukan layout dan menggambar konten ke layar.
    • Jika font belum tersedia, browser mungkin tidak merender piksel teks apa pun.
    • Setelah font tersedia, browser akan menggambar piksel teks.

"Perlombaan" antara penggambaran pertama pada konten halaman, yang dapat dilakukan segera setelah pohon render dibuat, dan permintaan untuk resource font adalah yang menciptakan "masalah teks kosong" tempat browser mungkin merender tata letak halaman tetapi menghilangkan teks apa pun.

Dengan melakukan pramuat WebFont dan menggunakan font-display untuk mengontrol perilaku browser dengan font yang tidak tersedia, Anda dapat mencegah halaman kosong dan pergeseran tata letak akibat pemuatan font.

Pramuat resource WebFont Anda

Jika kemungkinan besar halaman Anda akan memerlukan WebFont tertentu yang dihosting di URL yang Anda ketahui sebelumnya, Anda dapat memanfaatkan penentuan prioritas resource. Penggunaan <link rel="preload"> akan memicu permintaan untuk WebFont lebih awal di jalur rendering penting, tanpa harus menunggu proses pembuatan WebView.

Menyesuaikan penundaan rendering teks

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

Dalam postingan Hindari teks tidak terlihat selama pemuatan font, Anda dapat melihat bahwa perilaku browser default tidak konsisten. Namun, Anda dapat memberi tahu browser modern bagaimana Anda ingin perilakunya menggunakan font-display.

Dukungan Browser

  • 60
  • 79
  • 58
  • 11.1

Sumber

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

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

Dengan memahami periode ini, Anda dapat menggunakan font-display untuk menentukan bagaimana font Anda akan dirender, bergantung pada apakah atau kapan font Anda didownload.

Untuk menggunakan properti font-display, tambahkan properti tersebut ke aturan @font-face Anda:

@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 bersamaan, <link rel="preload"> dan font-display CSS memberi Anda kontrol yang besar atas pemuatan dan rendering font, tanpa menambahkan banyak overhead. Namun, jika Anda memerlukan penyesuaian tambahan, dan bersedia mengeluarkan biaya tambahan yang disebabkan oleh menjalankan JavaScript, ada opsi lain.

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

Dukungan Browser

  • 35
  • 79
  • 41
  • 10

Sumber

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

Selanjutnya, karena Anda dapat memeriksa status font (melalui metode check()) dan melacak progres downloadnya, Anda juga dapat menentukan strategi kustom untuk merender teks di halaman Anda:

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

Yang paling penting, Anda juga dapat memadupadankan strategi di atas untuk berbagai konten di halaman. Misalnya, Anda dapat menunda rendering teks di beberapa bagian hingga font tersedia, menggunakan font pengganti, lalu merender ulang setelah download font selesai.

Penyimpanan cache yang tepat adalah suatu keharusan

Resource font biasanya merupakan resource statis yang tidak sering diperbarui. Oleh karena itu, metode ini cocok untuk masa berlaku maksimum yang panjang— pastikan Anda menentukan header ETag bersyarat, dan kebijakan Cache-Control optimal untuk semua resource font.

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

Anda tidak boleh menyimpan font menggunakan localStorage atau IndexedDB; setiap font memiliki masalah performanya masing-masing. Cache HTTP browser memberikan mekanisme terbaik dan paling kuat untuk mengirimkan resource font ke browser.

Daftar periksa pemuatan WebFont

  • Sesuaikan pemuatan dan rendering font menggunakan <link rel="preload">, font-display, atau Font Loading API: perilaku pemuatan lambat default dapat menyebabkan rendering teks yang tertunda. Fitur platform web ini memungkinkan Anda mengganti perilaku ini untuk font tertentu, serta menentukan strategi waktu tunggu dan rendering kustom untuk konten yang berbeda di halaman.
  • Tentukan validasi ulang dan kebijakan penyimpanan cache yang optimal: font adalah resource statis yang jarang diupdate. Pastikan server Anda memberikan stempel waktu umur maksimal yang panjang dan token validasi ulang, agar font dapat digunakan kembali secara efisien di antara halaman yang berbeda. 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 bahwa Anda mengikuti praktik terbaik pengoptimalan font web.

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