Gambar DPI tinggi untuk kepadatan piksel variabel

Salah satu fitur lanskap perangkat yang kompleks saat ini adalah adanya berbagai kepadatan piksel layar yang sangat luas. Beberapa perangkat memiliki layar beresolusi sangat tinggi, sementara yang lainnya tertinggal. Developer aplikasi harus mendukung berbagai kepadatan piksel, yang bisa jadi cukup menantang. Di web seluler, tantangan ditambah dengan beberapa faktor:

  • Berbagai perangkat dengan faktor bentuk yang berbeda-beda.
  • Bandwidth jaringan dan masa pakai baterai terbatas.

Dalam hal gambar, tujuan developer aplikasi web adalah menayangkan gambar berkualitas terbaik seefisien mungkin. Artikel ini akan membahas beberapa teknik yang berguna untuk melakukannya saat ini dan dalam waktu dekat.

Hindari gambar jika memungkinkan

Sebelum membuka kaleng worm, ingat bahwa web memiliki banyak teknologi canggih yang sebagian besar tidak bergantung pada resolusi dan DPI. Secara khusus, teks, SVG, dan banyak CSS akan "bisa berfungsi" karena fitur penskalaan piksel otomatis web (melalui devicePixelRatio).

Meskipun demikian, Anda tidak selalu bisa menghindari gambar raster. Misalnya, Anda mungkin diberi aset yang akan cukup sulit untuk direplikasi dalam SVG/CSS murni, atau Anda menangani foto. Meskipun Anda dapat mengonversi gambar menjadi SVG secara otomatis, memvektorkan foto menjadi sedikit masuk akal karena versi yang diperbesar biasanya tidak terlihat bagus.

Latar belakang

Histori yang sangat singkat terkait kepadatan tampilan

Pada awalnya, layar komputer memiliki kepadatan piksel 72 atau 96 dpi (titik per inci).

Layar meningkat secara bertahap dalam kepadatan piksel, sebagian besar didorong oleh kasus penggunaan seluler, yang mana pengguna umumnya mendekatkan ponsel ke wajah, membuat piksel lebih terlihat. Pada tahun 2008, ponsel 150 dpi adalah norma baru. Tren peningkatan kepadatan tampilan terus berlanjut, dan ponsel baru saat ini menggunakan layar 300 dpi (bermerek "Retina" oleh Apple).

Yang terpenting, tentu saja, adalah tampilan dengan piksel yang sepenuhnya tidak terlihat. Untuk faktor bentuk ponsel, generasi layar Retina/HiDPI saat ini mungkin hampir mencapai kondisi tersebut. Namun, kelas baru hardware dan perangkat wearable seperti Project Glass kemungkinan akan terus mendorong peningkatan kepadatan piksel.

Dalam praktiknya, gambar berkepadatan rendah akan terlihat sama pada layar baru seperti yang terlihat pada layar lama, tetapi dibandingkan dengan gambar tajam yang digunakan pengguna dengan kepadatan tinggi, gambar kepadatan rendah terlihat mengagetkan dan mengalami piksel-piksel. Berikut adalah simulasi kasar tentang tampilan gambar 1x pada tampilan 2x. Sebaliknya, gambar 2x terlihat cukup bagus.

Babun 1x
Babun 2x
Babun! pada kepadatan piksel yang berbeda.

Piksel di web

Saat web dirancang, 99% tampilannya memiliki resolusi 96 dpi (atau dianggap sebagai), dan beberapa penyediaan dibuat untuk variasi di bagian depan ini. Karena besarnya variasi dalam ukuran dan kepadatan layar, kami memerlukan cara standar untuk membuat gambar terlihat bagus di berbagai kepadatan dan dimensi layar.

Spesifikasi HTML baru-baru ini mengatasi masalah ini dengan menentukan piksel referensi yang digunakan produsen untuk menentukan ukuran piksel CSS.

Dengan menggunakan piksel referensi, produsen dapat menentukan ukuran piksel fisik perangkat secara relatif terhadap piksel standar atau ideal. Rasio ini disebut rasio piksel perangkat.

Menghitung rasio piksel perangkat

