Automatizzare la compressione e la codifica

Rendi la generazione di origini di immagini ad alte prestazioni una parte perfetta del tuo il processo di sviluppo.

Tutte le sintassi presenti in questo corso, dalla codifica dei dati immagine alla codifica markup alla base delle immagini adattabili: sono metodi di comunicazione tra le macchine e le macchine. Hai ha scoperto vari modi per far sì che un browser client comunichi le sue esigenze a un server e che un server risponda in natura. Il markup delle immagini adattabili (srcset e sizes in particolare) riesce a descrivere una quantità scioccante di informazioni relativamente con pochi caratteri. Meglio o peggio, la brevità è dovuta alla progettazione: rende queste sintassi meno concise e così più facili per gli sviluppatori potrebbero renderli più difficili da analizzare per un browser. Maggiore è la complessità aggiunta a una stringa, più possibili errori dei parser o differenze involontarie di comportamento da un browser all'altro.

Una finestra di codifica automatica delle immagini.

Tuttavia, la stessa caratteristica che può rendere questi soggetti così intimidatori può anche fornirti delle soluzioni: una sintassi semplice read dalle macchine è una sintassi scritta più facilmente dalle loro macchine. Quasi certamente hai visto molti esempi di modelli codifica e compressione di immagini come utente del web: qualsiasi immagine caricata sul Web tramite piattaforme di social media, contenuti sistemi di gestione dei contenuti (CMS) e persino i client di posta passeranno quasi inevitabilmente attraverso un sistema che ridimensiona, ricodifica, e li comprime.

Analogamente, attraverso plug-in, librerie esterne, strumenti autonomi per il processo di compilazione o un uso responsabile dello scripting lato client, il markup dell'immagine adattabile si presta subito all'automazione.

Queste sono le due preoccupazioni principali relative all'automazione delle prestazioni delle immagini: gestione della creazione delle immagini (le loro codifiche), compressione e le origini alternative che utilizzerai per compilare un attributo srcset, generando così il nostro markup rivolto agli utenti. In questo modulo scoprirai alcuni approcci comuni alla gestione delle immagini nell'ambito di un flusso di lavoro moderno, che sia fase automatizzata del processo di sviluppo, attraverso il framework o il sistema di gestione dei contenuti alla base del tuo sito, oppure sono quasi completamente astratti da una rete CDN (Content Delivery Network) dedicata.

Automatizzare la compressione e la codifica

Difficilmente ti ritroverai in una posizione in cui poter determinare manualmente la codifica e il livello ideali una compressione di ogni singola immagine da usare in un progetto, come non faresti. Come è importante che le dimensioni di trasferimento delle immagini siano il più piccolo possibile, delle impostazioni di compressione e il salvataggio di origini alternative per ogni asset immagine destinato a un sito web di produzione introdurrà un enorme collo di bottiglia nel lavoro quotidiano.

Come hai appreso durante la lettura dei vari formati e tipi di compressione delle immagini, la codifica più efficiente per un'immagine sarà sempre dettata da questa impostazione. dei relativi contenuti e, come hai imparato nelle immagini adattabili, le dimensioni alternative necessarie per le origini delle immagini saranno dettate dalla posizione che queste immagini occupano nel layout della pagina. In un flusso di lavoro moderno, dovrai affrontare queste decisioni a livello olistico piuttosto che individualmente, determinando una serie di valori predefiniti sensibili per le immagini, più adatti ai contesti in cui il loro utilizzo.

Quando si scelgono le codifiche per una directory di immagini fotografiche, AVIF è il chiaro vincitore per qualità e dimensioni di trasferimento. ma ha un supporto limitato, WebP offre un'alternativa moderna e ottimizzata e JPEG è l'impostazione predefinita più affidabile. L'opzione alternativa dimensioni che dobbiamo produrre per le immagini destinate a occupare una barra laterale in un layout di pagina varieranno molto dalle immagini significate per occupare l'intera area visibile del browser nei punti di interruzione più alti. Per le impostazioni di compressione è necessario controllare la sfocatura e artefatti di compressione su più file risultanti, lasciando meno spazio per il ritaglio di ogni possibile byte da ogni immagine in cambio di un flusso di lavoro più flessibile e affidabile. In breve, seguirai lo stesso processo decisionale che hai utilizzato per capire meglio questo corso.

Per quanto riguarda l'elaborazione stessa, ci sono un enorme numero di librerie di elaborazione di immagini open source che forniscono metodi di convertendo, modificando e modificando le immagini in batch, concorrendo su velocità, efficienza e affidabilità. Queste elaborazioni consente di applicare le impostazioni di codifica e compressione a intere directory delle immagini contemporaneamente, senza aprire un software di modifica delle immagini e in modo da preservare le fonti delle immagini originali, qualora queste impostazioni poterla regolare all'istante. Sono progettate per essere eseguite in una vasta gamma di contesti, dall'ambiente di sviluppo locale lo stesso server web, ad esempio ImageMin incentrato sulla compressione per Node.js può essere esteso per adattarsi ad applicazioni specifiche attraverso un array di plug-in, mentre ImageMagick multipiattaforma e Sharp basati su Node.js offrono un numero sbalorditivo di funzionalità pronte all'uso.

