Sıkıştırmayı ve kodlamayı otomatikleştirme

Yüksek performanslı görüntü kaynakları oluşturmayı, geliştirme sürecinizin sorunsuz bir parçası haline getirin.

Bu kurstaki tüm söz dizimi, resim verilerinin kodlanmasından duyarlı görüntüleri destekleyen yoğun bilgi işaretlemeye kadar, makinelerin makinelerle iletişim kurmasını sağlayan yöntemlerdir. İstemci tarayıcısının ihtiyaçlarını bir sunucuya iletmesi ve sunucunun aynı şekilde yanıt vermesi için bir dizi yol keşfettiniz. Duyarlı resim işaretleme (özellikle srcset ve sizes), şok edici miktarda bilgiyi nispeten az sayıda karakterle açıklamayı başarır. Daha da kötüsü, bu kısalığın tasarımdan kaynaklandığını söyleyebiliriz: Bu söz diziminin daha kısa ve geliştiricilerin ayrıştırması kolay hale getirilmesi, tarayıcı tarafından ayrıştırılmayı zorlaştırabilirdi. Bir dizeye ne kadar karmaşıklık eklenirse, ayrıştırıcı hataları veya bir tarayıcı ile diğerine yönelik istenmeyen davranış farklılıkları da o kadar olasıdır.

Otomatik resim kodlama penceresi.

Ancak bu kişilerin bu kadar korkutucu hissetmelerini sağlayan aynı özellik size çözümler de sağlayabilir: Makinelerin kolayca okuduğu bir söz dizimi, daha kolay yazılan bir söz dizimidir. Bir web kullanıcısı olarak neredeyse birçok otomatik resim kodlama ve sıkıştırma örneğiyle karşılaşmışsınızdır: Sosyal medya platformları, içerik yönetim sistemleri (CMS) ve hatta e-posta istemcileri üzerinden web'e yüklenen tüm resimler, neredeyse her zaman bunları yeniden boyutlandıran, yeniden kodlayan ve sıkıştıran bir sistemden geçer.

Benzer şekilde; eklentiler, harici kitaplıklar, bağımsız derleme işlemi araçları veya istemci taraflı komut dosyası kullanımının sorumlu bir şekilde kullanılması gibi yöntemlerle, duyarlı resim işaretleme kolayca otomasyona uygundur.

Resim performansını otomatikleştirmeyle ilgili başlıca iki endişe kaynağı budur: Resim oluşturma (resimlerin kodlama, sıkıştırma ve srcset özelliğini doldurmak için kullanacağınız alternatif kaynaklar) yönetimi ve kullanıcılara yönelik işaretlememizi oluşturma. Bu modülde, ister sitenizi destekleyen çerçeve veya içerik yönetim sistemiyle ister geliştirme sürecinizde otomatik bir aşama olarak ya da özel bir içerik yayınlama ağıyla neredeyse tamamen soyutlanmış bir şekilde, modern bir iş akışının parçası olarak resimleri yönetmeye yönelik birkaç yaygın yaklaşım hakkında bilgi edineceksiniz.

Sıkıştırmayı ve kodlamayı otomatikleştirme

Bir projede kullanılması amaçlanan her bir görüntü için ideal kodlama ve sıkıştırma düzeyini manuel olarak belirlemeye vakit ayırabilecek durumda olmanız pek olası değildir. Resim aktarım boyutlarınızı mümkün olduğunca küçük tutmak her ne kadar önemli olsa da sıkıştırma ayarlarınıza ince ayar yapmak ve üretim web sitesine yönelik her resim öğesi için alternatif kaynakları yeniden kaydetmek , günlük işlerinizde büyük bir tıkanıklığa yol açabilir.

Çeşitli resim biçimleri ve sıkıştırma türlerini okurken öğrendiğiniz gibi, bir resim için en verimli kodlama her zaman içeriğe göre belirlenir. Duyarlı Resimler bölümünde de öğrendiğiniz gibi, resim kaynaklarınız için ihtiyaç duyacağınız alternatif boyutlar, bu resimlerin sayfa düzeninde bulundukları konuma göre belirlenir. Modern bir iş akışında, bu kararlara tek tek değil, bütünsel bir yaklaşımla yaklaşırsınız. Görüntüler için, kullanılmaları amaçlanan bağlamlara en uygun olan, makul varsayılanlar kümesini belirlersiniz.

