Este codelab é uma extensão do Minificar e compactar payloads de rede
e pressupõe que você conheça os conceitos básicos de compactação. Em
comparação com outros algoritmos de compactação, como gzip, este codelab mostra como
a compactação Brotli (br) pode reduzir ainda mais as taxas de compactação e o tamanho
geral do app.

Medida
Antes de adicionar otimizações, é sempre bom analisar o estado atual do aplicativo.
- Clique em Remix to Edit para tornar o projeto editável.
- Para visualizar o site, pressione View App. Em seguida, pressione
Fullscreen
.
No codelab Minificar e compactar payloads de rede,
reduzimos o tamanho de main.js de 225 KB para 61,6 KB. Neste codelab, você
vai aprender como a compactação Brotli pode reduzir ainda mais o tamanho do pacote.
Compactação Brotli
O Brotli
é um algoritmo de compactação mais recente que pode fornecer resultados de compactação de texto ainda melhores
do que o gzip. De acordo com o
CertSimple, o desempenho do Brotli é:
- 14% menor que
gzippara JavaScript - 21% menor que
gzippara HTML - 17% menor que
gzippara CSS
Para usar o Brotli, seu servidor precisa ser compatível com HTTPS. O Brotli é compatível com todos os navegadores mais recentes. Os navegadores compatíveis com o Brotli
incluem br nos cabeçalhos Accept-Encoding:
Accept-Encoding: gzip, deflate, br
É possível determinar qual algoritmo de compactação é usado usando o campo Content-Encoding na guia "Rede" das Ferramentas para Desenvolvedores do Chrome (Command+Option+I ou Ctrl+Alt+I):
Como ativar o Brotli
A configuração de um servidor da Web para enviar recursos codificados com Brotli depende de como você planeja codificá-los. As opções são compactar dinamicamente os recursos com o Brotli no momento da solicitação (dinâmica) ou codificá-los com antecedência para que já estejam compactados quando o usuário os solicitar (estática).
Compactação dinâmica
A compactação dinâmica envolve a compactação de recursos em tempo real conforme eles são solicitados pelo navegador.
Vantagens
- Não é necessário criar e atualizar versões compactadas salvas de recursos.
- A compactação em tempo real funciona especialmente bem para páginas da Web geradas dinamicamente.
Desvantagens
- A compactação de arquivos em níveis mais altos para alcançar melhores taxas de compactação leva mais tempo. Isso pode afetar o desempenho, já que o usuário precisa esperar que os recursos sejam compactados antes de serem enviados pelo servidor.
Compactação dinâmica com Node e Express
O arquivo server.js é responsável por configurar o servidor Node que hospeda
o aplicativo.
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}`);
});
Isso importa express e usa o middleware express.static
para carregar todos os arquivos HTML, JS e CSS estáticos no
public/directory (e esses arquivos são criados pelo webpack em cada build).
Para garantir que todos os recursos sejam compactados usando o brotli sempre que forem
solicitados, use o módulo
shrink-ray. Comece adicionando-o como um devDependency em package.json:
"devDependencies": {
// ...
"shrink-ray": "^0.1.3"
},
E importe-o para o arquivo do servidor, server.js:
const express = require('express');
const shrinkRay = require('shrink-ray');
E adicione-o como um middleware antes de express.static ser montado:
// ...
const 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:
Agora você pode ver que brotli é aplicado 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 é compactar e salvar os recursos com antecedência.
Vantagens
- A latência devido a altos níveis de compactação não é mais um problema. Não é preciso fazer nada em tempo real para compactar arquivos, já que agora eles podem ser buscados diretamente.
Desvantagens
- Os recursos precisam ser compactados em cada build. Os tempos de build podem aumentar significativamente se forem usados níveis de compactação altos.
Compactação estática com Node e Express com webpack
Como a compactação estática envolve a compactação de arquivos com antecedência, as configurações do webpack
podem ser modificadas para compactar recursos como parte da etapa de build. O
brotli-webpack-plugin pode ser usado para isso.
Comece adicionando-o como um devDependency em 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');
E inclua-o na matriz de plug-ins:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
A matriz de plug-ins usa os seguintes argumentos:
asset: o nome do recurso de destino.[file]é substituído pelo nome do arquivo de 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 app é recarregado e recriado, uma versão compactada do pacote principal é
criada. Abra o console do Glitch para conferir o que há dentro do diretório final
public/ que é disponibilizado pelo servidor Node.
- Clique no botão Ferramentas.
- Clique no botão Console.
- No console, execute os comandos a seguir para mudar para o diretório
publice ver todos os arquivos dele:
cd public
ls -lh
A versão compactada do pacote, main.bundle.js.br, agora também é salva
aqui e é ~76% menor (225 KB em comparação com 53 KB) do que
main.bundle.js.
Em seguida, instrua o servidor a enviar esses arquivos compactados com Brotli sempre que as
versões JS originais forem solicitadas. Para isso, defina uma nova
rota em server.js antes que os arquivos sejam disponibilizados com 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 é usado para informar ao servidor como responder a uma solicitação GET para um
endpoint específico. Uma função de callback é usada para definir como processar essa
solicitação. O trajeto funciona assim:
- Especificar
'*.js'como o primeiro argumento significa que isso funciona para todos os endpoints acionados para buscar um arquivo JS. - No callback,
.bré anexado ao URL da solicitação, e o cabeçalho de respostaContent-Encodingé definido comobr. - O cabeçalho
Content-Typeestá definido comoapplication/javascript; charset=UTF-8para especificar o tipo MIME. - Por fim,
next()garante que a sequência continue para qualquer callback que possa ser o próximo.
Como alguns navegadores podem não ser compatíveis com a compactação brotli, confirme se ela é
compatível antes de retornar o arquivo compactado com brotli. Para isso, verifique se o
cabeçalho da solicitação Accept-Encoding inclui 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'));
Depois que o app for recarregado, confira o painel Network mais uma vez.
Pronto. Você usou a compactação Brotli para compactar ainda mais seus recursos.
Conclusão
Este codelab mostrou como o brotli pode reduzir ainda mais o tamanho geral do
app. Quando compatível, o brotli é um algoritmo de compactação mais eficiente do que o
gzip.