NGINX : Install Brotli Compression Menggunakan Dynamic Module

Posted by

Menggunakan Brotli compression di Nginx bisa mempercepat page load speed jika di bandingkan menggunakan Gzip compression asalkan di konfigurasi dengan benar.

Karena jika tidak di konfigurasi dengan optimal, alih – alih kita mendapatkan peningkatan performa page load time, yang ada page load time akan semakin lambat.

Efeknya, visitor pun tak akan betah mengunjungi web kita.

Brotli bekerja secara optimal hanya di level 4 jika dibandingkan dengan Gzip dalam hal kompresi on the fly.

Di atas level 4, maka kinerja Brotli berada di bawah dari performa kompresi dari Gzip.

Walaupun ukuran file yang di hasilkan melalui kompresi menggunakan Brotli lebih baik, namun waktu yang di perlukan untuk memprosesnya lebih lama.

Mengapa hal ini berpengaruh?

Karena browser baru akan menampilkan halaman web setelah mendapat response dari server.

Dan server baru akan memberikan respon setelah kompresi selesai di lakukan.

Oleh sebab itu, walaupun file yang akan di kirim ke browser berukuran lebih kecil, namun server tidak akan memberikan response sebelum proses kompresi selesai di lakukan.

Ada satu lagi pertimbangan untuk menggunakan Brotli yang mungkin anda sering dengar, yaitu jumlah browser yang sudah bisa memproses kompresi Brotli masih terbatas.

Apakah benar?

Jika di bandingkan dengan Gzip, memang jumlah browser yang sudah support Brotli tidak sebanyak browser yang sudah support Gzip.

Hal ini karena Brotli merupakan sistem kompresi yang masih tergolong “baru” jika di bandingkan dengan Gzip.

Namun jika kita lihat data dari CanIuse, jumlah browser yang sudah mensupport kompresi Brotli sebanyak ± 85.41%% dari browser yang di gunakan secara global dan ± 75.94% dari browser yang di gunakan di Indonesia.

brotli-supported-browser
Browser yang sudah support Brotli

Melihat dari gambar di atas, kenapa kita harus ragu menggunakan Brotli sebagai sistem kompresi kita?

Untuk mengimplementasikan Brotli di Nginx saat ini terbilang cukup mudah.

Karena Brotli sudah bisa di implementasikan di Nginx menggunakan dynamic module.

BROTLI INSTALLATION

Pada contoh kali ini saya menggunakan server dengan sistem operasi Ubuntu, yang mana bisa juga di terapkan di Debian.

Jika anda menggunakan sistem operasi linux yang lain, caranya overall hampir sama, hanya berbeda di sistem package manager ataupun editor.

1.  Download Nginx Source Code

Buat folder baru sebagai tempat untuk meng compile, disini saya akan menggunakan folder nginx-modules sebagai contoh di home folder.

Setelah itu kita buka folder tersebut.


mkdir -p nginx-modules 

cd nginx-modules
 

Selanjutnya anda perlu melakukan cek versi Nginx menggunakan perintah berikut.


nginx -v
 

Dan terlihat kalau Nginx yang saya gunakan adalah Nginx versi 1.15.2.

nginx -v
nginx version: nginx/1.15.2
 

Setelah kita mengetahui versi dari Nginx, selanjutnya kita download dan ekstrak Nginx sesuai dengan versi yang kita miliki.


wget http://nginx.org/download/nginx-1.15.2.tar.gz 
 

tar -xzvf nginx-1.15.2.tar.gz
 
Download dan Extract Nginx

Setelah proses ekstraksi selesai, kita cek apakah Nginx sudah terekstraksi atau belum.

ls
nginx-1.15.2  nginx-1.15.2.tar.gz

2.  Download Brotli Module

Langkah berikutnya kita akan mendownload Brotli Module untuk di gunakan di Nginx.

Untuk mendownload Brotli Module saya akan menggunakan git, sehingga pastikan git sudah terinstall di server anda.

Jika belum, anda bisa menginstallnya dengan cara berikut.


sudo apt-get install git-core
 

Selanjutnya untuk mendownload brotli kita gunakan perintah berikut ini.


git clone https://github.com/google/ngx_brotli.git
 
