Meminifikasi dan mengompresi payload jaringan dengan brotli

Michael DiBlasio
Michael DiBlasio

Codelab ini adalah ekstensi dari Minifikasi dan kompresi payload jaringan codelab dan mengasumsikan Anda telah familier dengan konsep dasar-dasar kompresi. Sebagai dibandingkan dengan algoritma kompresi lainnya seperti gzip, codelab ini mempelajari cara Kompresi Brotli dapat lebih mengurangi rasio kompresi dan keseluruhan ukuran.

Screenshot aplikasi

Ukur

Sebelum menambah pengoptimalan, sebaiknya Anda menganalisis status aplikasi saat ini.

  1. Klik Remix to Edit agar project dapat diedit.
  2. Untuk melihat pratinjau situs, tekan Lihat Aplikasi. Lalu tekan Layar penuh layar penuh.

Di artikel sebelumnya, Minifikasi dan kompresi payload jaringan codelab ini, kami mengurangi ukuran main.js dari 225 KB menjadi 61,6 KB. Dalam codelab ini, Anda akan mempelajari bagaimana kompresi Brotli dapat mengurangi ukuran paket ini lebih jauh.

Kompresi Brotli

Brotli adalah algoritma kompresi yang lebih baru yang dapat memberikan kompresi teks hasil dibandingkan gzip. Menurut CertSimple, performa Brotli:

  • 14% lebih kecil dari gzip untuk JavaScript
  • 21% lebih kecil dari gzip untuk HTML
  • 17% lebih kecil dari gzip untuk CSS

Untuk menggunakan Brotli, server Anda harus mendukung HTTPS. Brotli didukung di versi terbaru sebagian besar browser. Browser yang mendukung Brotli akan menyertakan br di header Accept-Encoding:

Accept-Encoding: gzip, deflate, br

Anda dapat menentukan algoritma kompresi mana yang digunakan melalui Content-Encoding di tab Jaringan Alat Developer Chrome (Command+Option+I atau Ctrl+Alt+I):

Panel jaringan

Mengaktifkan Brotli

Kompresi dinamis

Kompresi dinamis melibatkan kompresi aset dengan cepat saat aset tersebut yang diminta oleh browser.

Kelebihan

  • Membuat dan memperbarui versi aset terkompresi yang disimpan tidak perlu selesai.
  • Mengompresi dengan cepat bekerja sangat baik untuk laman web yang dibuat secara dinamis.

Kekurangan

  • Mengompresi file pada tingkat yang lebih tinggi untuk mencapai rasio kompresi yang lebih baik membutuhkan jadi lebih panjang. Hal ini dapat menyebabkan hit performa saat pengguna menunggu aset mengompresi sebelum dikirim oleh server.

Kompresi dinamis dengan Node/Express

File server.js bertanggung jawab untuk menyiapkan server Node yang menghosting aplikasi.

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

Yang dilakukan saat ini adalah mengimpor express dan menggunakan express.static middleware untuk memuat semua file HTML, JS, dan CSS statis di public/directory (dan file tersebut dibuat oleh webpack dengan setiap build).

Untuk memastikan semua aset dikompresi menggunakan brotli setiap kali permintaan, shrink-ray dapat digunakan. Mulailah dengan menambahkannya sebagai devDependency di package.json:

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

Lalu impor ke file server, server.js:

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

Dan tambahkan sebagai middleware sebelum express.static dipasang:

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

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

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

Sekarang muat ulang aplikasi, dan lihat ukuran paket di panel Jaringan:

Ukuran paket dengan kompresi Brotli dinamis

Sekarang Anda dapat melihat brotli diterapkan dari bz di header Content-Encoding. main.bundle.js dikurangi dari 225 KB menjadi 53,1 KB. Ukuran ini ~14% lebih kecil dibandingkan dengan gzip (61,6 KB).

Kompresi statis

Ide di balik kompresi statis adalah untuk membuat aset dikompresi dan disimpan di awal waktu tertentu.

Kelebihan

  • Latensi karena tingkat kompresi yang tinggi bukan lagi masalah penting. Tidak akan terjadi apa-apa harus dilakukan dengan cepat untuk mengompresi file karena sekarang file tersebut dapat diambil secara langsung.

Kekurangan

  • Aset harus dikompresi dengan setiap build. Waktu build dapat bertambah secara signifikan jika tingkat kompresi tinggi digunakan.

Kompresi statis dengan Node/Express dan webpack

Karena kompresi statis melibatkan kompresi file terlebih dahulu, webpack dapat diubah untuk mengompresi aset sebagai bagian dari langkah build. Tujuan brotli-webpack-plugin dapat digunakan untuk ini.

Mulailah dengan menambahkannya sebagai devDependency di package.json:

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

Seperti plugin webpack lainnya, impor di file konfigurasi, webpack.config.js:

var path = require("path");

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

Dan sertakan dalam array plugin:

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

Array plugin menggunakan argumen berikut:

  • asset: Nama aset target.
  • [file] diganti dengan nama file aset asli.
  • test: Semua aset yang cocok dengan RegExp ini (yaitu, aset JavaScript yang diakhiri dengan .js) diproses.

Misalnya, main.js akan diganti namanya menjadi main.js.br.

Saat aplikasi dimuat ulang dan dibuat ulang, versi terkompresi paket utama akan dibuat. Buka Glitch Console untuk melihat isi final Direktori public/ yang disalurkan oleh server Node.

  1. Klik tombol Alat.
  2. Klik tombol Konsol.
  3. Di konsol, jalankan perintah berikut untuk berubah menjadi public direktori tersebut dan melihat semua filenya:
cd public
ls -lh
Ukuran paket dengan kompresi Brotli statis

Versi paket terkompresi Brotli, main.bundle.js.br, kini disimpan dan ukurannya ~76% lebih kecil (225 KB vs. 53 KB) daripada main.bundle.js.

Selanjutnya, beri tahu server untuk mengirim file yang dikompresi brotli ini setiap kali versi JS asli yang diminta. Hal ini dapat dilakukan dengan menentukan rute di server.js sebelum file ditayangkan dengan 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 digunakan untuk memberi tahu server cara merespons permintaan GET untuk endpoint tertentu. Fungsi callback kemudian digunakan untuk menentukan cara menangani hal ini permintaan. Rutenya berfungsi seperti ini:

  • Menentukan '*.js' sebagai argumen pertama berarti cara ini berfungsi untuk setiap yang diaktifkan untuk mengambil file JS.
  • Dalam callback, .br dilampirkan ke URL permintaan dan Header respons Content-Encoding disetel ke br.
  • Header Content-Type ditetapkan ke application/javascript; charset=UTF-8 untuk menetapkan jenis MIME.
  • Terakhir, next() akan memastikan urutan berlanjut ke callback yang mungkin akan menjadi karakter berikutnya.

Karena beberapa browser mungkin tidak mendukung kompresi brotli, konfirmasi bahwa brotli adalah didukung sebelum mengembalikan file yang dikompresi brotli dengan memeriksa Header permintaan Accept-Encoding mencakup 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'));

Setelah aplikasi dimuat ulang, lihat panel Jaringan sekali lagi.

Ukuran paket 53,1 KB (dari 225 KB)

Berhasil! Anda telah menggunakan kompresi Brotli untuk mengompresi aset lebih lanjut!

Kesimpulan

Codelab ini menggambarkan bagaimana brotli dapat lebih mengurangi keseluruhan performa aplikasi Anda ukuran. Jika didukung, brotli adalah algoritma kompresi yang lebih kuat daripada gzip.