Este codelab es una extensión del codelab de reducción y compresión de cargas útiles de red, y se da por sentado que ya conoces los conceptos básicos de la compresión. En comparación con otros algoritmos de compresión como gzip
, en este codelab se explora cómo la compresión Brotli puede reducir aún más los índices de compresión y el tamaño general de tu app.
Medir
Antes de comenzar a agregar optimizaciones, siempre es una buena idea analizar primero el estado actual de la aplicación.
- Haz clic en Remix to Edit para que el proyecto sea editable.
- Para obtener una vista previa del sitio, presiona Ver app. Luego, presiona Pantalla completa .
En el codelab de reducción y compresión de cargas útiles de red anterior, redujimos el tamaño de main.js
de 225 KB a 61.6 KB. En este codelab, explorarás cómo la compresión de Brotli puede reducir aún más el tamaño de este paquete.
Compresión Brotli
Brotli es un algoritmo de compresión más nuevo que puede proporcionar resultados de compresión de texto aún mejores que gzip
. Según CertSimple, el rendimiento de Brotli tiene las siguientes características:
- Un 14% más pequeño que
gzip
para JavaScript - un 21% más pequeño que
gzip
para HTML - Un 17% más pequeño que
gzip
para CSS
Para usar Brotli, el servidor debe admitir HTTPS. Brotli es compatible con las versiones más recientes de la mayoría de los navegadores. Los navegadores compatibles con Brotli incluirán br
en los encabezados Accept-Encoding
:
Accept-Encoding: gzip, deflate, br
Puedes determinar qué algoritmo de compresión se usa en el campo Content-Encoding
de la pestaña Red de Herramientas para desarrolladores de Chrome (Command+Option+I
o Ctrl+Alt+I
):
Habilitando Brotli
Compresión dinámica
La compresión dinámica implica comprimir elementos sobre la marcha a medida que el navegador los solicita.
Ventajas
- No es necesario crear y actualizar las versiones comprimidas guardadas de los elementos.
- La compresión sobre la marcha funciona especialmente bien para las páginas web que se generan de forma dinámica.
Desventajas
- La compresión de archivos en niveles más altos para lograr mejores índices de compresión lleva más tiempo. Esto puede provocar un problema de rendimiento, ya que el usuario espera a que se compriman los elementos antes de que el servidor los envíe.
Compresión dinámica con Node y Express
El archivo server.js
se encarga de configurar el servidor de Node que aloja la aplicación.
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);
});
Por el momento, lo único que hace es importar express
y usar el middleware express.static
para cargar todos los archivos HTML, JS y CSS estáticos en el public/directory
(y esos archivos se crean mediante webpack con cada compilación).
Para garantizar que todos los recursos se compriman con brotli cada vez que se soliciten, se puede usar el módulo shrink-ray
. Para comenzar, agrégalo como devDependency
en package.json
:
"devDependencies": {
//...
"shrink-ray": "^0.1.3"
},
Y, luego, impórtala en el archivo de servidor, server.js
:
var express = require('express');
var shrinkRay = require('shrink-ray');
Además, agrégalo como middleware antes de activar express.static
:
//...
var app = express();
// compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
Ahora, vuelve a cargar la app y observa el tamaño del paquete en el panel Network:
Ahora puedes ver que brotli
se aplica desde bz
en el encabezado Content-Encoding
.
main.bundle.js
se redujo de 225 KB a 53.1 KB. Esto es aproximadamente un 14% menor en comparación con gzip
(61.6 KB).
Compresión estática
La idea detrás de la compresión estática es comprimir los recursos y guardarlos de antemano.
Ventajas
- La latencia debida a altos niveles de compresión ya no es una preocupación. No es necesario que ocurra nada sobre la marcha para comprimir archivos, ya que ahora se pueden recuperar directamente.
Desventajas
- Los recursos se deben comprimir con cada compilación. Los tiempos de compilación pueden aumentar significativamente si se usan niveles altos de compresión.
Compresión estática con Node/Express y webpack
Dado que la compresión estática implica comprimir archivos con anticipación, se puede modificar la configuración del paquete web para comprimir elementos como parte del paso de compilación. Se puede usar brotli-webpack-plugin
para esto.
Para comenzar, agrégalo como devDependency
en package.json
:
"devDependencies": {
//...
"brotli-webpack-plugin": "^1.1.0"
},
Como cualquier otro complemento de webpack, impórtalo en el archivo de configuración, webpack.config.js
:
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
Además, inclúyelo dentro del array de complementos:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
El array de complementos usa los siguientes argumentos:
asset
: Es el nombre del recurso de destino.- Se reemplazará
[file]
por el nombre de archivo del recurso original. test
: Se procesan todos los elementos que coinciden con esta expresión regular (es decir, los recursos de JavaScript que terminan en.js
).
Por ejemplo, se cambiaría el nombre de main.js
a main.js.br
.
Cuando la app se vuelva a cargar y compilar, se creará una versión comprimida del paquete principal. Abre la consola de Glitch para ver el contenido del directorio final public/
que entrega el servidor de Node.
- Haz clic en el botón Herramientas.
- Haz clic en el botón Consola.
- En la consola, ejecuta los siguientes comandos para cambiar al directorio
public
y ver todos sus archivos:
cd public
ls -lh
La versión comprimida de brotli del paquete, main.bundle.js.br
, ahora también se guarda aquí y es ~76% más pequeña (225 KB frente a 53 KB) que main.bundle.js
.
A continuación, indícale al servidor que envíe estos archivos comprimidos con brotli cada vez que se soliciten sus versiones de JS originales. Para ello, define una ruta nueva en server.js
antes de que los archivos se entreguen con 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
se usa para indicarle al servidor cómo responder a una solicitud GET
para un extremo específico. Luego, se utiliza una función de devolución de llamada para definir cómo manejar esta solicitud. La ruta funciona de la siguiente manera:
- Especificar
'*.js'
como primer argumento significa que esto funciona para cada extremo que se activa a fin de recuperar un archivo JS. - Dentro de la devolución de llamada, se adjunta
.br
a la URL de la solicitud y el encabezado de respuestaContent-Encoding
se establece enbr
. - El encabezado
Content-Type
se establece enapplication/javascript; charset=UTF-8
para especificar el tipo de MIME. - Por último,
next()
garantiza que la secuencia continúe hasta cualquier devolución de llamada que pueda ser la siguiente.
Debido a que es posible que algunos navegadores no admitan la compresión de brotli, confirma que brotli sea compatible antes de mostrar el archivo comprimido brotli. Para ello, verifica que el encabezado de la solicitud Accept-Encoding
incluya 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'));
Una vez que se vuelva a cargar la app, vuelve a ver el panel Network.
¡Listo! Usaste la compresión Brotli para comprimir aún más tus recursos.
Conclusión
En este codelab, se ilustró cómo brotli
puede reducir aún más el tamaño general de tu app. Cuando es compatible, brotli
es un algoritmo de compresión más potente que gzip
.