git clone https://github.com/google/ngx_brotli.git
Cloning into 'ngx_brotli'...
remote: Counting objects: 68, done.
remote: Total 68 (delta 0), reused 0 (delta 0), pack-reused 68
Unpacking objects: 100% (68/68), done.
ls
nginx-1.15.2  nginx-1.15.2.tar.gz  ngx_brotli
 

Selanjutnya kita pastikan kalau submodule Brotli sudah ada dan siap digunakan.


cd ngx_brotli 
 

git submodule update --init
 

3.  Compiling Brotli Dynamic Module

Selanjutnya, masuk ke folder Nginx yang telah anda download dan ekstrak pada langkah di atas.

Jika anda masih berada di folder ngx_brotli maka gunakan command berikut.


cd ../nginx-1.15.2
 

Jika anda berada di folder nginx_modules maka gunakan command berikut ini.


cd nginx-1.15.2
 

Pastikan nama folder sesuai dengan versi Nginx yang telah anda download.

Langkah selanjutnya kita akan melakukan konfigurasi Nginx untuk meracik brotli sebagai dynamic module


./configure --with-compat --add-dynamic-module=../ngx_brotli
 

Tunggu sebentar hingga Nginx selesai melakukan konfigurasi.

Tunggu konfigurasi Nginx selesai
Tunggu konfigurasi Nginx selesai

Setelah selesai, saatnya kita build dynamic module Brotli.


make modules
 

Setelah proses selesai, dynamic module brotli akan ada di folder ~/nginx-modules/nginx-1.15.2/objs . Kita cek terlebih dahulu apakah dynamic module brotli sudah ada atau belum.


ls objs
 
Folder objs
Folder objs

Dari gambar di atas terlihat kalau dynamic module Brotli sudah sukses kita build (warna hijau).

Sekarang kita copy dynamic module tersebut ke Nginx.


sudo cp objs/ngx_http_brotli_filter_module.so objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
 

Ada dua file dynamic module yang bisa anda gunakan. Anda bisa menggunakan salah satu, atau bahkan keduanya tergantung optimasi server anda.

  • ngx_http_brotli_filter_module.so untuk kompresi on-the-fly (dinamis)
  • ngx_http_brotli_static_module.so untuk kompresi precompress (statis)

Lalu kita cek lagi.


ls /etc/nginx/modules/
 
ls /etc/nginx/modules/
ngx_http_brotli_filter_module.so  ngx_http_brotli_static_module.so
 

4.  Load Module dan Konfigurasi Nginx

Sebelum melanjutkan, ada yang harus anda pahami dari Brotli Module sebelum anda melakukan compiling.

Sistem kompresi Brotli terbagi dua, yaitu sistem kompresi statis dan sistem kompresi dinamis.

Kompresi statis berupa sistem precompress, dimana Brotli akan memberikan hasil response langsung berupa file yang telah di kompres terlebih dahulu menggunakan Brotli, yaitu file dengan .br sebagai ekstensinya.

Sedangkan kompresi dinamis berupa sistem kompresi on the fly, dimana ketika terjadi request file, Brotli akan melakukan kompresi terlebih dahulu terhadap file yang di request, jika file tersebut belum terkompresi.

Ketika proses kompresi telah selesai, file tersebut baru di kirim sebagai response.

Dari alur tersebut kita bisa pahami, semakin lama proses kompresi berjalan, maka semakin lama juga visitor menunggu halaman web terkait muncul di browser.

Agar lebih mudah, sekarang kita akan bermain dalam folder Nginx yang ada di /etc/nginx.


cd /etc/nginx
 

Buka file konfigurasi Nginx.


sudo nano nginx.conf
 

Lalu tambahkan baris berikut pada top level context / main context, bukan pada blok http ataupun stream context.


# Untuk kompresi On-the-fly (dinamis) 
load_module modules/ngx_http_brotli_filter_module.so;
 

Fokus untuk kemudahan secara general, maka disini saya hanya menggunakan kompresi dinamis – Brotli on the fly.

Jika anda ingin menggunakan Brotli statis, silahkan baca di poin kami selanjutnya.

Kita lanjutkan kembali, selanjutnya kita cari blok http pada file nginx.conf yang kurang lebih terlihat seperti ini.