Queste librerie di elaborazione delle immagini consentono agli sviluppatori di creare strumenti dedicati all'ottimizzazione delle immagini senza problemi come parte dei tuoi processi di sviluppo standard, assicurandoti che il progetto faccia sempre riferimento a un'immagine pronta per la produzione con il minor overhead possibile.

Flussi di lavoro e strumenti per lo sviluppo locale

È possibile usare Task-runner e bundler come Grunt, Gulp o Webpack ottimizzare gli asset immagine insieme ad altre attività comuni correlate al rendimento, come la minimizzazione di CSS e JavaScript. A illustra, prendiamo un caso d'uso relativamente semplice: una directory nel tuo progetto contiene una decina di immagini fotografiche, destinati a essere utilizzati su un sito web rivolto al pubblico.

Innanzitutto, dovrai garantire una codifica coerente ed efficiente per queste immagini. Come hai appreso nei moduli precedenti, WebP è uno standard efficiente per le immagini fotografiche in termini di qualità e dimensioni del file. WebP è ben supportato, ma non è universalmente supportato, quindi ti consigliamo di includere anche un'immagine di riserva sotto forma di JPEG progressivo. Poi, per usare l'attributo srcset per una pubblicazione efficiente di questi asset, dovrai generare più dimensioni alternative per ogni codifica.

Anche se sarebbe un'attività ripetitiva e dispendiosa in termini di tempo se eseguita con un software di modifica delle immagini, gli addetti alle attività come I gulp sono progettati per automatizzare esattamente questo tipo di ripetizione. Il componente gulp-adattabile che utilizza Sharp, è un'opzione tra molte che seguono uno schema simile: raccogliendo tutti i file in una directory di origine, ricodificandoli e comprimindoli in base alla stessa "qualità" standardizzata una forma breve che hai imparato in Formati delle immagini e compressione. I file risultanti vengono quindi restituiti in un percorso da te definito, pronto per essere consultato negli attributi src degli elementi img rivolti agli utenti lasciando i file originali intatti.

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

Con un processo come questo in atto, non subirebbero danni a un ambiente di produzione se qualcuno sul progetto inavvertitamente ha aggiunto una fotografia codificata come enorme PNG truecolor alla directory contenente le fonti delle immagini originali, indipendentemente la codifica dell'immagine originale, questa attività produrrà un file di riserva WebP efficiente e un file JPEG progressivo affidabile, livello di compressione che può essere regolato facilmente e all'istante. Naturalmente, questo processo garantisce anche che l'immagine originale file verranno conservati all'interno dell'ambiente di sviluppo del progetto, il che significa che queste impostazioni possono essere e solo l'output automatico sarà sovrascritto.

Per ottenere l'output di più file, occorre passare più oggetti di configurazione, tutti gli stessi, a parte l'aggiunta di una chiave width e un valore in pixel:

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

Nel caso dell'esempio precedente, l'immagine originale (monarch.png) era superiore a 3,3 MB. Il file più grande generato questa attività (monarch-1000.jpeg) è di circa 150 KB. Il più piccolo, monarch-400.web, è di soli 32 KB.

