Di modul sebelumnya, beberapa teori di balik jalur rendering kritis dan bagaimana resource yang memblokir render dan pemblokir parser dapat menunda rendering awal halaman. Sekarang setelah Anda memahami beberapa teori di balik Anda siap mempelajari beberapa teknik untuk mengoptimalkan jalur rendering.
Saat halaman dimuat, banyak sumber daya dirujuk dalam HTML-nya yang menyediakan dengan tampilan dan tata letaknya melalui CSS, serta interaktivitasnya melalui JavaScript. Dalam modul ini, sejumlah konsep penting terkait sumber daya ini dan bagaimana pengaruhnya terhadap waktu muat laman telah dibahas.
Pemblokiran render
Seperti yang telah dibahas dalam modul sebelumnya, CSS adalah resource render-blocking, karena memblokir browser agar tidak merender konten apa pun hingga CSS Object Model (CSSOM) akan dibuat. Browser memblokir rendering untuk mencegah Flash Konten Tanpa Gaya (FOUC), yang tidak diinginkan dari sudut pandang pengalaman pengguna.
Dalam video sebelumnya, terdapat FOUC singkat tempat Anda dapat melihat halaman tanpa gaya apa pun. Selanjutnya, semua gaya diterapkan setelah CSS halaman selesai memuat dari jaringan, dan versi laman tanpa gaya ditampilkan segera diganti dengan versi {i>style<i}.
Secara umum, FOUC adalah sesuatu yang biasanya tidak Anda lihat, tetapi konsepnya penting dipahami agar Anda mengetahui alasan browser memblokir rendering halaman hingga CSS didownload dan diterapkan ke halaman. Pemblokiran render bukan tidak diinginkan, tetapi Anda ingin meminimalkan berapa lama kejadian itu menjaga CSS Anda tetap optimal.
Pemblokiran parser
Resource pemblokiran parser mengganggu parser HTML, seperti <script>
tanpa atribut async
atau defer
. Ketika parser menemukan
<script>
, browser perlu mengevaluasi dan mengeksekusi skrip sebelum
melanjutkan proses penguraian sisa HTML. Hal ini sesuai rencana, karena skrip mungkin
mengubah atau mengakses DOM selama suatu waktu saat masih sedang dibuat.
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
Saat menggunakan file JavaScript eksternal (tanpa async
atau defer
), parser akan
diblokir sejak file ditemukan hingga diunduh, diuraikan, dan
telah dijalankan. Saat menggunakan JavaScript inline, parser juga diblokir hingga
skrip sebaris akan
diuraikan dan dieksekusi.
Pemindai pramuat
Pemindai pramuat adalah pengoptimalan browser dalam bentuk HTML sekunder
yang memindai respons HTML mentah untuk menemukan dan mengambil secara spekulatif
sumber daya sebelum parser HTML utama
akan menemukannya. Sebagai
misalnya, pemindai pramuat akan memungkinkan browser untuk mulai mendownload
resource yang ditentukan dalam elemen <img>
, meskipun parser HTML diblokir
saat mengambil dan memproses resource seperti CSS dan JavaScript.
Untuk memanfaatkan pemindai pramuat, resource penting harus disertakan dalam markup HTML yang dikirim oleh server. Pola pemuatan resource berikut adalah tidak dapat ditemukan oleh pemindai pramuat:
- Gambar dimuat oleh CSS menggunakan properti
background-image
. Gambar ini ada di CSS, dan tidak bisa ditemukan oleh pemindai pramuat. - Skrip yang dimuat secara dinamis dalam bentuk markup elemen
<script>
yang dimasukkan ke dalam DOM menggunakan JavaScript atau modul yang dimuat menggunakanimport()
dinamis. - HTML yang dirender pada klien menggunakan JavaScript. Markup tersebut berada dalam string dalam resource JavaScript, dan tidak dapat ditemukan oleh pramuat pemindai.
- Deklarasi
@import
CSS.
Semua pola pemuatan sumber daya ini adalah sumber
daya yang baru ditemukan, dan karenanya
tidak mendapatkan manfaat dari
pemindai pramuat. Hindari hal tersebut bila memungkinkan. Jika
menghindari pola tersebut tidak mungkin dilakukan, tetapi Anda dapat menggunakan
Petunjuk preload
untuk menghindari penundaan penemuan resource.
CSS
CSS menentukan presentasi dan tata letak halaman. Seperti yang dijelaskan sebelumnya, CSS adalah sumber daya yang memblokir perenderan, jadi mengoptimalkan CSS dapat menimbulkan dampak terhadap waktu muat halaman secara keseluruhan.
Minifikasi
Memperkecil file CSS akan mengurangi ukuran file resource CSS, sehingga menjadikannya lebih kecil lebih cepat diunduh. Hal ini dilakukan terutama dengan menghapus konten dari sumber file CSS seperti spasi dan karakter tak terlihat lainnya, dan menghasilkan hasilnya ke file yang baru dioptimalkan:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
Dalam bentuknya yang paling mendasar, minifikasi CSS adalah pengoptimalan efektif yang dapat meningkatkan FCP situs Anda, dan bahkan mungkin LCP dalam beberapa kasus. Alat seperti pemaket dapat otomatis melakukan pengoptimalan ini untuk Anda dalam produksi build yang berbeda.
Hapus CSS yang tidak digunakan
Sebelum merender konten apa pun, browser perlu mengunduh dan mengurai semua spreadsheet gaya. Waktu yang dibutuhkan untuk menyelesaikan penguraian juga termasuk gaya yang tidak digunakan di halaman saat ini. Jika Anda menggunakan bundler yang menggabungkan semua CSS sumber daya ke dalam satu file, pengguna Anda cenderung mengunduh lebih banyak CSS daripada yang diperlukan untuk merender halaman saat ini.
Untuk menemukan CSS yang tidak digunakan untuk halaman saat ini, gunakan alat Cakupan di Chrome DevTools.
Menghapus CSS yang tidak digunakan memiliki dua efek: selain mengurangi download Anda mengoptimalkan konstruksi hierarki render, karena browser harus memproses lebih sedikit aturan CSS.
Menghindari deklarasi @import
CSS
Meskipun tampaknya nyaman, Anda harus menghindari deklarasi @import
di CSS:
/* Don't do this: */
@import url('style.css');
Serupa dengan cara kerja elemen <link>
di HTML, deklarasi @import
di CSS memungkinkan Anda mengimpor sumber daya CSS eksternal dari dalam lembar gaya. Tujuan
perbedaan utama antara kedua pendekatan ini adalah elemen <link>
HTML
merupakan bagian dari respons HTML, sehingga ditemukan jauh lebih cepat daripada CSS
file yang didownload oleh deklarasi @import
.
Alasannya adalah agar deklarasi @import
dapat
ditemukan, file CSS yang memuatnya harus terlebih dahulu didownload. Ini
menghasilkan rantai permintaan yang—dalam kasus CSS—keterlambatan
berapa lama waktu yang dibutuhkan halaman untuk pertama kali dirender. Kelemahan lain adalah
spreadsheet gaya yang dimuat menggunakan deklarasi @import
tidak dapat ditemukan oleh
pramuat, dan menjadi sumber daya pemblokir render yang baru ditemukan.
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
Dalam sebagian besar kasus, Anda dapat mengganti @import
dengan menggunakan
elemen <link rel="stylesheet">
. Elemen <link>
memungkinkan style sheet
didownload secara serentak dan mengurangi waktu muat keseluruhan, dibandingkan @import
deklarasi, yang mendownload style sheet secara berurutan.
CSS penting inline
Waktu yang diperlukan untuk mendownload file CSS dapat meningkatkan FCP halaman. {i>Inline<i}
gaya kritis dalam dokumen <head>
menghilangkan permintaan jaringan untuk
Sumber daya CSS, dan—jika dilakukan dengan benar—dapat meningkatkan waktu pemuatan awal ketika
{i>cache browser<i} pengguna tidak disiapkan. CSS yang tersisa dapat dimuat
asinkron, atau ditambahkan di akhir elemen <body>
.
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
Kelemahannya, membuat CSS dalam jumlah besar akan menambahkan lebih banyak byte Respons HTML. Karena sumber daya HTML sering kali tidak dapat disimpan di cache untuk waktu yang lama—atau pada semua—ini berarti bahwa CSS inline tidak di-cache untuk halaman berikutnya yang gunakan CSS yang sama di lembar gaya eksternal. Uji dan ukur metrik kinerja untuk memastikan dampak yang diperoleh sepadan dengan usaha yang dilakukan.
Demo CSS
JavaScript
JavaScript menggerakkan sebagian besar interaktivitas di web, tetapi hal ini membutuhkan biaya. Mengirimkan terlalu banyak JavaScript dapat membuat halaman web Anda lambat merespons selama halaman dimuat, dan bahkan dapat menyebabkan masalah responsivitas yang memperlambat interaksi yang dapat membingungkan pengguna.
JavaScript Pemblokir Render
Saat memuat elemen <script>
tanpa atribut defer
atau async
,
browser memblokir penguraian dan rendering hingga skrip didownload, diuraikan, dan
telah dijalankan. Demikian pula, skrip inline memblokir parser hingga skrip diuraikan
dan dieksekusi.
async
vs. defer
async
dan defer
memungkinkan skrip eksternal dimuat tanpa memblokir HTML
sementara skrip (termasuk skrip inline) dengan type="module"
ditangguhkan secara otomatis. Namun, async
dan defer
memiliki beberapa perbedaan yang
sangatlah penting untuk dipahami.
Skrip yang dimuat dengan async
akan segera diuraikan dan dieksekusi setelah didownload,
sedangkan skrip yang dimuat dengan defer
dieksekusi saat penguraian dokumen HTML
selesai—ini terjadi bersamaan dengan peristiwa DOMContentLoaded
browser.
Selain itu, skrip async
dapat mengeksekusi secara tidak berurutan, sedangkan skrip defer
dieksekusi sesuai urutan kemunculannya dalam markup.
Rendering sisi klien
Umumnya, Anda harus menghindari penggunaan JavaScript untuk merender konten penting atau elemen LCP halaman Anda. Hal ini dikenal sebagai {i>rendering<i} sisi klien, dan merupakan teknik digunakan secara ekstensif dalam Aplikasi Web Satu Halaman (SPA).
Markup yang dirender oleh JavaScript menggantikan pemindai pramuat, karena resource yang ada dalam markup yang dirender klien tidak dapat ditemukan olehnya. Ini dapat menunda download resource penting, seperti gambar LCP. Browser hanya mulai mendownload gambar LCP setelah skrip dijalankan, dan menambahkan elemen ke DOM. Selanjutnya, skrip hanya dapat dieksekusi setelah ditemukan, diunduh, dan diuraikan. Ini dikenal sebagai permintaan kritis jaringan organisasi dan harus dihindari.
Selain itu, merender markup menggunakan JavaScript cenderung menghasilkan tugas yang lebih lama daripada markup yang didownload dari server sebagai respons terhadap navigasi permintaan. Penggunaan rendering sisi klien HTML secara negatif dapat berdampak negatif dan latensi interaksi. Terutama jika DOM halaman sangat besar, yang memicu tugas rendering yang signifikan saat JavaScript memodifikasi DOM.
Minifikasi
Serupa dengan CSS, meminimalkan JavaScript mengurangi ukuran file resource skrip. Hal ini dapat menghasilkan download yang lebih cepat, memungkinkan browser berpindah ke penguraian dan kompilasi JavaScript dengan lebih cepat.
Selain itu, minifikasi JavaScript selangkah lebih maju dibandingkan mengecilkan aset lain, seperti CSS. Saat diminifikasi, JavaScript tidak hanya dihilangkan hal-hal seperti spasi, tab, dan komentar, tetapi simbol di sumber JavaScript dipersingkat. Proses ini terkadang dikenal sebagai uglification. Kepada lihat perbedaannya, ambil kode sumber JavaScript berikut:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
Jika kode sumber JavaScript sebelumnya diringkas, hasilnya mungkin terlihat sesuatu seperti cuplikan kode berikut:
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
Dalam cuplikan sebelumnya, terlihat bahwa variabel yang dapat dibaca manusia
scriptElement
di sumber disingkat menjadi t
. Ketika diterapkan pada
kumpulan skrip, penghematannya bisa cukup signifikan, tanpa mempengaruhi
fitur yang disediakan oleh
JavaScript produksi situs web.
Jika Anda menggunakan bundler untuk memproses kode sumber situs web Anda, sering kali dilakukan secara otomatis untuk build produksi. Uglifier—seperti Terser, misalnya—juga sangat mudah dikonfigurasi, yang memungkinkan Anda menyesuaikan agresivitas algoritme uglifikasi untuk mencapai penghematan maksimum. Namun, setelan default untuk alat uglification apa pun biasanya cukup untuk memukul keseimbangan yang tepat antara ukuran {i>output<i} dan mempertahankan kemampuan.
Demo JavaScript
Menguji pengetahuan Anda
Apa cara terbaik untuk memuat beberapa file CSS di browser?
<link>
.@import
CSS.Apa fungsi pemindai pramuat browser?
<link rel="preload">
di
sumber daya HTML.
Mengapa browser memblokir penguraian HTML untuk sementara secara default saat mendownload resource JavaScript?
Berikutnya: Membantu browser dengan petunjuk resource
Setelah Anda memahami cara pemuatan resource dalam elemen <head>
memengaruhi pemuatan halaman awal dan berbagai metrik, kini saatnya Anda melanjutkan. Dalam
modul, petunjuk resource dieksplorasi, dan bagaimana mereka dapat memberikan petunjuk
browser untuk mulai memuat resource dan membuka koneksi ke lintas origin
server lebih cepat daripada {i>browser<i}
yang tidak akan bisa tanpanya.