Misalkan ponsel cerdas memiliki layar dengan ukuran piksel fisik 180 piksel per inci (ppi). Menghitung rasio piksel perangkat memerlukan tiga langkah:

  1. Bandingkan jarak sebenarnya saat perangkat dipegang dengan jarak untuk piksel referensi.

    Sesuai spesifikasi, kita tahu bahwa pada ukuran 28 inci, ukuran idealnya adalah 96 piksel per inci. Namun, karena ini adalah ponsel pintar, orang mendekatkan perangkat ke wajah mereka daripada ke laptop. Mari kita perkirakan jarak itu adalah 18 inci.

  2. Kalikan rasio jarak dengan kepadatan standar (96 ppi) untuk mendapatkan kepadatan piksel ideal untuk jarak yang ditentukan.

    idealPixelDensity = (28/18) * 96 = 150 piksel per inci (kurang-lebih)

  3. Ambil rasio kepadatan piksel fisik terhadap kepadatan piksel ideal untuk mendapatkan rasio piksel perangkat.

    devicePixelRatio = 180/150 = 1,2

Cara penghitungan devicePixelRatio.
Diagram yang menunjukkan satu piksel sudut referensi, untuk membantu menggambarkan cara penghitungan devicePixelRatio.

Jadi, kini ketika browser perlu mengetahui cara mengubah ukuran gambar agar sesuai dengan layar sesuai dengan resolusi ideal atau standar, browser merujuk pada rasio piksel perangkat sebesar 1,2 - yang berarti bahwa, untuk setiap piksel yang ideal, perangkat ini memiliki 1,2 piksel fisik. Formula untuk menentukan antara piksel ideal (sebagaimana didefinisikan oleh spesifikasi web) dan fisik (titik di layar perangkat) adalah sebagai berikut:

physicalPixels = window.devicePixelRatio * idealPixels

Sebelumnya, vendor perangkat cenderung membulatkan devicePixelRatios (DPR). iPhone dan iPad Apple melaporkan DPR 1, dan laporan yang setara dengan Retina 2. Spesifikasi CSS merekomendasikan bahwa

unit piksel mengacu pada keseluruhan jumlah piksel perangkat yang paling mendekati piksel referensi.

Salah satu alasan rasio bulat bisa menjadi lebih baik adalah karena rasio tersebut dapat menyebabkan lebih sedikit artefak sub-piksel.

Namun, kenyataan lanskap perangkat jauh lebih bervariasi, dan ponsel Android sering kali memiliki DPR 1,5. Tablet Nexus 7 memiliki DPR ~1,33, yang diperoleh dengan penghitungan yang mirip dengan yang di atas. Anda akan melihat lebih banyak perangkat dengan DPR variabel pada masa mendatang. Karena itu, Anda tidak boleh berasumsi bahwa klien Anda akan memiliki DPR bilangan bulat.

Ringkasan teknik gambar HiDPI

Ada banyak teknik untuk mengatasi masalah menampilkan gambar berkualitas terbaik secepat mungkin, yang secara luas dibagi menjadi dua kategori:

  1. Mengoptimalkan satu gambar, dan
  2. Mengoptimalkan pilihan di antara beberapa gambar.

Pendekatan gambar tunggal: gunakan satu gambar, tetapi lakukan sesuatu yang cerdas dengan gambar itu. Pendekatan ini memiliki kelemahan, yaitu Anda pasti akan mengorbankan performa, karena Anda akan mendownload image HiDPI bahkan pada perangkat lama dengan DPI yang lebih rendah. Berikut adalah beberapa pendekatan untuk kasus gambar tunggal:

  • Gambar HiDPI yang dikompresi berat
  • Format gambar yang benar-benar mengagumkan
  • Format gambar progresif

Beberapa pendekatan gambar: gunakan beberapa gambar, tetapi lakukan sesuatu yang cerdas untuk memilih gambar yang akan dimuat. Pendekatan ini memiliki overhead inheren bagi developer untuk membuat beberapa versi aset yang sama, lalu mencari strategi keputusan. Berikut ini adala opsinya:

  • JavaScript
  • Pengiriman sisi server
  • Kueri media CSS
  • Fitur browser bawaan (image-set(), <img srcset>)

Gambar HiDPI yang dikompresi berat

Gambar sudah terdiri dari 60% bandwidth yang dihabiskan untuk mendownload sebuah situs rata-rata. Dengan menampilkan image HiDPI ke semua klien, kami akan meningkatkan jumlah ini. Seberapa besar pertumbuhannya?

