Pada artikel ini, saya akan membagikan 8 teknik untuk mengoptimalkan pemuatan gambar yang mengurangi bandwidth jaringan yang diperlukan dan beban prosesor saat ditampilkan di layar. Berikut beberapa contoh HTML beranotasi untuk memudahkan Anda menggandakannya. Beberapa teknik telah dikenal sejak lama, dan beberapa muncul relatif baru-baru ini. Idealnya, mekanisme penerbitan dokumen web favorit Anda (seperti CMS, generator situs statis, atau kerangka aplikasi web) harus melakukan semua ini di luar kotak.
Secara kolektif, teknik tersebut mengoptimalkan semua elemen Google Core Web Vitals dengan:
- meminimalkan masalah konten utama ( Largest Contentful Paint (LCP) ) melalui pengurangan ukuran, caching, dan pemuatan lambat ;
- pemeliharaan pergeseran tata letak kumulatif nol ( Pergeseran Tata Letak Kumulatif (CLS) );
- mengurangi penundaan input pertama ( First Input Delay (FID) ) dengan mengurangi konsumsi prosesor (untuk thread utama eksekusi).
Untuk melihat semua teknik dalam tindakan, lihat kode sumber untuk memuat gambar ini:
https://www.industrialempathy.com/img/remote/ZiClJf.jpg
<img loading="lazy" decoding="async" style="background-size: cover; background-image: none;" src="/img/remote/ZiClJf.avif" alt="Sample image illustrating the techniques outlined in this post." width="4032" height="2268">
Teknik pengoptimalan
Tata letak responsif
Teknik langsung ini memungkinkan gambar menempati ruang horizontal yang tersedia dengan tetap mempertahankan rasio aspek. Pada tahun 2020, browser telah belajar untuk memesan jumlah ruang vertikal yang tepat untuk gambar sebelum dimuat jika elemen
img
berisi atribut
width
dan
height
. Ini menghindari pergeseran kumulatif tata letak.
<style>
img {
max-width: 100%;
height: auto;
}
</style>
<!-- Providing width and height is more important than ever. -->
<img height="853" width="1280" … />
Rendering malas
Teknik kedua lebih rumit. Atribut CSS baru
content-visibility: auto
memberi tahu browser untuk tidak memikirkan menempatkan gambar sampai siap. Pendekatan ini memiliki beberapa keuntungan, yang utama adalah bahwa sampai browser menerima gambar placeholder yang kabur atau gambar itu sendiri, itu tidak akan memecahkan kode, menghemat sumber daya prosesor.
Tidak perlu lagi mengandung-intrinsic-size
Versi artikel sebelumnya menjelaskan cara
contain-intrinsic-size
menghindari efek CLS saat menggunakan
content-visibility: auto
. Namun di Chromium 88, hal ini tidak lagi diperlukan untuk gambar yang
width
dan
height
. Mulai 27 Januari 2021,
content-visibility: auto
belum diterapkan di mesin browser lain , kemungkinan besar mereka akan mengikuti jejak Chromium. Jadi ya, sekarang jauh lebih mudah!
<style>
/* This probably only makes sense for images within the main scrollable area of your page. */
main img {
/* Only render when in viewport */
content-visibility: auto;
}
</style>
AVIF
AVIF adalah format grafik terbaru yang mendapat dukungan di browser. Sekarang didukung di Chromium dan dengan bendera di Firefox. Safari belum berfungsi dengannya, tetapi karena Apple adalah bagian dari grup yang mengembangkan format tersebut, browser ini juga harus mendukung AVIF di masa mendatang.
Format ini luar biasa karena jauh lebih unggul dari JPEG. Dan ini lebih baik dibandingkan dengan format WebP, gambar yang tidak selalu lebih kecil dari JPEG dan yang dapat meningkatkan konsumsi sumber daya karena kurangnya dukungan untuk pemuatan progresif.
Untuk menerapkan ekstensi progresif untuk AVIF, Anda dapat menggunakan
picture
.
Elemen tersebut sebenarnya
img
bertingkat
picture
... Ini bisa membingungkan, karena
img
terkadang disebut solusi fallback untuk browser yang tidak mendukung
picture
, tetapi sebenarnya elemen ini hanya membantu pemilihan
src
, dan tidak memiliki tata letaknya sendiri. Elemen
img
akan digambar , dan Anda akan menerapkan gayanya.
Sampai saat ini, cukup sulit untuk menerapkan gambar AVIF di sisi server, tetapi versi terbaru dari pustaka seperti Sharp membuat tugas ini jauh lebih mudah.
<picture>
<source
sizes="(max-width: 608px) 100vw, 608px"
srcset="
/img/Z1s3TKV-1920w.avif 1920w,
/img/Z1s3TKV-1280w.avif 1280w,
/img/Z1s3TKV-640w.avif 640w,
/img/Z1s3TKV-320w.avif 320w
"
type="image/avif"
/>
<!-- snip lots of other stuff -->
<img />
</picture>
Memuat jumlah piksel yang benar
Kode di atas memiliki atribut
srcset
dan
sizes
. Mereka menggunakan pemilih
w
untuk memberi tahu browser URL mana yang harus diambil berdasarkan jumlah fisik piksel yang diperlukan untuk merender gambar di perangkat tertentu. Jumlah ini bergantung pada lebar gambar, yang dihitung berdasarkan atribut
sizes
(yang merupakan ekspresi dari kueri media).
Ini memastikan bahwa browser akan selalu memuat gambar sekecil mungkin, memberikan kualitas terbaik pada perangkat tertentu. Atau, dia dapat memilih gambar terkecil jika pengguna mengaktifkan mode penyimpanan data.
Solusi fallback
Untuk browser yang hanya mendukung format gambar yang lebih lama, Anda dapat
srcset
menyediakan lebih banyak elemen mentah dengan bantuan :
<source
sizes="(max-width: 608px) 100vw, 608px"
srcset="
/img/Z1s3TKV-1920w.webp 1920w,
/img/Z1s3TKV-1280w.webp 1280w,
/img/Z1s3TKV-640w.webp 640w,
/img/Z1s3TKV-320w.webp 320w
"
type="image/webp"
/>
<source
sizes="(max-width: 608px) 100vw, 608px"
srcset="
/img/Z1s3TKV-1920w.jpg 1920w,
/img/Z1s3TKV-1280w.jpg 1280w,
/img/Z1s3TKV-640w.jpg 640w,
/img/Z1s3TKV-320w.jpg 320w
"
type="image/jpeg"
/>
Caching dan URL yang tidak dapat diubah
Sematkan di URL gambar hash dari jumlah byte yang ditempati gambar. Dalam contoh di atas, saya melakukannya dengan
Z1s3TKV
. Saat Anda mengubah gambar, URL juga akan berubah, yang berarti Anda dapat menerapkan cache gambar tanpa batas. Header cache akan terlihat seperti ini
cache-control: public,max-age=31536000,immutable
.
immutable
Apakah arti yang benar secara semantik
cache-control
, tetapi memiliki sedikit dukungan browser hari ini (Saya melihat Anda, Chrome).
max-age=31536000
- Metode penyimpanan cadangan sepanjang tahun.
public
diperlukan CDN Anda untuk menyimpan gambar dan mengirimkannya dari tepi jaringan. Tetapi pendekatan ini hanya dapat digunakan jika tidak melanggar kebijakan privasi Anda.
Pemuatan lambat
Dengan menambahkan
loading=«lazy»
elemen,
img
kami memberi tahu browser untuk mulai mengambil gambar hanya jika sudah siap untuk dirender.
<img loading="lazy" … />
Dekripsi asinkron
Dengan menambahkan
decoding=«async»
elemen,
img
kami mengizinkan browser untuk mendekripsi gambar di luar aliran utama sehingga prosedur ini tidak mengganggu pengguna. Seharusnya tidak ada kekurangan yang terlihat dalam solusi ini, kecuali bahwa itu tidak selalu berlaku secara default di browser lama.
<img decoding="async" … />
Rintisan kabur
Rintisan fuzzy adalah gambar sebaris yang memberi pengguna gambaran tentang gambar lengkap yang akan dimuat nanti, tanpa mentransfer data melalui jaringan.
https://www.industrialempathy.com/img/blurry.svg
Beberapa catatan implementasi:
- Rintisan itu berbentuk inline seperti
background-image
gambar. Teknik ini memungkinkan Anda melepaskan elemen HTML kedua dengan menyembunyikan stub secara harfiah saat gambar utama dimuat, tidak diperlukan JavaScript. - URI data gambar utama dibungkus dalam URI data gambar SVG. Hal ini dilakukan karena blur dilakukan pada level SVG dan tidak menggunakan filter CSS. Artinya, pemburaman dilakukan satu kali untuk setiap gambar saat diraster dengan SVG, bukan untuk setiap tata letak. Ini menghemat sumber daya prosesor.
<img
style="
…
background-size: cover;
background-image:
url('data:image/svg+xml;charset=utf-8,%3Csvg xmlns=\'http%3A//www.w3.org/2000/svg\'
xmlns%3Axlink=\'http%3A//www.w3.org/1999/xlink\' viewBox=\'0 0 1280 853\'%3E%3Cfilter id=\'b\' color-interpolation-filters=\'sRGB\'%3E%3CfeGaussianBlur stdDeviation=\'.5\'%3E%3C/feGaussianBlur%3E%3CfeComponentTransfer%3E%3CfeFuncA type=\'discrete\' tableValues=\'1 1\'%3E%3C/feFuncA%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cimage filter=\'url(%23b)\' x=\'0\' y=\'0\' height=\'100%25\' width=\'100%25\'
xlink%3Ahref=\'data%3Aimage/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAGCAIAAACepSOSAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAs0lEQVQI1wGoAFf/AImSoJSer5yjs52ktp2luJuluKOpuJefsoCNowB+kKaOm66grL+krsCnsMGrt8m1u8mzt8OVoLIAhJqzjZ2tnLLLnLHJp7fNmpyjqbPCqLrRjqO7AIeUn5ultaWtt56msaSnroZyY4mBgLq7wY6TmwCRfk2Pf1uzm2WulV+xmV6rmGyQfFm3nWSBcEIAfm46jX1FkH5Djn5AmodGo49MopBLlIRBfG8yj/dfjF5frTUAAAAASUVORK5CYII=\'%3E%3C/image%3E%3C/svg%3E');
"
…
/>
(Opsional) Pengoptimalan JavaScript
Peramban mungkin dipaksa untuk meraster ulang rintisan buram meskipun gambar sudah dimuat. Masalahnya bisa diatasi dengan menghapus rasterisasi saat boot. Selain itu, jika gambar Anda memiliki area transparan, maka pengoptimalan ini menjadi wajib, jika tidak, sebuah rintisan akan ditampilkan melalui gambar.
<sript>
document.body.addEventListener(
"load",
(e) => {
if (e.target.tagName != "IMG") {
return;
}
// Remove the blurry placeholder.
e.target.style.backgroundImage = "none";
},
/* capture */ true
);
</sript>
Selain itu
Alat berguna yang menerapkan semua pengoptimalan yang dijelaskan: blog berkinerja tinggi sebelas