Fotoğraf görüntülerinden oluşan bir dizin için kodlama seçerken, AVIF kalite ve aktarım boyutu açısından açık kazanan, ancak sınırlı destek sunan, WebP optimize edilmiş modern bir yedek, JPEG ise en güvenilir varsayılan seçenektir. Sayfa düzeninde bir kenar çubuğunu doldurması amaçlanan resimler için oluşturmamız gereken alternatif boyutlar, en yüksek ayrılma noktalarımızda tarayıcı görüntü alanının tamamını doldurmayı amaçlayan resimlerden çok farklı olacaktır. Sıkıştırma ayarları, oluşturulan birden fazla dosyadaki bulanıklaştırma ve sıkıştırma yapıları konusunda dikkatli olmayı gerektirir. Böylece, daha esnek ve güvenilir bir iş akışı için her resimden mümkün olan her bir baytı bölmek için daha az alan sağlanır. Özetle, bu kursta öğrendiğiniz karar verme sürecini genel hatlarıyla takip etmiş olacaksınız.

İşleme açısından, görüntüleri toplu olarak dönüştürme, değiştirme ve düzenleme yöntemleri sağlayan ve hız, verimlilik ve güvenilirlik açısından rekabet eden çok sayıda açık kaynak resim işleme kitaplığı vardır. Bu işleme kitaplıkları, resim düzenleme yazılımını açmanıza gerek kalmadan ve ayarların anında ayarlanması gerektiğinde orijinal resim kaynaklarınızı koruyacak şekilde tüm resim dizinlerine aynı anda kodlama ve sıkıştırma ayarlarını uygulayabilmenizi sağlar. Bunlar, yerel geliştirme ortamınızdan web sunucusunun kendisine kadar çeşitli bağlamlarda çalışacak şekilde tasarlanmıştır. Örneğin, Node.js için sıkıştırma odaklı ImageMin, bir dizi eklenti aracılığıyla belirli uygulamalara uyacak şekilde genişletilebilir. Öte yandan, platformlar arası ImageMagick ve Node.js tabanlı Sharp, oldukça büyük bir özellik sayısına sahiptir.

Bu görüntü işleme kitaplıkları, geliştiricilerin standart geliştirme süreçlerinizin bir parçası olarak resimleri sorunsuz bir şekilde optimize etmeye yönelik araçlar oluşturmasına olanak tanır. Böylece projeniz her zaman, mümkün olduğunca az ek yük ile üretime hazır görüntü kaynaklarına başvurur.

Yerel geliştirme araçları ve iş akışları

Grunt, Gulp veya Webpack gibi görev yürütücüler ve paketleyiciler, CSS ve JavaScript'in küçültülmesi gibi performansla ilgili diğer yaygın görevlerin yanı sıra resim öğelerini optimize etmek için kullanılabilir. Örnek verecek olursak, nispeten basit bir kullanım örneğini ele alalım: Projenizdeki bir dizin, herkese açık bir web sitesinde kullanılmak üzere tasarlanmış bir düzine fotoğraf görseli içerir.

İlk olarak, bu resimler için tutarlı ve verimli kodlama yapmanız gerekir. Önceki modüllerde öğrendiğiniz gibi, WebP, fotoğraf görüntüleri için hem kalite hem de dosya boyutu açısından etkili bir varsayılan seçenektir. WebP iyi bir şekilde desteklenir, ancak evrensel olarak desteklenmez. Bu nedenle, progresif JPEG biçiminde bir yedek de eklemeniz önerilir. Daha sonra, bu öğelerin etkili bir şekilde yayınlanması amacıyla srcset özelliğinden yararlanmak için her kodlama için birden çok alternatif boyut oluşturmanız gerekir.

Bu iş resim düzenleme yazılımıyla yapılırsa tekrar eden ve zaman alan bir iş olsa da Gulp gibi görev koçları, tam olarak bu tür tekrarı otomatikleştirecek şekilde tasarlanmıştır. Sharp'ı kullanan gulp-responsive eklentisi, aynı şablonu izleyen pek çok seçenekten biridir: tüm dosyaları kaynak dizinde toplamak, yeniden kodlamak ve Resim Biçimleri ve Sıkıştırma bölümünde öğrendiğiniz standartlaştırılmış "kalite" kısayoluna göre sıkıştırmak. Sonuçta elde edilen dosyalar, tanımladığınız bir yola çıkış olarak çıkartılır ve orijinal dosyalarınız değişmeden kalırken kullanıcıya yönelik img öğelerinizin src özelliklerinde başvurulmaya hazır olur.

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/'));
}