Saya menjalankan beberapa pengujian yang menghasilkan fragmen gambar 1x dan 2x dengan kualitas JPEG pada 90, 50, dan 20. Berikut adalah skrip shell yang saya gunakan (menggunakan ImageMagick) untuk membuatnya:

Contoh kartu 1. Contoh kartu 2. Contoh kartu 3.
Contoh gambar dengan kompresi dan kepadatan piksel yang berbeda-beda.

Dari pengambilan sampel kecil dan tidak ilmiah ini, tampaknya mengompresi gambar besar memberikan tradeoff kualitas ke ukuran yang baik. Bagi mata saya, gambar 2x yang dikompresi berat sebenarnya terlihat lebih baik daripada gambar 1x yang tidak dikompresi.

Tentu saja, menyajikan gambar 2x berkualitas rendah dan sangat terkompresi ke perangkat 2x lebih buruk daripada menyajikan perangkat yang berkualitas lebih tinggi, dan pendekatan di atas menimbulkan penalti kualitas gambar. Jika Anda membandingkan kualitas: 90 gambar dengan kualitas: 20 gambar, akan terlihat penurunan kejelasan dan grainitas yang meningkat. Artefak ini mungkin tidak dapat diterima jika gambar berkualitas tinggi merupakan kuncinya (misalnya, aplikasi penampil foto), atau untuk developer aplikasi yang tidak mau disusupi.

Perbandingan di atas sepenuhnya dibuat dengan JPEG terkompresi. Perlu diperhatikan bahwa ada banyak konsekuensi antara format gambar yang diterapkan secara luas (JPEG, PNG, GIF), yang membawa kita ke...

Format gambar yang benar-benar mengagumkan

WebP adalah format gambar yang cukup menarik yang mengompresi dengan sangat baik sekaligus mempertahankan fidelitas gambar yang tinggi. Tentu saja, belum diterapkan di mana-mana.

Salah satu caranya adalah memeriksa dukungan WebP adalah melalui JavaScript. Anda memuat gambar 1 px melalui data-uri, menunggu peristiwa dimuat atau error diaktifkan, lalu memverifikasi bahwa ukurannya sudah benar. Modernizr dikirimkan dengan skrip deteksi fitur tersebut, yang tersedia melalui Modernizr.webp.

Namun, cara yang lebih baik untuk melakukannya adalah langsung di CSS menggunakan fungsi image(). Jadi, jika memiliki gambar WebP dan penggantian JPEG, Anda dapat menulis kode berikut:

#pic {
  background: image("foo.webp", "foo.jpg");
}

Ada beberapa masalah dengan pendekatan ini. Pertama, image() sama sekali tidak diterapkan secara luas. Kedua, meskipun kompresi WebP meniupkan JPEG keluar, masih berupa peningkatan yang relatif inkremental – sekitar 30% lebih kecil berdasarkan galeri WebP ini. Oleh karena itu, WebP tidak cukup untuk mengatasi masalah DPI tinggi.

Format gambar progresif

Format gambar progresif seperti JPEG 2000, Progressive JPEG, Progressive PNG, dan GIF memiliki manfaat (agak diperdebatkan) karena gambar muncul sebelum dimuat sepenuhnya. Hal ini mungkin menimbulkan beberapa overhead ukuran, meskipun ada bukti yang bertentangan tentang hal ini. Jeff Atwood mengklaim bahwa mode progresif "menambahkan sekitar 20% untuk ukuran gambar PNG, dan sekitar 10% untuk ukuran gambar JPEG dan GIF". Namun, Stoyan Stefanov mengklaim bahwa untuk file berukuran besar, mode progresif lebih efisien (dalam sebagian besar kasus).

Secara sekilas, gambar progresif terlihat sangat menjanjikan dalam konteks penyajian gambar berkualitas terbaik secepat mungkin. Tujuannya adalah agar browser berhenti mendownload dan mendekode gambar setelah mengetahui bahwa data tambahan tidak akan meningkatkan kualitas gambar (semua peningkatan fidelitas adalah subpiksel).

Meskipun koneksi mudah dihentikan, sering kali biayanya mahal untuk memulai ulang. Untuk situs yang memiliki banyak gambar, pendekatan yang paling efisien adalah menjaga satu koneksi HTTP tetap aktif, menggunakannya kembali selama mungkin. Jika koneksi dihentikan sebelum waktunya karena satu gambar telah cukup didownload, browser perlu membuat koneksi baru, yang dapat menjadi sangat lambat di lingkungan latensi rendah.

