Speed By Mike Wilson

Jalur Rendering Penting dan Link Preload

Halo teman-teman, kali ini gue bakalan bahas mengenai jalur rendering penting. Mungkin teman-teman bertanya-tanya, istilah apaan sih itu, kok kedengarannya asing. Sabar teman-teman, pertanyaan itu akan terjawab pada penjelasan selanjutnya. Selain membahas mengenai jalur rendering penting, gue juga bahas mengenai link preload, yang sebenarnya kedua hal tersebut saling berhubungan satu sama lain.

Jalur Rendering Penting

Untuk memahami apa itu critical rendering path, gue mengutip tulisan Ilya Grigorik di halaman Google Developers: Web Fundamentals,

A critical resource is a resource that could block initial rendering of the page. The fewer of these resources, the less work for the browser, the CPU, and other resources.

Untuk mendefinisikan jalur rendering penting, kita harus memahami dulu apa itu sumber daya penting atau critical resource. Sumber daya penting adalah sumber daya yang dapat menghalangi rendering awal halaman. Sumber daya tersebut dapat berupa CSS, JavaScript atau font eksternal. Biasanya sumber daya penting tersebut terletak di dalam tag <head></head>.

Kemudian yang disebut jalur rendering penting adalah serangkaian even yang harus dilakukan oleh peramban untuk menampilkan tampilan awal sebuah situs web. Contoh even tersebut adalah mendapatkan html, mendapatkan aset (CSS, JavaScript, Gambar, Font), memparse data, menampilkan situs web.

Bayangkan jika ada situs web yang memiliki kode HTML5 seperti berikut,

<!DOCTYPE html>
<html>
<head>
  <title>Judul Halaman</title>
  <meta charset="utf-8">
  <link rel="stylesheet" href="URL CSS eksternal 1">
  <link rel="stylesheet" href="URL CSS eksternal 2">
  <link rel="stylesheet" href="URL CSS eksternal 3">
  <script src="URL JavaScript eksternal 1"></script>
  <script src="URL JavaScript eksternal 2"></script>
  <script src="URL JavaScript eksternal 3"></script>
</head>
<body>
  <!-- Konten -->
  <script src="URL JavaScript eksternal 4"></script>
  <script src="URL JavaScript eksternal 5"></script>
</body>
</html>

Di dalam tag <head></head> terdapat banyak sekali sumber daya eksternal, belum lagi JavaScript eksternal yang terletak sebelum tag penutup </body>. Ada banyak sumber daya eksternal yang harus dimuat terlebih dahulu sehingga pengguna tidak dapat melihat tampilan awal secara langsung.

Tampilan Awal

Tampilan awal yang dimaksud di sini adalah tampilan yang dilihat pengguna tanpa harus menggulung layar terlebih dahulu. Tampilan awal ini lebih dikenal dengan istilah di atas lipatan atau above the fold. Sedangkan tampilan di bawahnya disebut di bawah lipatan atau below the fold. Untuk lebih memahami istilah di atas lipatan, teman-teman dapat melihat gambar di bawah ini,

Above The Fold Blog Amp By Jefrydco
Bagian tampilan awal yang harus dilihat pengguna secara langsung
Gambar oleh jefrydco

Ketika membuka situs web, pengguna seharusnya sudah dapat melihat tampilan awal secara langsung. Tampilan awal tersebut sesuai dengan viewport. Misal pengguna membuka situs web tersebut menggunakan desktop dengan resolusi 1920x1200, maka tampilan awal yang harus dilihat pengguna secara langsung adalah sebesar 1920x1200.

Sedangkan jika pengguna membuka situs web menggunakan ponsel beresolusi 768x1024, maka tampilan awal yang harus dilihat pengguna secara langsung adalah sebesar 768x1024. Sebenarnya nggak pas 1920x1200 atau 768x1024 juga sih, karena kan kepotong sama toolbar peramban. Tapi, untuk lebih mudahnya, anggap saja ukurannya sesuai dengan resolusi layar.

Jika teman-teman mengecek halaman yang belum teroptimasi dengan baik menggunakan Google PageSpeed Insight, maka teman-teman akan mendapat hasil seperti pada gambar berikut,

