Menjadikan pembuatan sumber gambar berperforma tinggi bagian lancar dari proses pengembangan Anda.
Semua sintaks dalam materi ini—mulai dari pengkodean data gambar hingga
yang mendukung gambar responsif—merupakan metode bagi mesin untuk berkomunikasi dengan mesin. Anda memiliki
menemukan sejumlah cara agar {i>browser<i} klien mengkomunikasikan
kebutuhannya ke server, dan server untuk memberikan tanggapan.
Markup gambar responsif (khususnya srcset
dan sizes
) berhasil mendeskripsikan sejumlah informasi yang mengejutkan dengan relatif
beberapa karakter. Baik atau buruk, kesingkatan itu memang sengaja dibuat: membuat sintaks ini tidak terlalu singkat, dan lebih mudah bagi developer
untuk diurai, dapat membuatnya lebih sulit untuk diurai oleh browser. Makin rumit ditambahkan ke suatu {i>string<i}, maka
potensi kesalahan pengurai, atau perbedaan perilaku yang tidak disengaja dari satu browser ke browser lainnya.
Namun, sifat yang sama yang dapat membuat subjek ini terasa sangat mengintimidasi juga dapat memberi Anda solusi: {i>syntax<i} dengan mudah dibaca oleh mesin adalah sintaksis yang lebih mudah ditulis oleh mesin. Anda hampir pasti telah menemukan banyak contoh otomatisasi encoding dan kompresi gambar sebagai pengguna web: gambar apa pun yang diupload ke web melalui platform media sosial, konten sistem pengelolaan (CMS), dan bahkan klien email hampir selalu melalui sistem yang mengubah ukuran, mengenkode ulang, dan mengompresinya.
Demikian pula, baik melalui plugin, library eksternal, alat proses build mandiri, atau penggunaan pembuatan skrip sisi klien yang bertanggung jawab, markup gambar responsif siap digunakan untuk otomatisasi.
Itulah dua permasalahan utama seputar otomatisasi performa gambar: mengelola pembuatan gambar—encodingnya,
kompresi, dan sumber alternatif yang akan Anda gunakan untuk mengisi atribut srcset
—dan membuat markup yang ditampilkan kepada pengguna.
Dalam modul ini, Anda akan mempelajari beberapa pendekatan umum untuk mengelola gambar sebagai bagian dari alur kerja modern, baik sebagai
otomatis pada proses pengembangan, melalui kerangka kerja atau sistem pengelolaan konten yang mendukung situs, atau
hampir sepenuhnya diabstraksikan oleh
jaringan penayangan konten khusus.
Mengotomatiskan kompresi dan encoding
Anda tidak akan menemukan diri Anda dalam posisi di mana Anda perlu meluangkan waktu untuk menentukan secara manual encoding dan level yang ideal kompresi untuk setiap gambar individual yang dimaksudkan untuk digunakan pada proyek—Anda juga tidak mau. Sebagai penting karena menjaga ukuran transfer gambar sekecil mungkin , akan menyesuaikan setelan kompresi dan penyimpanan ulang sumber alternatif untuk setiap aset gambar yang ditujukan untuk situs produksi, hambatan yang sangat besar dalam pekerjaan sehari-hari.
Seperti yang telah Anda pelajari saat membaca tentang berbagai format gambar dan jenis kompresi, pengkodean yang paling efisien untuk gambar akan selalu ditentukan oleh kontennya, dan seperti yang Anda pelajari di Gambar Responsif, ukuran alternatif yang Anda perlukan untuk sumber gambar adalah ditentukan oleh posisi gambar tersebut dalam tata letak halaman. Dalam alur kerja modern, Anda akan melakukan pendekatan terhadap keputusan ini secara holistik, bukan satu per satu—menentukan satu set {i>default<i} gambar yang logis, agar sesuai dengan konteks data tersebut dimaksudkan untuk digunakan.
Ketika memilih encoding untuk direktori gambar fotografi, AVIF adalah pemenang mutlak untuk kualitas dan ukuran transfer tetapi memiliki dukungan terbatas, WebP menyediakan penggantian modern yang dioptimalkan, dan JPEG adalah default yang paling andal. Alternatif yang dibutuhkan untuk menghasilkan gambar yang dimaksudkan untuk menempati {i>sidebar<i} di tata letak laman akan sangat bervariasi dari gambar yang dimaksudkan menempati seluruh area pandang browser di titik henti sementara tertinggi. Setelan kompresi akan mengharuskan Anda memperhatikan pemburaman dan artefak kompresi di beberapa file yang dihasilkan, sehingga memberikan lebih sedikit ruang untuk melakukan setiap byte yang memungkinkan dari setiap gambar sebagai imbalan atas alur kerja yang lebih fleksibel dan andal. Singkatnya, Anda akan mengikuti proses pengambilan keputusan yang sama seperti dari materi ini.
Untuk pemrosesan itu sendiri, ada sejumlah besar pustaka pemrosesan gambar {i>open source<i} yang menyediakan metode mengonversi, memodifikasi, dan mengedit gambar dalam beberapa kelompok, yang bersaing dalam hal kecepatan, efisiensi, dan keandalan. Pemrosesan ini memungkinkan Anda menerapkan setelan encoding dan kompresi ke seluruh direktori gambar sekaligus, tanpa membuka software pengeditan gambar, dan mempertahankan sumber gambar asli jika setelan itu memerlukannya. untuk disesuaikan dengan cepat. Iklan ini dimaksudkan untuk dijalankan dalam berbagai konteks, dari lingkungan pengembangan lokal Anda hingga server web itu sendiri—misalnya, ImageMin yang berfokus pada kompresi untuk Node.js dapat diperluas agar sesuai dengan aplikasi tertentu melalui array plugin, sedangkan ImageMagick lintas platform dan Sharp berbasis Node.js memiliki beragam fitur yang langsung bisa digunakan.
Library pemrosesan gambar ini memungkinkan developer membuat alat khusus untuk mengoptimalkan gambar dengan lancar sebagai bagian dari proses pengembangan standar—memastikan bahwa project Anda akan selalu merujuk pada image siap produksi sumber data dengan overhead yang seminimal mungkin.
Alur kerja dan alat pengembangan lokal
Task-runner dan pemaket seperti Grunt, Gulp, atau Webpack dapat digunakan untuk mengoptimalkan aset gambar beserta tugas umum lain yang terkait performa, seperti minifikasi CSS dan JavaScript. Kepada menggambarkan, mari kita ambil kasus penggunaan yang relatif sederhana: direktori dalam proyek Anda berisi selusin gambar fotografi, yang dimaksudkan untuk digunakan pada {i>website<i} yang berhubungan dengan publik.
Pertama-tama, Anda harus memastikan encoding yang konsisten dan efisien untuk gambar ini. Seperti yang telah Anda pelajari
di modul sebelumnya,
WebP adalah default yang efisien untuk gambar fotografi dalam hal kualitas dan ukuran file. WebP didukung dengan baik,
tetapi tidak didukung secara universal, jadi Anda juga perlu menyertakan fallback dalam bentuk progressive JPEG. Lalu:
agar dapat menggunakan atribut srcset
untuk pengiriman aset ini secara efisien, Anda harus membuat beberapa
ukuran alternatif untuk setiap encoding.
Meskipun ini akan menjadi tugas yang berulang dan memakan waktu jika dilakukan dengan perangkat lunak pengeditan gambar, pelari tugas seperti
Gulp dirancang untuk mengotomatiskan pengulangan semacam ini. Class gulp-responsive
, yang menggunakan Sharp, adalah salah satu dari banyak opsi yang semuanya mengikuti pola serupa:
mengumpulkan semua file dalam direktori sumber, mengenkodenya ulang, dan mengompresinya berdasarkan "kualitas" standar yang sama
singkat yang telah Anda pelajari di Format dan Kompresi Gambar. File yang dihasilkan kemudian {i>output<i}
ke jalur yang Anda tentukan,
siap direferensikan dalam atribut src
dari elemen img
yang ditampilkan kepada pengguna sekaligus membiarkan file asli Anda tetap utuh.
const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');
exports.webp = function() {
return src('./src-img/*')
.pipe(respimg({
'*': [{
quality: 70,
format: ['webp', 'jpeg'],
progressive: true
}]
}))
.pipe(dest('./img/'));
}
Dengan proses seperti ini, tidak ada kerugian yang akan terjadi pada lingkungan produksi jika seseorang dalam proyek secara tidak sengaja menambahkan foto yang dienkode sebagai PNG truecolor besar ke direktori yang berisi sumber gambar asli Anda—apa pun encoding gambar asli, tugas ini akan menghasilkan WebP yang efisien dan fallback progressive JPEG yang andal, serta tingkat kompresi yang dapat dengan mudah disesuaikan dengan cepat. Tentu saja, proses ini juga memastikan bahwa citra asli Anda file akan disimpan di dalam lingkungan pengembangan proyek, yang berarti bahwa pengaturan ini dapat disesuaikan kapan saja hanya dengan output otomatis yang ditimpa.
Untuk menghasilkan {i>output<i} beberapa file, Anda meneruskan beberapa objek konfigurasi—semuanya sama, terlepas dari penambahan
kunci width
dan nilai dalam piksel:
const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');
exports.default = function() {
return src('./src-img/*')
.pipe(respimg({
'*': [{
width: 1000,
format: ['jpeg', 'webp'],
progressive: true,
rename: { suffix: '-1000' }
},
{
width: 800,
format: ['jpeg', 'webp'],
progressive: true,
rename: { suffix: '-800' }
},
{
width: 400,
format: ['jpeg', 'webp'],
progressive: true,
rename: { suffix: '-400' },
}]
})
)
.pipe(dest('./img/'));
}
Dalam kasus contoh di atas, gambar asli (monarch.png) berukuran lebih dari 3,3 MB. File terbesar yang dibuat oleh tugas ini (monarch-1000.jpeg) berukuran sekitar 150 KB. Yang terkecil, monarch-400.web, hanya berukuran 32KB.
[10:30:54] Starting 'default'...
[10:30:54] gulp-responsive: monarch.png -> monarch-400.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-800.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-400.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-800.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.webp
[10:30:54] gulp-responsive: Created 6 images (matched 1 of 1 image)
[10:30:54] Finished 'default' after 374 ms
Tentu saja, Anda ingin memeriksa hasil dengan cermat untuk menemukan artefak kompresi yang terlihat, atau mungkin meningkatkan kompresi untuk penghematan tambahan. Karena tugas ini tidak bersifat destruktif, setelan ini dapat diubah dengan mudah.
Dengan kata lain, sebagai ganti beberapa kilobita yang bisa Anda hilangkan dengan pengoptimalan mikro manual yang cermat, Anda mendapatkan proses yang tidak hanya efisien, tetapi juga tangguh—alat yang secara lancar menerapkan pengetahuan Anda tentang aset gambar berperforma tinggi ke keseluruhan proyek, tanpa intervensi manual apa pun.
Cara kerja markup gambar responsif
Mengisi atribut srcset
biasanya menjadi proses manual yang mudah, karena atribut benar-benar hanya mengambil
informasi tentang konfigurasi yang telah Anda lakukan saat membuat sumber. Pada tugas di atas, kita telah menetapkan
nama file dan informasi lebar yang akan diikuti oleh atribut:
srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w"
Ingat bahwa konten atribut srcset
bersifat deskriptif, bukan preskriptif. Tidak ada salahnya membebani
srcset
, asalkan rasio aspek setiap sumber konsisten. Atribut srcset
dapat berisi URI
dan lebar setiap potongan alternatif yang dihasilkan oleh server tanpa menyebabkan permintaan yang tidak perlu, dan
sumber yang kami sediakan untuk gambar hasil render, maka browser akan semakin efisien dalam menyesuaikan permintaan.
Seperti yang telah dipelajari di Gambar Responsif, sebaiknya Anda memanfaatkan elemen <picture>
untuk menangani WebP dengan lancar
atau JPEG. Dalam hal ini, Anda akan menggunakan atribut type
bersama dengan srcset
.
<picture>
<source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
<img srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>
Seperti yang telah Anda pelajari, browser yang mendukung WebP akan mengenali konten atribut type
, lalu memilih <source>
atribut srcset
elemen sebagai daftar kandidat gambar. Browser yang tidak mengenali image/webp
sebagai media yang valid
jenis akan mengabaikan <source>
ini, dan sebagai gantinya menggunakan atribut srcset
elemen <img>
bagian dalam.
Ada satu pertimbangan lagi dalam hal dukungan browser: browser tanpa dukungan untuk markup gambar responsif akan
masih memerlukan penggantian, atau gambar berisiko rusak terutama dalam konteks penjelajahan lama. Karena <picture>
,
<source>
, dan srcset
semua diabaikan di browser ini, kita akan ingin menentukan sumber default di bagian dalam <img>
src
.
Karena penskalaan gambar ke bawah secara visual lancar dan encoding JPEG didukung secara universal, JPEG terbesar adalah pilihan yang masuk akal.
<picture>
<source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
<img src="filename-1000.jpg" srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>
sizes
bisa sedikit lebih sulit untuk ditangani. Seperti yang telah Anda pelajari, sizes
harus bersifat kontekstual—Anda
tidak dapat mengisi atribut tanpa mengetahui jumlah ruang yang ingin ditempati gambar dalam tata letak yang dirender. Sebagai
permintaan yang paling efisien, atribut sizes
yang akurat harus berada di markup kami pada saat permintaan tersebut
dibuat oleh pengguna akhir, jauh sebelum gaya yang mengatur tata letak laman diminta. Menghilangkan sizes
sepenuhnya
tidak hanya melanggar spesifikasi HTML, tetapi juga menghasilkan perilaku default yang setara dengan sizes="100vw"
—memberi tahu
browser bahwa gambar ini hanya dibatasi oleh area pandang itu sendiri, sehingga menghasilkan sumber kandidat
yang dipilih.
Seperti halnya pada tugas pengembangan web yang sangat memberatkan, sejumlah alat telah dibuat untuk menyederhanakan
proses penulisan atribut sizes
. respImageLint
adalah
cuplikan kode penting yang dimaksudkan untuk memeriksa akurasi atribut sizes
Anda dan memberikan saran untuk peningkatan.
Halaman ini berjalan sebagai bookmarklet—alat yang dijalankan di browser, sembari diarahkan ke halaman yang dirender sepenuhnya berisi gambar Anda
yang kurang penting. Dalam konteks di mana browser memiliki pemahaman penuh tentang tata letak halaman, browser juga akan memiliki hampir piksel-sempurna
kemampuan gambar untuk menempati ruang dalam tata letak itu pada setiap ukuran area pandang yang mungkin.
Alat untuk analisis lint atribut sizes
tentu saja berguna, tetapi alat ini memiliki nilai lebih sebagai alat untuk menghasilkannya secara grosir.
Seperti yang Anda ketahui, sintaksis srcset
dan sizes
dimaksudkan untuk mengoptimalkan permintaan aset gambar dengan cara yang lancar secara visual. Meskipun
bukan sesuatu yang harus digunakan dalam produksi, nilai placeholder sizes
default sebesar 100vw
sangat wajar
saat mengerjakan tata letak halaman di lingkungan pengembangan lokal Anda. Setelah gaya tata letak diterapkan, menjalankan respImageLint
akan memberikan atribut sizes
yang disesuaikan yang dapat Anda salin dan tempel ke markup, dengan tingkat detail yang jauh lebih besar
dari yang ditulis dengan tangan:
Meskipun permintaan gambar yang dimulai oleh markup yang dirender server terjadi terlalu cepat bagi JavaScript untuk menghasilkan atribut sizes
sisi klien,
alasan yang sama tidak berlaku jika permintaan tersebut dimulai dari sisi klien. Project Lazysizes,
misalnya, memungkinkan Anda untuk menunda permintaan gambar sepenuhnya hingga tata letak dibuat, sehingga memungkinkan JavaScript membuat
nilai sizes
bagi kami—sebuah kemudahan besar bagi Anda, dan jaminan permintaan yang paling efisien untuk pengguna Anda.
Namun, perlu diingat bahwa pendekatan ini berarti mengorbankan keandalan markup yang dirender oleh server dan kecepatan
pengoptimalan yang dibangun ke dalam browser, dan memulai permintaan ini hanya setelah halaman dirender akan memiliki
dampak negatif pada skor LCP Anda.
Tentu saja, jika Anda sudah bergantung pada kerangka kerja rendering sisi klien seperti React atau Vue, itu adalah utang yang sudah Anda
menimbulkan biaya, dan dalam kasus tersebut, menggunakan Lazysizes berarti atribut sizes
Anda dapat hampir sepenuhnya diabstraksi.
Lebih baik lagi: karena sizes="auto"
pada gambar yang dimuat lambat akan memperoleh konsensus dan
implementasi native, Lazysizes akan secara efektif menjadi polyfill untuk perilaku browser yang baru distandardisasi.