Salah satu solusinya adalah menggunakan permintaan HTTP Range, yang memungkinkan browser menentukan rentang byte yang akan diambil. Browser smart dapat membuat permintaan HEAD untuk menuju header, memprosesnya, menentukan jumlah gambar yang benar-benar diperlukan, lalu mengambilnya. Sayangnya, HTTP Range tidak didukung di server web, sehingga pendekatan ini tidak praktis.

Terakhir, batasan yang jelas dari pendekatan ini adalah Anda tidak harus memilih gambar yang akan dimuat, hanya memiliki variasi fidelitas dari gambar yang sama. Akibatnya, pertanyaan ini tidak membahas kasus penggunaan "arah seni".

Gunakan JavaScript untuk menentukan gambar yang akan dimuat

Pendekatan pertama dan paling jelas dalam menentukan gambar yang akan dimuat adalah menggunakan JavaScript pada klien. Pendekatan ini memungkinkan Anda mengetahui segala sesuatu tentang agen pengguna dan melakukan hal yang benar. Anda dapat menentukan rasio piksel perangkat melalui window.devicePixelRatio, mendapatkan lebar dan tinggi layar, dan bahkan berpotensi melakukan beberapa sniffing koneksi jaringan melalui navigator.connection atau mengeluarkan permintaan palsu, seperti yang dilakukan oleh library foresight.js. Setelah mengumpulkan semua informasi ini, Anda dapat memutuskan gambar mana yang akan dimuat.

Ada sekitar satu juta library JavaScript yang melakukan hal seperti di atas, dan sayangnya tidak ada satu pun di antaranya yang benar-benar luar biasa.

Salah satu kelemahan besar dari pendekatan ini adalah penggunaan JavaScript berarti Anda akan menunda pemuatan gambar sampai parser lihat ke depan selesai. Artinya, gambar tidak akan mulai didownload hingga peristiwa pageload diaktifkan. Selengkapnya tentang hal ini ada di artikel Jason Grigsby.

Menentukan gambar yang akan dimuat di server

Anda dapat menyerahkan keputusan ke sisi server dengan menulis pengendali permintaan kustom untuk setiap gambar yang ditayangkan. Pengendali tersebut akan memeriksa dukungan Retina berdasarkan Agen Pengguna (satu-satunya informasi yang disampaikan ke server). Kemudian, berdasarkan apakah logika sisi server ingin menayangkan aset HiDPI atau tidak, Anda memuat aset yang sesuai (dinamai sesuai dengan beberapa konvensi yang diketahui).

Sayangnya, Agen Pengguna tidak selalu menyediakan informasi yang cukup untuk memutuskan apakah perangkat harus menerima gambar berkualitas tinggi atau rendah. Selain itu, tidak perlu dikatakan bahwa apa pun yang berkaitan dengan Agen Pengguna adalah peretasan dan harus dihindari jika memungkinkan.

Menggunakan kueri media CSS

Dengan kueri media CSS yang deklaratif, Anda dapat menyatakan maksud Anda, dan memungkinkan browser melakukan hal yang benar atas nama Anda. Selain penggunaan kueri media yang paling umum, yaitu mencocokkan ukuran perangkat, Anda juga dapat mencocokkan devicePixelRatio. Kueri media terkait adalah rasio piksel perangkat, dan memiliki varian min dan maksimum terkait, seperti yang mungkin Anda harapkan. Jika Anda ingin memuat gambar DPI tinggi dan rasio piksel perangkat melebihi batas, berikut ini yang dapat Anda lakukan:

#my-image { background: (low.png); }

@media only screen and (min-device-pixel-ratio: 1.5) {
  #my-image { background: (high.png); }
}

Proses ini akan menjadi sedikit lebih rumit jika semua awalan vendor tercampur, terutama karena perbedaan penempatan awalan "min" dan "maks" yang besar:

@media only screen and (min--moz-device-pixel-ratio: 1.5),
    (-o-min-device-pixel-ratio: 3/2),
    (-webkit-min-device-pixel-ratio: 1.5),
    (min-device-pixel-ratio: 1.5) {

  #my-image {
    background:url(high.png);
  }
}

Dengan pendekatan ini, Anda mendapatkan kembali manfaat penguraian lihat ke depan, yang hilang dengan solusi JS. Anda juga mendapatkan fleksibilitas dalam memilih titik henti sementara responsif (misalnya, Anda dapat memiliki gambar DPI rendah, sedang, dan tinggi), yang hilang dengan pendekatan sisi server.