Unoptimized Google Pagespeed Insight Result By Jefrydco
Hasil Google PageSpeed Insight yang belum teroptimasi
Gambar oleh jefrydco
Render Blocking Content By Jefrydco
Salah satu peringatan yang dapat dioptimasi
Gambar oleh jefrydco

Salah satu peringatan yang dapat dioptimasi adalah menghilangkan pemuatan JavaScript dan CSS yang dapat menghalangi pe-render-an konten. Sesuai dengan permasalahan yang gue uraikan di atas, pos kali ini juga bakalan menghilangkan peringatan tersebut dan membuat skor Google PageSpeed situs web teman-teman menjadi lebih baik.

Solusi

Kita harus membuat tampilan awal dapat dilihat pengguna secara langsung terlebih dahulu, walaupun bagian bawahnya masih belum termuat sempurna. Solusinya adalah dengan menggunakan metode pemisahan CSS. CSS yang digunakan untuk menampilkan tampilan awal dipisah dan diletakkan di dalam tag <style></style> secara internal. Kemudian sisanya diletakkan berkas lain dan dimuat menggunakan link preload.

Pemisahan CSS

Ada beberapa hal yang harus dipersiapkan sebelum pemisahan CSS dilakukan.

Menggabungkan Semua CSS Eksternal

Pastikan teman-teman telah menggabungkan semua CSS eksternal menjadi satu. Yang perlu diperhatikan ketika menggabungkannya menjadi satu adalah urutan peletakkannya. CSS framework diletakkan paling atas kemudian diikuti CSS lainnya yang bergantung pada CSS framework tersebut.

Contohnya misal situs web teman-teman menggunakan bootstrap dan CSS kustom buatan teman-teman sendiri, urutan ketika digabungkan adalah bootstrap terlebih dahulu kemudian CSS kustom. Mengapa urutan penggabungan CSS sangat penting? Karena ketika CSS dibaca oleh peramban jika terdapat aturan yang sama, maka yang digunakan oleh peramban adalah aturan terakhir.

#selector {
  background-color: blue; // Properti ini akan ditimpa
}
/* CSS lainnya */
#selector {
  background-color: #2196f3; // Properti ini yang digunakan peramban
}

Minify

Jika CSS yang teman-teman gunakan dalam keadaan unminify seperti contoh sebelumnya, silahkan minify terlebih dahulu. Tujuannya agar ukuran CSS menjadi lebih kecil. Teman-teman dapat menggunakan tool berikut untuk melakukan minify,

Pemisahan

Untuk memisahkan CSS antara yang digunakan untuk menampilkan tampilan awal dengan yang tidak, teman-teman dapat menggunakan tool berikut, Critical Path CSS Generator untuk versi gratis dan tool berikut, Critical CSS untuk versi berbayar.

Critical Path Css Generatory By Jefrydco
Critical Path CSS Generator
Gambar oleh jefrydco

Silahkan teman-teman mem-paste-kan semua CSS yang telah digabungkan dan di-minify tadi ke form di sebelah kiri. Paste-kan juga tautan halaman yang ingin dipisahkan CSS-nya. Kemudian silahkan klik tombol Create Critical Path CSS. Setelah proses selesai, akan muncul form baru di sebelah kanan berisi CSS yang digunakan untuk menampilkan tampilan awal. Copy CSS tersebut dan letakkan di dalam tag <style></style> secara internal.

Sebelum Pemisahan
<!DOCTYPE html>
<html>
<head>
  <title>Judul Halaman</title>
  <meta charset="utf-8">
  <link rel="stylesheet" href="URL CSS eksternal 1">
  <link rel="stylesheet" href="URL CSS eksternal 2">
  <link rel="stylesheet" href="URL CSS eksternal 3">
  <script src="URL JavaScript eksternal 1"></script>
  <script src="URL JavaScript eksternal 2"></script>
  <script src="URL JavaScript eksternal 3"></script>
</head>
<body>
  <!-- Konten -->
  <script src="URL JavaScript eksternal 4"></script>
  <script src="URL JavaScript eksternal 5"></script>
</body>
</html>
Sesudah Pemisahan
<!DOCTYPE html>
<html>
<head>
  <title>Judul Halaman</title>
  <meta charset="utf-8">
  <style>
    /* Letakkan CSS hasil generate di sini */
  </style>
  <link rel="stylesheet" href="URL CSS eksternal yang telah digabung dan diminify">
  <script src="URL JavaScript eksternal 1"></script>
  <script src="URL JavaScript eksternal 2"></script>
  <script src="URL JavaScript eksternal 3"></script>
