Optimasi gambar

Taruh gambar berukuran penuh di src/ atau public/, arahkan sebuah <img> kepadanya, dan sitelo mengubah ukurannya, mengonversinya ke format modern, lalu menulis ulang tagnya dengan srcset. Tidak ada yang perlu diimpor, tidak ada komponen yang perlu dipelajari.

Mengaktifkannya

export default {
  images: true,
}

Pengodean dikerjakan oleh sharp, sebuah dependensi rekan opsional — pasang bersama sitelo ketika Anda menyalakan gambar:

npm install -D sharp

Situs yang melewatkan optimasi gambar tidak perlu memasangnya sama sekali.

Tulis <img> biasa

import { html, body, img } from 'javascript-to-html'

export default () =>
  html({ lang: 'id' },
    body(
      img({ src: '/images/hero.png', alt: 'Matahari terbit di pelabuhan' }),
    ),
  )

Sumber berukuran 3000×2000 keluar di ujung lain seperti ini:

<img src="/assets/img/hero.a1b2c3d4-3000.webp"
     alt="Matahari terbit di pelabuhan"
     sizes="100vw"
     width="3000" height="2000"
     loading="lazy" decoding="async"
     srcset="/assets/img/hero.9f8e7d6c-400.webp 400w,
             /assets/img/hero.5b4a3c2d-800.webp 800w,
             /assets/img/hero.7c6d5e4f-1200.webp 1200w,
             /assets/img/hero.a1b2c3d4-3000.webp 3000w">

Layar selebar sampai 400px mendapat berkas 400, sampai 800 mendapat 800, sampai 1200 mendapat 1200, dan yang lebih lebar mendapat 3000 penuh — peramban memilih anak tangga pertama yang menutupi viewport (dikalikan dua pada layar 2×).

Yang Anda dapat

Penulisan ulang berjalan di atas HTML hasil build, jadi ia mencakup gambar dari src/ maupun public/.

Begitu sebuah tag ditulis ulang, tidak ada lagi yang menunjuk berkas aslinya, sehingga secara bawaan ia dipangkas dari build. Hanya berkas yang benar-benar tidak dirujuk yang hilang: setiap berkas HTML, CSS, JS, XML, dan JSON dalam build dipindai, jadi berkas asli yang ditautkan dari <a href>, og:image, lampiran RSS, url() CSS, atau tag data-no-optimize akan tetap ada. Yang tidak bisa dilihatnya adalah URL yang dirangkai saat jalan di dalam skrip, atau yang dirender oleh island server — setel prune: false jika Anda punya yang seperti itu.

Opsi

export default {
  images: {
    widths: [400, 800, 1200],
    formats: ['avif', 'webp'],
    quality: { avif: 55, webp: 78, jpeg: 82 },
    exclude: ['**/og/**'],
  },
}

Dua format memberi Anda

AVIF lebih kecil tetapi lebih muda daripada WebP, jadi mendaftarkan keduanya membiarkan peramban memilih sekaligus menyimpan cadangan untuk yang lama:

<picture>
  <source type="image/avif" srcset="/assets/img/hero.*-400.avif 400w, ..." sizes="...">
  <source type="image/webp" srcset="/assets/img/hero.*-400.webp 400w, ..." sizes="...">
  <img src="/assets/img/hero.*-3000.png" alt="..." srcset="..." width="3000" height="2000">
</picture>

Satu ukuran, dengan menyebutnya

Gambar mini korsel, avatar, kisi kartu — sebagian gambar hanya pernah ditampilkan pada satu ukuran, dan satu tangga penuh mubazir untuknya. Nama berkas varian membawa hash konten, jadi Anda tidak bisa menulisnya sendiri; sebutkan lebarnya di URL dan tagnya keluar dengan satu berkas itu:

<img src="/images/hero.png?w=400" alt="Matahari terbit di pelabuhan">
<img src="/images/hero.png?w=400&format=jpeg" alt="Matahari terbit di pelabuhan">
<img src="/images/hero.png?w=200&h=200" alt="Matahari terbit di pelabuhan">
<img src="/images/hero.png?w=200&h=200&fit=contain" alt="Matahari terbit di pelabuhan">
<img src="/images/hero.png?w=200&h=200&background=fff" alt="Matahari terbit di pelabuhan">
<img src="/images/hero.png?w=200&h=200&position=top" alt="Matahari terbit di pelabuhan">
<img src="/assets/img/hero.9f8e7d6c-400.webp"
     alt="Matahari terbit di pelabuhan"
     width="400" height="267"
     loading="lazy" decoding="async">

Dengan beberapa formats terkonfigurasi, lebar yang disematkan tetap memberi Anda <picture>, dengan satu berkas per <source>. Namanya sama dengan yang dipakai vite-imagetools. URL jarak jauh tidak pernah diurai — string kuerinya milik asalnya — dan dengan images dimatikan, hosting statis mengabaikan kueri dan menyajikan berkas aslinya.

Membiarkan gambarnya memilih pemangkasan

Tepi atau sudut bisa diduga, tetapi korsel berisi foto campuran jarang punya subjek di tempat yang sama dua kali. entropy dan attention meminta sharp melihat tiap gambar dan menggeser jendela pemangkasan ke tempat yang ditemukannya layak disimpan:

<img src="/images/hero.png?w=300&h=300&position=entropy" alt="Matahari terbit di pelabuhan">
<img src="/images/team.jpg?w=300&h=300&position=attention" alt="Tim">

Keduanya heuristik biasa — tanpa model, tanpa pelatihan — jadi anggaplah sebagai nilai bawaan yang masuk akal untuk banyak gambar, bukan jaminan untuk satu gambar. Untuk gambar utama yang Anda pedulikan, sebutkan tepinya sendiri. Pilihannya hanya bergantung pada gambarnya, jadi ia deterministik dan disinggahkan seperti varian lain.

Menonaktifkannya

Tag yang sudah punya srcset, berada di dalam <picture>, atau menunjuk SVG, GIF beranimasi, maupun URL jarak jauh dibiarkan apa adanya. Untuk yang lain, katakan saja:

<img src="/images/exact.png" alt="Pixel art" data-no-optimize>

Gambar kartu sosial dan favicon tinggal di <meta> dan <link>, yang tidak pernah ditulis ulang di sini — keduanya mempertahankan URL tetapnya.

Gambar jarak jauh

Konten yang diimpor dari CMS sering menunjuk server orang lain. Nyalakan remote dan gambar-gambar itu diunduh, dioptimasi, lalu disajikan dari domain Anda sendiri:

export default {
  images: {
    remote: true,
  },
}

Pengambilan yang gagal meninggalkan tagnya persis seperti semula, disertai peringatan — asal yang labil tidak pernah menggagalkan build Anda. prune kemudian menghapus berkas asli lokal yang tidak lagi dirujuk apa pun.