Sayangnya, hal ini masih sedikit berat, dan menyebabkan CSS yang terlihat aneh (atau memerlukan pemrosesan sebelumnya). Selain itu, pendekatan ini dibatasi untuk properti CSS, sehingga tidak ada cara untuk menetapkan <img src>, dan semua gambar Anda harus berupa elemen dengan latar belakang. Terakhir, dengan hanya mengandalkan rasio piksel perangkat, Anda dapat mengakibatkan situasi saat ponsel pintar Dpi Tinggi pada akhirnya mendownload aset gambar 2x yang sangat besar saat menggunakan koneksi EDGE. Ini bukan pengalaman pengguna terbaik.

Menggunakan fitur browser baru

Ada banyak diskusi terbaru seputar dukungan platform web untuk masalah gambar DPI tinggi. Apple baru-baru ini menerobos kehebohan, menghadirkan fungsi CSS image-set() ke WebKit. Hasilnya, baik Safari dan Chrome mendukungnya. Karena ini adalah fungsi CSS, image-set() tidak mengatasi masalah untuk tag <img>. Masukkan @srcset, yang mengatasi masalah ini, tetapi (pada saat penulisan ini) belum memiliki implementasi referensi. Bagian berikutnya membahas lebih dalam tentang image-set dan srcset.

Fitur browser untuk dukungan DPI tinggi

Pada akhirnya, keputusan tentang pendekatan yang Anda ambil bergantung pada persyaratan khusus Anda. Meskipun begitu, perlu diingat bahwa semua pendekatan yang disebutkan di atas memiliki kelemahan. Namun, ke depannya, setelah image-set dan srcset didukung secara luas, keduanya akan menjadi solusi yang tepat untuk masalah ini. Untuk saat ini, mari kita bahas beberapa praktik terbaik yang dapat membawa kita sedekat mungkin dengan masa depan ideal.

Pertama, apa perbedaan antara keduanya? image-set() adalah fungsi CSS, yang sesuai untuk digunakan sebagai nilai properti CSS latar belakang. srcset adalah atribut khusus untuk elemen <img>, dengan sintaksis serupa. Kedua tag ini memungkinkan Anda menentukan deklarasi gambar, tetapi atribut srcset juga memungkinkan Anda mengonfigurasi gambar mana yang akan dimuat berdasarkan ukuran area tampilan.

Praktik terbaik untuk kumpulan gambar

Fungsi CSS image-set() tersedia dengan awalan -webkit-image-set(). Sintaksisnya cukup sederhana, mengambil satu atau beberapa deklarasi gambar yang dipisahkan koma, yang terdiri dari string URL atau fungsi url() yang diikuti dengan resolusi terkait. Contoh:

background-image:  -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

Pernyataan ini akan memberi tahu browser bahwa ada dua gambar yang dapat dipilih. Salah satunya dioptimalkan untuk 1x layar, dan satu lagi untuk 2x tampilan. Kemudian, browser dapat memilih mana yang akan dimuat, berdasarkan berbagai faktor, yang bahkan mungkin termasuk kecepatan jaringan, jika browser sudah cukup cerdas (saat ini tidak diimplementasikan sejauh yang saya tahu).

Selain memuat gambar yang benar, browser juga akan menskalakannya sebagaimana mestinya. Dengan kata lain, browser mengasumsikan bahwa 2 gambar dua kali lebih besar dari gambar 1x, sehingga akan menurunkan skala gambar 2x dengan faktor 2, sehingga gambar yang ditampilkan memiliki ukuran yang sama di halaman.

Selain menetapkan 1x, 1,5x, atau Nx, Anda juga dapat menentukan kepadatan piksel perangkat tertentu dalam dpi.

Tindakan ini berfungsi dengan baik, kecuali di browser yang tidak mendukung properti image-set, yang tidak akan menampilkan gambar sama sekali. Hal ini jelas buruk, jadi Anda harus menggunakan penggantian (atau serangkaian penggantian) untuk mengatasi masalah tersebut:

background-image: url(icon1x.jpg);
background-image: -webkit-image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);
/* This will be useful if image-set gets into the platform, unprefixed.
    Also include other prefixed versions of this */
background-image: image-set(
  url(icon1x.jpg) 1x,
  url(icon2x.jpg) 2x
);

