Minifique e compacte payloads de rede com o brotli

Michael DiBlasio
Michael DiBlasio

Este codelab é uma extensão do guia Minificar e compactar payloads de rede codelab e pressupõe que você conhece os conceitos básicos de compactação. Conforme em comparação com outros algoritmos de compactação, como gzip, este codelab mostra como A compactação Brotli pode reduzir ainda mais as taxas de compactação e o desempenho geral do seu app tamanho.

Captura de tela do aplicativo

Medir

Antes de começar a incluir as otimizações, é sempre uma boa ideia analisar primeiro o estado atual do aplicativo.

  1. Clique em Remixar para editar para tornar o projeto editável.
  2. Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia tela cheia

Na versão anterior, Minifique e compacte payloads de rede codelab, reduzimos o tamanho de main.js de 225 KB para 61,6 KB. Neste codelab, você vai aprender a vamos mostrar como a compactação de Brotli pode reduzir ainda mais o tamanho desse pacote.

Compressão Brotli

Brotli (link em inglês) é um algoritmo de compactação mais recente que pode oferecer compactação de texto ainda melhor resultados que gzip. De acordo com CertSimple, a performance de Brotli é:

  • 14% menor que gzip para JavaScript
  • 21% menor que gzip para HTML
  • 17% menor que gzip no CSS

Para usar o Brotli, seu servidor precisa ser compatível com HTTPS. O Brotli é compatível com o versões mais recentes da maioria dos navegadores. Navegadores que oferecem suporte ao Brotli vão incluir br em cabeçalhos Accept-Encoding:

Accept-Encoding: gzip, deflate, br

É possível determinar qual algoritmo de compactação é usado pelo Content-Encoding na guia "Rede" das Ferramentas para desenvolvedores do Chrome (Command+Option+I ou Ctrl+Alt+I):

Painel Network

Como ativar o Brotli

Compactação dinâmica

A compressão dinâmica envolve a compactação de recursos em tempo real à medida que eles são solicitado pelo navegador.

Prós

  • A criação e a atualização de versões compactadas salvas de recursos não precisam ser feito.
  • A compactação em tempo real funciona especialmente bem para páginas da Web que são geradas de modo dinâmico.

Contras

  • A compactação de arquivos em níveis mais altos para obter taxas de compactação melhores leva mais longas. Isso pode causar um impacto na performance enquanto o usuário espera os recursos compactadas antes de serem enviadas pelo servidor.

Compactação dinâmica com o Node/Express

O arquivo server.js é responsável por configurar o servidor do nó que hospeda o aplicativo.

var express = require('express');

var app = express();

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

var listener = app.listen(process.env.PORT, function() {
  console.log('Your app is listening on port ' + listener.address().port);
});

No momento, tudo o que isso faz é importar express e usar o express.static middleware para carregar todos os arquivos estáticos HTML, JS e CSS na public/directory (e esses arquivos são criados pelo webpack em cada build).

Para garantir que todos os recursos sejam compactados usando brotli sempre que forem solicitado, o shrink-ray pode ser usado. Para começar, adicione-o como um devDependency no package.json:

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

E importe-o para o arquivo do servidor, server.js:

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

E adicione-o como um middleware antes de express.static ser ativado:

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

// compress all requests
app.use(shrinkRay());

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

Agora, atualize o app e confira o tamanho do pacote no painel "Network":

Tamanho do pacote com compactação Brotli dinâmica

Agora é possível conferir que a brotli é aplicada de bz no cabeçalho Content-Encoding. main.bundle.js foi reduzido de 225 KB para 53,1 KB. Isso é cerca de 14% menor em comparação com gzip (61,6 KB).

Compactação estática

A ideia por trás da compactação estática é ter os recursos compactados e salvos com antecedência período.

Prós

  • A latência devido aos altos níveis de compactação não é mais uma preocupação. Nada precisa acontecer instantaneamente para comprimir arquivos, pois agora eles podem ser obtidos diretamente.

Contras

  • Os recursos precisam ser compactados em cada build. Os tempos de build podem aumentar significativamente se altos níveis de compactação forem usados.

Compactação estática com o Node/Express e o webpack

Como a compactação estática envolve a compactação antecipada de arquivos, o webpack podem ser modificadas para compactar recursos como parte da etapa de criação. A brotli-webpack-plugin pode ser usada para isso.

Para começar, adicione-o como um devDependency no package.json:

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

Como qualquer outro plug-in do webpack, importe-o no arquivo de configurações, webpack.config.js:

var path = require("path");

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

Inclua-o na matriz de plug-ins:

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

A matriz do plug-in usa os seguintes argumentos:

  • asset: o nome do recurso de destino.
  • [file] foi substituído pelo nome do arquivo do recurso original.
  • test: todos os recursos que correspondem a essa RegExp (ou seja, recursos JavaScript que terminam em .js) são processados.

Por exemplo, main.js seria renomeado como main.js.br.

Quando o aplicativo é recarregado e criado novamente, uma versão compactada do pacote principal é foi criado. Abra o Glitch Console para conferir o conteúdo final public/ que é exibido pelo servidor do nó.

  1. Clique no botão Ferramentas.
  2. Clique no botão Console.
  3. No console, execute os comandos a seguir para mudar para public e confira todos os seus arquivos:
cd public
ls -lh
Tamanho do pacote com compactação Brotli estática

A versão compactada brotli do pacote, main.bundle.js.br, foi salva aqui também é 76% menor em tamanho (225 KB versus 53 KB) do que main.bundle.js.

Em seguida, diga ao servidor para enviar esses arquivos compactados sempre que versões originais do JS estão sendo solicitadas. Isso pode ser feito definindo uma nova rota em server.js antes que os arquivos sejam disponibilizados com express.static.

var express = require('express');

var 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 é usada para informar ao servidor como responder a uma solicitação GET para uma em um endpoint específico. Uma função de callback é usada para definir como lidar com o solicitação. O trajeto funciona assim:

  • Especificar '*.js' como o primeiro argumento significa que ele funciona para cada que é disparado para buscar um arquivo JS.
  • No callback, .br é anexado ao URL da solicitação e ao O cabeçalho de resposta Content-Encoding está definido como br.
  • O cabeçalho Content-Type é definido como application/javascript; charset=UTF-8 para especificar o tipo MIME.
  • Por fim, next() garante que a sequência continue em qualquer callback que possa ser o próximo.

Como alguns navegadores podem não ser compatíveis com a compactação brotli, confirme se o brotli é suportado antes de retornar o arquivo compactado brotli verificando o O cabeçalho da solicitação Accept-Encoding inclui br:

var express = require('express');

var 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'));

Quando o app recarregar, confira o painel Network mais uma vez.

Tamanho do pacote de 53,1 KB (de 225 KB)

Pronto. Você usou a compactação Brotli para compactar ainda mais seus recursos.

Conclusão

Este codelab ilustrou como o brotli pode reduzir ainda mais a duração geral tamanho. Quando compatível, o brotli é um algoritmo de compactação mais eficiente do que gzip.