Minimizza e comprimi i payload di rete con Brotli

Michael DiBlasio
Michael DiBlasio

Questo codelab è un'estensione del codelab Minimizza e comprime i payload di rete e presuppone che tu abbia familiarità con i concetti di base della compressione. Rispetto ad altri algoritmi di compressione, come gzip, questo codelab esplora come la compressione di Broli (br) può ridurre ulteriormente i rapporti di compressione e le dimensioni complessive della tua app.

Screenshot dell'app

Misura

Prima di iniziare ad aggiungere ottimizzazioni, è sempre buona prassi analizzare innanzitutto lo stato attuale dell'applicazione.

  1. Fai clic su Remix per modificare per rendere il progetto modificabile.
  2. Per visualizzare l'anteprima del sito, premi Visualizza app. Quindi premi A schermo intero schermo intero.

Nel precedente codelab Minimizza e comprime i payload di rete, abbiamo ridotto le dimensioni di main.js da 225 KB a 61,6 KB. In questo codelab, scoprirai in che modo la compressione Brotli può ridurre ulteriormente le dimensioni del bundle.

Compressione Brotli

Brotli è un algoritmo di compressione più recente che può fornire risultati di compressione del testo ancora migliori rispetto a gzip. Secondo CertSimple, le prestazioni di Brotli sono:

  • Il 14% più piccolo di gzip per JavaScript
  • Il 21% più piccolo di gzip per HTML
  • 17% inferiore a gzip per il CSS

Per utilizzare Brotli, il tuo server deve supportare HTTPS. Brotli è supportato in tutti i browser moderni. I browser che supportano Brotli includeranno br nelle intestazioni Accept-Encoding:

Accept-Encoding: gzip, deflate, br

Puoi determinare quale algoritmo di compressione viene utilizzato utilizzando il campo Content-Encoding nella scheda Rete di Strumenti per sviluppatori di Chrome (Command+Option+I o Ctrl+Alt+I):

nel riquadro Rete. La colonna Codifica dei contenuti mostra le codifiche utilizzate per vari asset, tra cui gzip e brotli (br).

Come attivare Brotli

La modalità di configurazione di un server web per l'invio di risorse con codifica Brotli dipende da come prevedi di codificarle. Puoi scegliere di comprimere dinamicamente le risorse con Brotli al momento della richiesta (dinamico) o di codificarle in anticipo in modo che siano già compresse al momento della richiesta dell'utente (statico).

Compressione dinamica

La compressione dinamica prevede la compressione immediata degli asset quando vengono richiesti dal browser.

Vantaggi

  • Non è necessario creare e aggiornare le versioni compresse salvate delle risorse.
  • La compressione dinamica è particolarmente efficace per le pagine web generate dinamicamente.

Svantaggi

  • La compressione dei file a livelli superiori per ottenere rapporti di compressione migliori richiede più tempo. Ciò può causare un hit da rendimento in quanto l'utente attende che gli asset vengano compressi prima di essere inviati dal server.

Compressione dinamica con Node ed Express

Il file server.js è responsabile della configurazione del server Node che ospita l'applicazione.

const express = require('express');
const app = express();
app.use(express.static('public'));

const listener = app.listen(process.env.PORT, function() {
  console.log(`Your app is listening on port ${listener.address().port}`);
});

Tutto ciò che fa è importare express e utilizzare il middleware express.static per caricare tutti i file HTML, JS e CSS statici in public/directory (e questi file vengono creati da webpack con ogni compilazione).

Per assicurarti che tutte le risorse vengano compresse utilizzando brotli ogni volta che vengono richieste, puoi utilizzare il modulo shrink-ray. Per iniziare, aggiungilo come devDependency in package.json:

"devDependencies": {
  // ...
  "shrink-ray": "^0.1.3"
},

E importalo nel file del server, server.js:

const express = require('express');
const shrinkRay = require('shrink-ray');

Aggiungilo come middleware prima del montaggio di express.static:

// ...
const app = express();

// Compress all requests
app.use(shrinkRay());
app.use(express.static('public'));

Ora ricarica l'app e controlla le dimensioni del bundle nel riquadro Rete:

Dimensioni del bundle con compressione Brotli dinamica.

Ora puoi vedere che brotli è applicato da bz nell'intestazione Content-Encoding. main.bundle.js è stato ridotto da 225 KB a 53,1 KB. ovvero circa il 14% in meno rispetto a gzip (61,6 KB).

Compressione statica

L'idea alla base della compressione statica è comprimere e salvare gli asset in anticipo.