# ... code sebelumnya 
http { 
  # ... Baris Code 
} 
# ... code setelahnya
 

Pada blok http tersebut kita define konfigurasi untuk broti dengan code sebagai berikut.


# Konfigurasi Kompresi Dinamis (on-the-fly) 
http { 
  # ... code sebelumnya (jika ada) 
  brotli on; 
  brotli_comp_level 4; ## Level kompresi 0 - 11, angka 4 hanya contoh 
  brotli_types 
    text/plain 
    text/css 
    application/javascript 
    application/json 
    image/svg+xml 
    application/xml+rss; 
  # ... code setelahnya (jika ada) 
}
 

Melihat konfigurasi di atas, mungkin anda akan bertanya seperti ini.

Kok file image yang di compress cuma SVG?

Gak bener nih, Masa JPG dan PNG tidak di ajak!

Tenang sob, kenapa saya tidak memasukkan file statis seperti JPG, PNG, MP4, dan sejenisnya?

Karena file tersebut merupakan file binary. Dan tools spesifik yang kita gunakan untuk mengkompresi file binary tersebut lebih baik dari kompresi menggunakan Gzip maupun Brotli.

Jadi tidak ada gunanya kita gunakan Gzip maupun Brotli untuk mengkompresi file binary.

Dalam beberapa kasus, kompresi file binary menggunakan Gzip dan Brotli malah akan menghasilkan output dengan ukuran yang lebih besar.

Tools seperti Photoshop, TinyPNG, dan sejenisnya sudah memberikan kompresi yang optimal, so kenapa kita harus melakukan kompresi lagi?

Sampai disini sekarang kita akan cek apakah kompresi Brotli sudah di gunakan atau belum.

Kita gunakan command berikut untuk mengecek header.


curl -I -L -H 'Accept-Encoding: gzip,br' omgoblog.com
 
check-brotli-header

Dari gambar di atas terlihat pada baris paling bawah dimana,

content-encoding: br

Yang menunjukkan kalau server mengirimkan brotli sebagai response.

Jika anda ingin memaksimalkan kemampuan brotli, lanjutkan membaca.

BROTLI STATIS DAN DINAMIS (Opsional)

Untuk mendapatkan hasil yang maksimal, maka kita akan melakukan kombinasi antara Brotli Statis dan Brotli Dinamis.

Berbagai cara sudah saya lakukan, mulai dari satu artikel ke artikel lainnya, dari satu panduan ke panduan lainnya, hingga tak terhitung berapa cara yang sudah saya coba.

Sudah berkali – kali juga saya harus mengkonfigurasi ulang server karena crash, error, bug, dan lain sebagainya.

Namun semangat tak boleh padam, asa tak boleh sirna, sampai akhirnya saya menemukan cara ini.

Dengan kemampuan server yang pas – pasan, maka kita harus terus menerus melakukan optimasi server.

Untuk sistem kompresi Brotli memang lebih baik dibandingkan dengan sistem kompresi Gzip. Namun untuk melakukan kompresi lebih, Brotli membutuhkan resource server yang lebih juga dibandingkan Gzip.

Seperti yang telah di bahas diatas, untuk mendapatkan resource server dalam melakukan kompresi on-the-fly seperti layaknya Gzip, kompresi Brotli paling optimal di level 4.

Supaya kita bisa mendapatkan hasil dan kinerja server yang optimal, maka kita perlu untuk membagi kinerja sistem kompresi Brotli.

Konsepnya, kita akan menggunakan sistem kompresi precompress untuk meng-handle file statis seperti image, CSS, Javascript, SVG, dan lain sebagainya.

Lalu untuk file dinamis seperti PHP, Python, dan lain sebagainya, sistem kompresi akan di lakukan on-the-fly.

Sehingga untuk mendapatkan kecepatan yang optimal, kita akan menggunakan kompresi on-the-fly di level 4 dan kompresi precompress di level 11 ( maksimum ).

Panjang amat basa basinya, buruan dong!!

Sabar kawan, karena kalau anda tau alurnya, maka anda bisa dengan mudah untuk mengoptimasi Brotli agar sesuai dengan kemampuan server anda.

Oke deh, sekarang saatnya kita masuk ke prakteknya.

1.  Brotli Precompress