[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

Ovviamente ti consigliamo di esaminare attentamente i risultati per individuare gli artefatti di compressione ed eventualmente aumentare la compressione per ulteriori risparmi. Poiché questa attività non è distruttiva, queste impostazioni possono essere modificate facilmente.

Detto ciò, in cambio dei pochi kilobyte che potresti ottenere con un'attenta ottimizzazione manuale, ottieni un processo non solo efficiente, ma resiliente: uno strumento che applica perfettamente le tue conoscenze sugli asset immagine ad alte prestazioni. a un intero progetto, senza alcun intervento manuale.

Markup delle immagini adattabili nella pratica

Il completamento degli attributi srcset in genere è una procedura manuale semplice, poiché in realtà l'attributo acquisisce solo informazioni sulla configurazione che hai già eseguito durante la generazione delle origini. Nelle attività descritte sopra, abbiamo definito i nomi dei file e le informazioni sulla larghezza che il nostro attributo seguirà:

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

Ricorda che i contenuti dell'attributo srcset sono descrittivi, non prescrittivi. Non c'è niente di male nel sovraccaricare srcset, purché le proporzioni di ogni origine siano coerenti. Un attributo srcset può contenere l'URI e la larghezza di ogni taglio alternativo generato dal server senza generare richieste non necessarie; più da cui forniamo un'immagine visualizzata, più efficiente sarà il browser in grado di personalizzare le richieste.

Come hai imparato con le immagini adattabili, ti consigliamo di utilizzare l'elemento <picture> per gestire senza problemi il WebP o JPEG di riserva. In questo caso, utilizzerai l'attributo type insieme a 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>

Come hai appreso, i browser che supportano WebP riconosceranno i contenuti dell'attributo type e selezioneranno tale <source> srcset dell'elemento come elenco di immagini candidati. Browser che non riconoscono image/webp come contenuto multimediale valido ignora questo <source> e utilizza invece l'attributo srcset dell'elemento <img> interno.

C'è un'altra considerazione da considerare in termini di supporto dei browser: i browser che non supportano il markup di immagini reattive hanno comunque bisogno di un video di riserva, altrimenti potremmo correre il rischio che l'immagine venga danneggiata in particolari contesti di navigazione. Poiché <picture>, <source> e srcset vengono tutte ignorate in questi browser, pertanto è consigliabile specificare una sorgente predefinita nel browser <img> src.

Poiché il ridimensionamento di un'immagine verso il basso è semplice visivamente e la codifica JPEG è universalmente supportata, il formato una scelta sensata.

<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 può essere un po' più difficile da gestire. Come hai imparato, sizes è necessariamente contestuale: non possono completare l'attributo senza conoscere la quantità di spazio che l'immagine deve occupare nel layout visualizzato. Per richieste più efficienti possibili, un attributo sizes preciso deve essere nel nostro markup al momento in cui queste richieste vengono creati dall'utente finale, molto prima che vengano richiesti gli stili che regolano il layout della pagina. sizes ometti del tutto non solo una violazione della specifica HTML, ma determina un comportamento predefinito equivalente a sizes="100vw", informando al browser che l'immagine sia vincolata solo dall'area visibile stessa, il che genera il numero maggiore di origini candidati possibili in fase di selezione.

Come nel caso di qualsiasi attività di sviluppo web particolarmente gravosa, sono stati creati numerosi strumenti per astrarre il processo di scrittura a mano libera degli attributi sizes. respImageLint è assolutamente Snippet di codice essenziale destinato a controllare l'accuratezza degli attributi sizes e fornire suggerimenti per migliorare. Viene eseguito come un bookmarklet, uno strumento che esegui nel browser, mentre l'utente punta alla pagina con il rendering completo contenente l'immagine elementi. In un contesto in cui il browser comprende appieno il layout della pagina, avrà una resa quasi perfetta consapevolezza dello spazio che un'immagine deve occupare in quel layout per ogni possibile dimensione dell'area visibile.

Report sulle immagini adattabili che mostra una mancata corrispondenza di dimensione/larghezza.

Uno strumento per l'analisi tramite lint degli attributi sizes è sicuramente utile, ma ha ancora più valore come strumento per generarli all'ingrosso. Come saprai, la sintassi srcset e sizes ha lo scopo di ottimizzare le richieste di asset immagine in modo visivamente semplice. Sebbene non dovrebbe essere mai utilizzato in produzione, un valore segnaposto sizes predefinito pari a 100vw è perfettamente ragionevole mentre lavori al layout di una pagina nel tuo ambiente di sviluppo locale. Una volta definiti gli stili di layout, esecuzione di respImageLint ti fornirà attributi sizes personalizzati che puoi copiare e incollare nel tuo markup, a un livello di dettaglio molto maggiore rispetto a quelli scritti a mano.

Report sulle immagini adattabili con le dimensioni suggerite.

Anche se le richieste di immagini avviate dal markup con rendering eseguito dal server avvengono troppo rapidamente e non è possibile generare un attributo sizes lato client da parte di JavaScript, lo stesso ragionamento non vale se le richieste vengono avviate lato client. Il progetto Lazysizes, Ad esempio, è possibile rinviare completamente le richieste di immagini fino a quando non è stato stabilito il layout, consentendo a JavaScript di generare i valori di sizes per noi: una grande comodità per te e una garanzia delle richieste più efficienti possibili per i tuoi utenti. Tieni presente, tuttavia, che questo approccio significa sacrificare l'affidabilità del markup del rendering eseguito dal server e la velocità ottimizzazioni integrate nei browser e l'avvio di queste richieste solo dopo il rendering della pagina avrà un impatto negativo sul punteggio LCP.

Ovviamente, se dipendi già da un framework di rendering lato client come React o Vue, si tratta di un debito che e, in questi casi, utilizzando Lazysizes, gli attributi sizes possono essere quasi completamente astratti. Meglio ancora: man mano che sizes="auto" su immagini con caricamento lento ottiene consenso e per le implementazioni native, il formato Lazysize diventerà di fatto un polyfill per il nuovo comportamento standardizzato del browser.