Vantaggi

  • La latenza dovuta a livelli di compressione elevati non è più un problema. Non è necessario eseguire alcuna operazione al volo per comprimere i file, poiché ora possono essere recuperati direttamente.

Svantaggi

  • Gli asset devono essere compressi a ogni build. I tempi di compilazione possono aumentare in modo significativo se vengono utilizzati livelli di compressione elevati.

Compressione statica con Node ed Express con webpack

Poiché la compressione statica prevede la compressione dei file in anticipo, le impostazioni di webpack possono essere modificate per comprimere gli asset nell'ambito del passaggio di compilazione. Per questo scopo, puoi utilizzare brotli-webpack-plugin.

Per iniziare, aggiungilo come devDependency in package.json:

"devDependencies": {
  // ...
 "brotli-webpack-plugin": "^1.1.0"
},

Come qualsiasi altro plug-in webpack, importalo nel file di configurazione,webpack.config.js:

var path = require("path");

//...
var BrotliPlugin = require('brotli-webpack-plugin');

e includilo nell'array di plugin:

module.exports = {
  // ...
  plugins: [
    // ...
    new BrotliPlugin({
      asset: '[file].br',
      test: /\.(js)$/
    })
  ]
},

L'array del plug-in utilizza i seguenti argomenti:

  • asset: il nome della risorsa di destinazione.
  • [file] viene sostituito con il nome file dell'asset originale.
  • test: vengono elaborati tutti gli asset che corrispondono a questa RegExp (ovvero gli asset JavaScript che terminano con .js).

Ad esempio, main.js verrebbe rinominato in main.js.br.

Quando l'app viene ricaricata e ricostruita, viene creata una versione compressa del bundle principale. Apri la console Glitch per dare un'occhiata al contenuto della directory public/ finale pubblicata dal server Node.

  1. Fai clic sul pulsante Strumenti.
  2. Fai clic sul pulsante Console.
  3. Nella console, esegui questi comandi per passare alla directory public e visualizzare tutti i relativi file:
cd public
ls -lh
Dimensioni del bundle con compressione Brotli statica

La versione compressa con brotli del bundle, main.bundle.js.br, viene ora salvata anche qui ed è circa il 76% più piccola (225 KB contro 53 KB) rispetto a main.bundle.js.

Successivamente, chiedi al server di inviare questi file compressi con Brotli ogni volta che vengono richieste le versioni JS originali. Per farlo, definisci un nuovo percorso in server.js prima che i file vengano pubblicati con express.static.

const express = require('express');
const app = express();

app.get('*.js', (req, res, next) => {
  req.url = req.url + '.br';
  res.set('Content-Encoding', 'br');
  res.set('Content-Type', 'application/javascript; charset=UTF-8');
  next();
});

app.use(express.static('public'));

app.get viene utilizzato per indicare al server come rispondere a una richiesta GET per un endpoint specifico. Viene quindi utilizzata una funzione di callback per definire come gestire questa richiesta. Il percorso funziona nel seguente modo:

  • Specificare '*.js' come primo argomento significa che questa operazione funziona per ogni endpoint attivato per recuperare un file JS.
  • All'interno del callback, .br viene allegato all'URL della richiesta e l'intestazione di risposta Content-Encoding è impostata su br.
  • L'intestazione Content-Type è impostata su application/javascript; charset=UTF-8 per specificare il tipo MIME.
  • Infine, next() garantisce che la sequenza continui a qualsiasi callback successivo.

Poiché alcuni browser potrebbero non supportare la compressione brotli, verifica che la compressione brotli sia supportata prima di restituire il file compresso con questo metodo controllando che l'intestazione della richiesta Accept-Encoding includa br:

const express = require('express');
const app = express();

app.get('*.js', (req, res, next) => {
  if (req.header('Accept-Encoding').includes('br')) {
    req.url = req.url + '.br';
    console.log(req.header('Accept-Encoding'));
    res.set('Content-Encoding', 'br');
    res.set('Content-Type', 'application/javascript; charset=UTF-8');
  }

  next();
});

app.use(express.static('public'));

Una volta ricaricata l'app, dai un'altra occhiata al riquadro Rete.

Dimensioni del bundle di 53,1 KB (da 225 KB)

Operazione riuscita. Hai utilizzato la compressione Brotli per comprimere ulteriormente gli asset.

Conclusione

Questo codelab ha illustrato come brotli può ridurre ulteriormente le dimensioni complessive della tua app. Se supportato, brotli è un algoritmo di compressione più potente di gzip.