</head>
<body>
  <!-- Konten -->
  <script src="URL JavaScript eksternal 4"></script>
  <script src="URL JavaScript eksternal 5"></script>
</body>
</html>

Setelah teman-teman berhasil memisahkan CSS antara yang digunakan untuk menampilkan tampilan awal dan yang tidak dan menaruhnya di dalam tag <style></style> secara internal. Hal tersebut tidak akan berdampak banyak kalau tidak digabung dengan link preload.

Link preload digunakan untuk memprioritaskan pemuatan suatu sumber daya sebelum peramban selesai memparse dokumen HTML5 seluruhnya. Cara kerjanya adalah ketika peramban menemukan tag link dengan atribut rel="preload", peramban secara langsung memuat sumber daya tersebut namun tidak dieksekusi terlebih dahulu. Setelah selesai memproses dokumen secara keseluruhan, baru memproses sumber daya yang dimuat menggunakan atribut rel="preload".

Untuk menggunakan fitur ini, silahkan teman teman mengubah atribut rel="stylesheet" yang ada pada tag link menjadi rel="preload".

Sebelum Atribut Dirubah
  <link rel="stylesheet" href="URL CSS eksternal yang telah digabung dan diminify">
Sesudah Atribut Dirubah
  <link rel="preload" href="URL CSS eksternal yang telah digabung dan diminify">

Namun sayangnya fitur atribut rel="preload" belum sepenuhnya didukung. Kalaupun didukung, hanya beberapa peramban saja dan itupun versi yang paling mutakhir.

Can I Use Rel Preload By Jefrydco
Tabel kompatibilitas atribut rel="preload" beberapa peramban terkenal
Gambar oleh jefrydco

Untuk mengatasinya, kita perlu menggunakan plugin JavaScript bernama loadCSS yang dibuat oleh Fillament GroupPlugin ini berfungsi untuk memuat CSS eksternal secara asinkron. Maksud dari asinkron di sini, CSS eksternal akan dimuat tidak secara bersamaan dengan pemuatan sumber daya eksternal lainnya.

Dalam hal ini, CSS eksternal akan diprioritaskan sehingga akan dimuat terlebih dahulu. Dengan kata lain, plugin loadCSS ini berfungsi seperti atribut rel="preload" untuk peramban yang belum mendukun fitur tersebut. Untuk memasang plugin ini silahkan teman-teman menambahkan tag <script></script> baru di bawah tag link preload.

  <link rel="preload" href="URL CSS eksternal yang telah digabung dan diminify">
  <script></script>

Kemudian copy dan paste-kan kode di bawah ini ke dalam tag <script></script> yang baru teman-teman buat tadi,

/*! Turn any rel=preload link into rel=stylesheet */
function e(){var e=Array.prototype.slice.call(document.querySelectorAll("link[rel=preload]"),0);e.length>0&&e.forEach(function(e){e.rel="stylesheet"})}
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
!function(e){var t=function(t,r,n){function a(e){return o.body?e():void setTimeout(function(){a(e)})}function i(){c.addEventListener&&c.removeEventListener("load",i),c.media=n||"all"}var s,o=e.document,c=o.createElement("link");if(r)s=r;else{var l=(o.body||o.getElementsByTagName("head")[0]).childNodes;s=l[l.length-1]}var d=o.styleSheets;c.rel="stylesheet",c.href=t,c.media="only x",a(function(){s.parentNode.insertBefore(c,r?s:s.nextSibling)});var u=function(e){for(var t=c.href,r=d.length;r--;)if(d[r].href===t)return e();setTimeout(function(){u(e)})};return c.addEventListener&&c.addEventListener("load",i),c.onloadcssdefined=u,u(i),c};"undefined"!=typeof exports?exports.loadCSS=t:e.loadCSS=t}("undefined"!=typeof global?global:this),
/*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
!function(e){if(e.loadCSS){var t=loadCSS.relpreload={};if(t.support=function(){try{return e.document.createElement("link").relList.supports("preload")}catch(t){return!1}},t.poly=function(){for(var t=e.document.getElementsByTagName("link"),r=0;r<t.length;r++){var n=t[r];"preload"===n.rel&&"style"===n.getAttribute("as")&&(e.loadCSS(n.href,n,n.getAttribute("media")),n.rel=null)}},!t.support()){t.poly();var r=e.setInterval(t.poly,300);e.addEventListener&&e.addEventListener("load",function(){t.poly(),e.clearInterval(r)}),e.attachEvent&&e.attachEvent("onload",function(){e.clearInterval(r)})}}}(this),window.addEventListener("load",e,!1)

Sehingga secara keseluruhan menjadi seperti berikut,

<!DOCTYPE html>
<html>
<head>
  <title>Judul Halaman</title>
  <meta charset="utf-8">
  <style>
    /* Letakkan CSS hasil generate di sini */
  </style>
  <link rel="stylesheet" href="URL CSS eksternal yang telah digabung dan diminify">
  <script>
  /*! Turn any rel=preload link into rel=stylesheet */