Untuk melakukan kompresi dengan brotli maka kita install software Brotli terlebih dahulu dengan cara berikut.


sudo apt-get install brotli
 

Sampai di sini kita sudah bisa melakukan kompresi file dengan cara berikut.


brotli -Z omgoblog.js 
brotli -Z omgoblog.css
 

Dimana -Z menginstruksikan untuk melakukan kompresi maksimum (Level 11), sedangkan omgoblog.js dan omgoblog.css merupakan file statis yang akan di kompresi.

2.  Brotli Bash Script

Terlihat simple, tapi bayangkan jika anda memiliki ribuan gambar, puluhan Javascript dan CSS, dan puluhan file statis lainnya, maka akan cukup merepotkan kita.

Maka dari itu kita akan membuat file Bash Script yang akan melakukan kompresi Brotli untuk kita.

a.  Membuat File Bash Script

Pada contoh kali ini saya membuat Bash Script di folder home.

Kita akan membuat file baru menggunakan Nano dengan nama brotli-compression.bash seperti berikut.


sudo nano brotli-compression.bash
 

Setelah itu masukkan kode berikut.


#!/usr/bin/env bash 
for FILE in $(find /var/public/omgoblog.com -type f -name '.css' -o -name '.js' -o -name '.svg' -o -name '.json'); 
do 
  echo -n "Compressing ${FILE}..." 
  brotli -fZ ${FILE}; 
  echo "done." 
done
 

Dimana /var/public/omgoblog.com merupakan direktori root web yang saya gunakan.

Anda bisa menggunakan direktori root web atau langsung pointing ke folder file statis yang ingin anda kompres.

Ketika dijalankan, script di atas akan mencari semua file dengan ekstensi CSS, JS, SVG, dan JSON di dalam folder /var/public/omgoblog.com, baik file statis yang ada di folder tersebut maupun di child folder yang ada di dalamnya, dan melakukan kompresi menggunakan brotli terhadap file tersebut.

b.  Eksekusi Bash Script

Untuk mengeksekusi script di atas, anda harus masuk ke dalam folder tempat file tersebut di simpan dan jalankan dengan perintah berikut.


sudo sh brotli-compression.bash
 

Proses kompresi akan berjalan dan waktu yang di butuhkan tergantung seberapa banyak file yang anda miliki.

Silahkan tunggu sambil menikmati secangkir kopi hangat.

Compressing /var/public/omgoblog.com/assets/js/jquery.js...done. <
Compressing /var/public/omgoblog.com/assets/js/navigation.js...done. 
Compressing /var/public/omgoblog.com/assets/css/media-rtl.min.css...done. 
Compressing /var/public/omgoblog.com/assets/css/main.css...done. 
Compressing /var/public/omgoblog.com/assets/svg/logo.svg...done. 
Compressing /var/public/omgoblog.com/assets/svg/social-icon.svg...done.
 

Jika proses telah selesai, silahkan cek file statis anda, maka akan ada file sejenis dengan ekstensi .br yang menandakan bahwa file tersebut telah di kompresi menggunakan Brotli.

Oh ya, jika anda ingin agar script di atas bisa anda jalankan dari folder mana saja (Global), maka anda perlu mengedit Path di file .bashrc yang ada di folder home.

c.  Global Bash Script

Supaya file .bashrcbisa di akses secara global, masuk ke folder home anda, lalu buka file .bashrc


sudo nano .bashrc
 

Lalu masukkan command berikut di bagian paling bawah file.


# Kalau script anda ada di home 
export PATH="~:$PATH" 

# Kalau script anda ada di folder i.e. ~/omgoblog-bash 
export PATH="~/omgoblog-bash:$PATH"
 

Setelah itu lakukan reboot system.

Yup, REBOOT SYSTEM yah sob, bukan reboot service.


sudo reboot
 

Jika sudah, sekarang anda bisa mengakses script anda dari mana saja cukup dengan mengetikkan


sudo brotli-compression.bash
 

Dan proses kompresi pun di lakukan.

3.  Konfigurasi File nginx.conf

Setelah file statis kita kompresi, sekarang saatnya kita lakukan konfigurasi file nginx.conf di folder Nginx anda.

Wait, wait, kan yang di bahas baru Brotli Precompress, terus nasib Brotli yang on-the-fly gimana?