Böyle bir süreç yürütüldüğünde, projedeki bir kişi yanlışlıkla orijinal resim kaynaklarınızı içeren dizine devasa gerçek renkli PNG olarak kodlanmış bir fotoğrafı eklerse, bu görev verimli bir WebP ve güvenilir progresif JPEG yedeği üretir. Ayrıca, anında kolayca ayarlanabilen bir sıkıştırma düzeyinde olur. Elbette bu süreç, orijinal görüntü dosyalarınızın projenin geliştirme ortamında korunmasını da sağlar. Diğer bir deyişle, bu ayarlar yalnızca otomatik çıkışın üzerine yazılarak herhangi bir zamanda ayarlanabilir.

Birden çok dosya çıktısı almak için width anahtarı ve piksel cinsinden bir değer eklenmesi dışında, birden fazla yapılandırma nesnesi aktarırsınız.

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/'));
}

Yukarıdaki örnekte, orijinal resim (monarch.png) 3,3 MB'tan büyüktür. Bu görev tarafından oluşturulan en büyük dosya (monarch-1000.jpeg) yaklaşık 150 KB'tır. En küçük dosya olan monarch-400.web, yalnızca 32 KB boyutundadır.

[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

Elbette, görünür sıkıştırma yapıları için sonuçları dikkatlice incelemek veya ek tasarruf için sıkıştırmayı artırmak isteyebilirsiniz. Bu işlem verilerde değişiklik yapmadığından ayarlar kolayca değiştirilebilir.

Tüm bunlar sayesinde, dikkatli manuel mikro optimizasyon ile ortadan kaldırabileceğiniz birkaç kilobayt karşılığında yalnızca verimli değil aynı zamanda esnek bir süreç elde edersiniz. Bu araç, yüksek performanslı resim öğeleri hakkındaki bilginizi herhangi bir manuel müdahaleye gerek olmadan projenin tamamına sorunsuz bir şekilde uygulayan bir araçtır.

Pratikte duyarlı resim işaretleme

srcset özelliklerinin doldurulması genellikle basit bir manuel işlemdir. Çünkü özellik, yalnızca kaynaklarınızı oluştururken önceden yaptığınız yapılandırmayla ilgili bilgileri yakalar. Yukarıdaki görevlerde, özelliğimizin izleyeceği dosya adlarını ve genişlik bilgilerini belirledik:

srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w"

srcset özelliğinin içeriklerinin kuralcı değil, açıklayıcı olduğunu unutmayın. Her kaynağın en boy oranı tutarlı olduğu sürece srcset özelliğini aşırı yüklemenin bir zararı yoktur. srcset özelliği, gereksiz isteklere neden olmadan sunucu tarafından oluşturulan her alternatif kesimin URI'sini ve genişliğini içerebilir ve oluşturulan bir resim için ne kadar çok aday kaynak sağlarsak tarayıcı istekleri o kadar verimli bir şekilde uyarlayabilir.

Duyarlı Resimler konusunda öğrendiğiniz gibi, WebP veya JPEG yedek kalıbını sorunsuz bir şekilde işlemek için <picture> öğesini kullanabilirsiniz. Bu durumda, srcset ile uyum içinde type özelliğini kullanırsınız.

<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>

Daha önce öğrendiğiniz gibi, WebP'yi destekleyen tarayıcılar type özelliğinin içeriklerini tanır ve resim adaylarının listesi olarak bu <source> öğesinin srcset özelliğini seçer. image/webp öğesini geçerli bir medya türü olarak tanımayan tarayıcılar bu <source> öğesini yoksayar ve bunun yerine iç <img> öğesinin srcset özelliğini kullanır.

Tarayıcı desteği konusunda dikkat edilmesi gereken bir nokta daha var: Duyarlı resim işaretlemeyi desteklemeyen tarayıcılar, yine de bir yedek gerekir. Aksi takdirde, özellikle eski göz atma bağlamlarında bozuk resim riskiyle karşı karşıya kalabiliriz. <picture>, <source> ve srcset bu tarayıcılarda yoksayıldığı için iç <img> src özelliğinde varsayılan bir kaynak belirtmek isteriz.

Bir resmin aşağı doğru ölçeklendirilmesi görsel olarak sorunsuz olduğu ve JPEG kodlaması evrensel olarak desteklendiği için en büyük JPEG makul bir seçimdir.

<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 ile başa çıkmak daha zor olabilir. Daha önce öğrendiğiniz gibi, sizes mutlaka bağlamsaldır. Resmin oluşturulan düzende kapladığı alan miktarını bilmeden özelliği dolduramazsınız. Mümkün olan en verimli istekler için, sayfa düzenini yöneten stiller istenmeden çok önce, son kullanıcı bu isteklerin yapıldığı anda işaretlememizde doğru bir sizes özelliğinin olması gerekir. sizes yönergesinin tamamen atlanması, yalnızca HTML spesifikasyonunun ihlaline yol açmaz, aynı zamanda sizes="100vw" ile eşdeğer bir varsayılan davranışla sonuçlanır. Bu da tarayıcıya, bu resmin yalnızca görüntü alanının kendisi tarafından kısıtlandığı ve mümkün olan en büyük aday kaynaklarının seçilmesine neden olduğu konusunda bilgi verir.

Özellikle zahmetli web geliştirme görevlerinde olduğu gibi, elle yazma sizes özelliklerini soyutlamak için çeşitli araçlar oluşturulmuştur. respImageLint, sizes özelliklerinizin doğruluğunu kontrol etmek ve iyileştirme önerileri sunmak için tasarlanan kesinlikle önemli bir kod snippet'idir. Bir yer işareti uygulaması (tarayıcınızda çalıştırdığınız ve resim öğelerinizi içeren tam olarak oluşturulmuş sayfayı işaret eden bir araçtır) olarak çalıştırır. Tarayıcı, sayfa düzenini tam olarak anladığı bir bağlamda, aynı zamanda, bir resmin olası her görüntü alanı boyutunda bu düzende kapladığı alanın neredeyse piksel düzeyinde bir farkındalığına sahip olur.

Boyut/genişlik uyuşmazlığını gösteren duyarlı resim raporu.

sizes özelliklerinizi satırlamaya yarayan bir araç kesinlikle faydalı olsa da toptan satış yapmanızı sağlayan bir araç olarak daha da fazla değeri vardır. Bildiğiniz gibi srcset ve sizes söz dizimi, resim öğesi isteklerini görsel olarak sorunsuz bir şekilde optimize etmek amacıyla tasarlanmıştır. Üretimde kullanılması gerekmese de, yerel geliştirme ortamınızda bir sayfanın düzeni üzerinde çalışırken 100vw olan varsayılan sizes yer tutucu değeri son derece makul bir değerdir. Düzen stilleri oluşturulduktan sonra, respImageLint çalıştırmak size elle yazılandan çok daha büyük bir ayrıntı düzeyinde kopyalayıp işaretlemenize yapıştırabileceğiniz özelleştirilmiş sizes özellikleri sağlar:

Önerilen boyutlara sahip duyarlı resim raporu.

Sunucu tarafından oluşturulan işaretleme tarafından başlatılan resim istekleri, JavaScript'in istemci tarafı sizes özelliği oluşturamayacağı kadar hızlı gerçekleşse de bu istekler istemci tarafında başlatıldığında aynı mantık geçerli olmaz. Örneğin, Lazysizes projesi, resim isteklerini düzen oluşturulana kadar tamamen ertelemenize olanak tanır. Bu da JavaScript'in bizim için sizes değerlerimizi oluşturmasına olanak tanır. Bu da sizin için büyük bir kolaylık sağlar ve kullanıcılarınız için olası en verimli istekleri garanti altına alır. Bununla birlikte, bu yaklaşımın sunucu tarafından oluşturulan işaretlemenin güvenilirliğinden ve tarayıcılarda yerleşik olarak bulunan hız optimizasyonlarından ödün vermek anlamına geldiğini ve bu istekleri yalnızca sayfa oluşturulduktan sonra başlatmanın LCP puanınız üzerinde çok büyük bir olumsuz etkiye sahip olacağını unutmayın.

Elbette React veya Vue gibi bir istemci tarafı oluşturma çerçevesi kullanıyorsanız bu zaten ödemeniz gereken bir borçtur. Bu durumlarda, Geç Boyutları kullanmak sizes özelliklerinizin neredeyse tamamen soyutlanabileceği anlamına gelir. Daha da iyisi: Geç yüklenen görüntülerdeki sizes="auto", fikir birliği ve yerel uygulamalarda fikir birliğine vardıkça, Lazysizes yeni standart hale gelen bu tarayıcı davranışı için etkili bir şekilde bir çoklu dolgu haline gelecek.