function e(){var e=Array.prototype.slice.call(document.querySelectorAll("link[rel=preload]"),0);e.length>0&&e.forEach(function(e){e.rel="stylesheet"})}
  /*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
!function(e){var t=function(t,r,n){function a(e){return o.body?e():void setTimeout(function(){a(e)})}function i(){c.addEventListener&&c.removeEventListener("load",i),c.media=n||"all"}var s,o=e.document,c=o.createElement("link");if(r)s=r;else{var l=(o.body||o.getElementsByTagName("head")[0]).childNodes;s=l[l.length-1]}var d=o.styleSheets;c.rel="stylesheet",c.href=t,c.media="only x",a(function(){s.parentNode.insertBefore(c,r?s:s.nextSibling)});var u=function(e){for(var t=c.href,r=d.length;r--;)if(d[r].href===t)return e();setTimeout(function(){u(e)})};return c.addEventListener&&c.addEventListener("load",i),c.onloadcssdefined=u,u(i),c};"undefined"!=typeof exports?exports.loadCSS=t:e.loadCSS=t}("undefined"!=typeof global?global:this),
  /*! loadCSS rel=preload polyfill. [c]2017 Filament Group, Inc. MIT License */
!function(e){if(e.loadCSS){var t=loadCSS.relpreload={};if(t.support=function(){try{return e.document.createElement("link").relList.supports("preload")}catch(t){return!1}},t.poly=function(){for(var t=e.document.getElementsByTagName("link"),r=0;r<t.length;r++){var n=t[r];"preload"===n.rel&&"style"===n.getAttribute("as")&&(e.loadCSS(n.href,n,n.getAttribute("media")),n.rel=null)}},!t.support()){t.poly();var r=e.setInterval(t.poly,300);e.addEventListener&&e.addEventListener("load",function(){t.poly(),e.clearInterval(r)}),e.attachEvent&&e.attachEvent("onload",function(){e.clearInterval(r)})}}}(this),window.addEventListener("load",e,!1)
  </script>
  <script src="URL JavaScript eksternal 1"></script>
  <script src="URL JavaScript eksternal 2"></script>
  <script src="URL JavaScript eksternal 3"></script>
</head>
<body>
  <!-- Konten -->
  <script src="URL JavaScript eksternal 4"></script>
  <script src="URL JavaScript eksternal 5"></script>
</body>
</html>

Oke cukup sekian pembahasan mengenai jalur rendering penting dan link preload kali ini. Kode di atas masih belum teroptimasi dengan baik karena masih terdapat beberapa JavaScript eksternal. Pada pos selanjutnya gue akan bahas mengenai cara menggabungkan beberapa JavaScript eksternal tersebut dengan lebih aman. Semoga bermanfaat dan tetap semangat untuk terus belajar.

Referensi

  1. Github Fillament Group: loadCSS
  2. Google Developers Web Fundamentals: Critical Rendering Path
  3. Google Developers Web Fundamentals: Optimizing the Critical Rendering Path
  4. Google Developers Web: Prioritizing Your Resources with link rel='preload'
  5. Medium: Understanding the critical rendering path, rendering pages in 1 second
  6. Mozilla Developers Network: Preloading content with rel="preload"
  7. Optimizely: Above the Fold
  8. Varvy: Critical rendering path
Top