Konfigurasi Brotli on-the-fly akan kita lakukan di file nginx.conf karena tidak seperti Brotli precompress yang memerlukan manual compression terlebih dahulu.

Kenapa?

Karena sistem Brotli on the fly baru akan melakukan kompresi jika ada request yang terjadi.

Sekarang kita buka file nginx.conf yang ada di dalam folder Nginx, yang secara general dan default ada di /etc/nginx.


sudo nano /etc/nginx/nginx.conf
 

Setelah file nginx.conf terbuka, load Brotli static dan dynamic module dengan menginput code berikut ini pada top level context / main context, bukan pada block context seperti http block atau server block misalnya.


# Load static and dynamic module 
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
 

Selanjutnya masukkan code berikut di blok http.


http {
  # ... code sebelumnya (jika ada)
  brotli on;
  brotli_comp_level 4; ## Level Optimal Brotli on the fly
  brotli_types 
    text/plain 
    text/css 
    application/javascript 
    application/json 
    image/svg+xml 
    application/xml+rss; 
    brotli_static on; 
  # ... code setelahnya (jika ada) 
}
 

Setelah itu kita save dengan menekan ctrl+x → Y → Enter lalu restart Nginx anda.


sudo service nginx restart
 

CONCLUSSION

Sampai pada tahap ini anda sudah dapat menikmati kompresi dengan Brotli, dan silahkan anda cek apakah ada peningkatan performa atau tidak jika dibandingkan dengan menggunakan Gzip.

Lalu gimana nasib user yang browsernya belum support Brotli?

Karena browser yang support Brotli baru sebanyak ± 70%++ , maka kita perlu mempertimbangkan masalah kompatibilitas.

Apakah kita memang harus mengorbankan ± 20% user tersebut atau tidak.

Luckily, ternyata Brotli dan Gzip bersahabat sob!!

Jadi jangan hapus konfigurasi Gzip anda di Nginx, maka Brotli dan Gzip akan saling support each other.

Ketika ada request dengan header seperti ini,


'Accept-Encoding: gzip, deflate, br' omgoblog.com
 

maka Brotli yang akan meng-handle request tersebut.

Sedangkan ketika ada request dengan header seperti ini,


'Accept-Encoding: gzip, deflate' omgoblog.com
 

maka Gzip yang akan meng-handle.

Tidak percaya?

Saya mencoba melakukan 2 request, dimana yang satu menggunakan header Accept-Encoding: gzip, deflate, br dan satu lagi hanya menggunakan header Accept-Encoding: gzip, deflate sebagai berikut.

curl -I -L -H 'Accept-Encoding: gzip, deflate, br' omgoblog.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.15.3
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://omgoblog.com/

HTTP/2 200 
server: nginx
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
link: <https://omgoblog.com/wp-json/>; rel="https://api.w.org/"
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
referrer-policy: strict-origin-when-cross-origin
fastcgi-cache: MISS
strict-transport-security: max-age=31536000;
x-page-speed: Powered By Omgoblog
cache-control: max-age=0, no-cache
content-encoding: br

curl -I -L -H 'Accept-Encoding: gzip, deflate' omgoblog.com
HTTP/1.1 301 Moved Permanently
Server: nginx/1.15.3
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://omgoblog.com/

HTTP/2 200 
server: nginx
content-type: text/html; charset=UTF-8
vary: Accept-Encoding
link: <https://omgoblog.com/wp-json/>; rel="https://api.w.org/"
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
referrer-policy: strict-origin-when-cross-origin
fastcgi-cache: MISS
strict-transport-security: max-age=31536000;
x-page-speed: Powered By Omgoblog
cache-control: max-age=0, no-cache
content-encoding: gzip

 

Pada request pertama, server omgoblog.com memberi respon content-encoding: br  yang bisa anda lihat pada baris 22.

Hal tersebut menunjukkan kalau Brotli yang menghandle request tersebut.

Sedangkan pada request kedua, anggaplah request terjadi berasal dari browser yang tidak mendukung Brotli.

Dan Server omgoblog.com memberi respon content-encoding: gzip  yang bisa anda lihat pada baris 45 yang menunjukkan Gzip yang menghandle request tersebut. Cool right?

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *