Codelab ini adalah ekstensi dari codelab Memperkecil dan mengompresi payload jaringan
dan mengasumsikan bahwa Anda memahami konsep dasar-dasar kompresi. Dibandingkan dengan algoritma kompresi lainnya seperti gzip
, codelab ini membahas bagaimana kompresi Brotli dapat lebih mengurangi rasio kompresi dan ukuran aplikasi Anda secara keseluruhan.
Ukur
Sebelum menambahkan pengoptimalan, sebaiknya analisis status aplikasi saat ini terlebih dahulu.
- Klik Remix untuk Mengedit agar project dapat diedit.
- Untuk melihat pratinjau situs, tekan Lihat Aplikasi. Lalu tekan Layar Penuh .
Dalam codelab Minifikasi dan kompresi payload jaringan sebelumnya, kami mengurangi ukuran main.js
dari 225 KB menjadi 61,6 KB. Dalam codelab ini, Anda akan mempelajari cara kompresi Brotli dapat mengurangi ukuran paket ini lebih jauh.
Kompresi Brotli
Brotli
adalah algoritma kompresi lebih baru yang dapat memberikan hasil kompresi teks
lebih baik daripada gzip
. Menurut CertSimple, performa Brotli adalah:
- 14% lebih kecil dari
gzip
untuk JavaScript - 21% lebih kecil daripada
gzip
untuk HTML - 17% lebih kecil dari
gzip
untuk CSS
Untuk menggunakan Brotli, server Anda harus mendukung HTTPS. Brotli didukung di
sebagian besar browser versi terbaru. Browser
yang mendukung Brotli akan menyertakan br
dalam header Accept-Encoding
:
Accept-Encoding: gzip, deflate, br
Anda dapat menentukan algoritma kompresi mana yang digunakan melalui kolom Content-Encoding
di tab Jaringan Chrome Developer Tools (Command+Option+I
atau
Ctrl+Alt+I
):
Mengaktifkan Brotli
Kompresi dinamis
Kompresi dinamis melibatkan kompresi aset dengan cepat saat diminta oleh browser.
Kelebihan
- Pembuatan dan update aset versi terkompresi yang disimpan tidak perlu dilakukan.
- Mengompresi dengan cepat sangat efektif untuk halaman web yang dibuat secara dinamis.
Kekurangan
- Mengompresi file di tingkat yang lebih tinggi untuk mencapai rasio kompresi yang lebih baik memerlukan waktu yang lebih lama. Hal ini dapat menyebabkan hit performa saat pengguna menunggu aset untuk dikompresi 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 saat ini dilakukan adalah mengimpor express
dan menggunakan middleware express.static
untuk memuat semua file HTML, JS, serta CSS statis di
public/directory
(dan file tersebut dibuat oleh webpack dengan setiap build).
Untuk memastikan semua aset dikompresi menggunakan brotli setiap kali
diminta, modul shrink-ray
dapat digunakan. Mulai dengan menambahkannya sebagai devDependency
di package.json
:
"devDependencies": {
//...
"shrink-ray": "^0.1.3"
},
Dan impor ke file server, server.js
:
var express = require('express');
var shrinkRay = require('shrink-ray');
Kemudian, 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:
Anda sekarang dapat melihat brotli
diterapkan dari bz
di header Content-Encoding
.
main.bundle.js
telah dikurangi dari 225 KB menjadi 53,1 KB. Ukuran ini ~14% lebih kecil
dibandingkan gzip
(61,6 KB).
Kompresi statis
Ide di balik kompresi statis adalah membuat aset dikompresi dan disimpan terlebih dahulu.
Kelebihan
- Latensi karena tingkat kompresi yang tinggi tidak lagi menjadi masalah. Tidak perlu terjadi saat proses mengompresi file karena file kini dapat diambil secara langsung.
Kekurangan
- Aset perlu dikompresi dengan setiap build. Waktu build dapat meningkat secara signifikan jika tingkat kompresi tinggi digunakan.
Kompresi statis dengan Node/Express dan webpack
Karena kompresi statis melibatkan kompresi file terlebih dahulu, setelan
webpack dapat dimodifikasi untuk mengompresi aset sebagai bagian dari langkah build. brotli-webpack-plugin
dapat digunakan untuk hal ini.
Mulai dengan menambahkannya sebagai devDependency
di package.json
:
"devDependencies": {
//...
"brotli-webpack-plugin": "^1.1.0"
},
Seperti plugin webpack lainnya, impor plugin tersebut dalam 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 di-build ulang, versi terkompresi dari paket utama
kini akan dibuat. Buka Glitch Console untuk melihat isi direktori public/
akhir yang disalurkan oleh server Node.
- Klik tombol Tools.
- Klik tombol Konsol.
- Di konsol, jalankan perintah berikut untuk berubah menjadi direktori
public
dan lihat semua filenya:
cd public
ls -lh
Versi paket terkompresi brotli, main.bundle.js.br
, kini juga disimpan
di sini dan berukuran ~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 aslinya diminta. Hal ini dapat dilakukan dengan menentukan rute
baru 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
permintaan ini. Rute bekerja seperti ini:
- Menentukan
'*.js'
sebagai argumen pertama berarti argumen ini berfungsi untuk setiap endpoint yang diaktifkan untuk mengambil file JS. - Dalam callback,
.br
dilampirkan ke URL permintaan dan header responsContent-Encoding
ditetapkan kebr
. - Header
Content-Type
ditetapkan keapplication/javascript; charset=UTF-8
untuk menentukan jenis MIME. - Terakhir,
next()
memastikan bahwa urutan tersebut berlanjut ke callback yang mungkin berikutnya.
Karena beberapa browser mungkin tidak mendukung kompresi brotli, konfirmasi bahwa brotli
didukung sebelum menampilkan file yang dikompresi brotli dengan memeriksa
header permintaan Accept-Encoding
menyertakan 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.
Berhasil! Anda telah menggunakan kompresi Brotli untuk mengompresi aset lebih lanjut.
Kesimpulan
Codelab ini mengilustrasikan cara brotli
dapat makin mengurangi ukuran keseluruhan
aplikasi Anda. Jika didukung, brotli
adalah algoritme kompresi yang lebih canggih daripada
gzip
.