Hal di atas akan memuat aset yang sesuai di browser yang mendukung kumpulan gambar, dan kembali ke aset 1x jika tidak. Peringatan yang jelas adalah bahwa meskipun dukungan browser image-set() rendah, sebagian besar agen pengguna akan mendapatkan aset 1x.

Demo ini menggunakan image-set() untuk memuat gambar yang benar, dan kembali ke aset 1x jika fungsi CSS ini tidak didukung.

Pada tahap ini, Anda mungkin bertanya-tanya mengapa tidak hanya polyfill (yaitu, membangun shim JavaScript untuk) image-set() dan menyebutnya sehari? Ternyata, menerapkan polyfill yang efisien untuk fungsi CSS cukup sulit. (Untuk mengetahui penjelasan mendetail, lihat diskusi www-style ini).

Gambar srcset

Berikut adalah contoh srcset:

<img alt="my awesome image"
  src="banner.jpeg"
  srcset="banner-HD.jpeg 2x, banner-phone.jpeg 640w, banner-phone-HD.jpeg 640w 2x">

Seperti yang dapat Anda lihat, selain deklarasi x yang disediakan image-set, elemen srcset juga menggunakan nilai w dan h yang sesuai dengan ukuran area pandang, sehingga mencoba menayangkan versi yang paling relevan. Contoh di atas akan menayangkan banner-phone.jpeg ke perangkat dengan lebar area pandang di bawah 640 px, banner-phone-HD.jpeg hingga perangkat DPI tinggi layar kecil, banner-HD.jpeg ke perangkat DPI tinggi dengan layar di atas 640 piksel, dan banner.jpeg untuk perangkat lainnya.

Menggunakan image-set untuk elemen gambar

Karena atribut srcset pada elemen img tidak diterapkan di sebagian besar browser, Anda mungkin tergoda untuk mengganti elemen img dengan <div> dengan latar belakang dan menggunakan pendekatan set image. Langkah ini akan berhasil, dengan peringatan. Kelemahan di sini adalah tag <img> memiliki nilai semantik yang sudah lama. Dalam praktiknya, hal ini terutama penting untuk web crawler dan alasan aksesibilitas.

Jika akhirnya menggunakan -webkit-image-set, Anda mungkin tergoda untuk menggunakan properti CSS latar belakang. Kelemahan dari pendekatan ini adalah Anda perlu menentukan ukuran gambar, yang tidak diketahui jika Anda menggunakan gambar non-1x. Daripada melakukannya, Anda dapat menggunakan properti CSS konten seperti berikut:

<div id="my-content-image"
  style="content: -webkit-image-set(
    url(icon1x.jpg) 1x,
    url(icon2x.jpg) 2x);">
</div>

Tindakan ini akan otomatis menskalakan gambar berdasarkan devicePixelRatio. Lihat contoh ini dari cara kerja teknik di atas, dengan penggantian tambahan ke url() untuk browser yang tidak mendukung image-set.

Polyfilling srcset

Salah satu fitur berguna srcset adalah bahwa ia dilengkapi dengan penggantian alami. Jika atribut srcset tidak diterapkan, semua browser akan tahu cara memproses atribut src. Selain itu, karena ini hanya atribut HTML, Anda dapat membuat polyfill dengan JavaScript.

Polyfill ini dilengkapi dengan pengujian unit untuk memastikannya semirip mungkin dengan spesifikasi. Selain itu, ada pemeriksaan yang mencegah polyfill mengeksekusi kode apa pun jika srcset diimplementasikan secara native.

Berikut adalah demo polyfill dalam penerapannya.

Kesimpulan

Tidak ada butir ajaib untuk memecahkan masalah gambar DPI tinggi.

Solusi termudah adalah menghindari gambar sepenuhnya, memilih SVG dan CSS. Namun, hal ini tidak selalu realistis, terutama jika Anda memiliki gambar berkualitas tinggi di situs Anda.

Pendekatan di JS, CSS, dan penggunaan sisi server memiliki kekuatan dan kelemahannya masing-masing. Namun, pendekatan yang paling menjanjikan adalah memanfaatkan fitur browser baru. Meskipun dukungan browser untuk image-set dan srcset masih belum lengkap, ada penggantian yang wajar untuk digunakan saat ini.

Ringkasnya, rekomendasi saya adalah sebagai berikut: