Optimize web assets & webpack with Brotli

สำหรับนักพัฒนาเว็บแล้ว คงปฎิเสธได้ยากว่าในการพัฒนา Web Application โดยเฉพาะ Single Page Application นั้น คงจะหลีกเลี่ยงการทำ bundling ตัว Web Resource (CSS/JS/TS/JSX/TSX) ได้ลำบาก เพราะในการพัฒนาเว็บในปัจจุบันค่อนข้างซับซ้อน และประกอบด้วย library หลากหลาย และเมื่อมีการพัฒนาเว็บแอพพลิชันที่ยิ่งมีความซับซ้อนมาก ขนาดของ bundle ก็จะใหญ่ขึ้นเป็นเงาตามตัว วันนี้เราจะมาทำความรู้จักกับอีกหนึ่งวิธีในการเพิ่มประสิทธิภาพของ bundle และ webpack กันนะครับ

ฺBrotli เป็น Compression algorithm ที่ Google พัฒนาขึ้นและ announce ในปี 2015 ( Github ของ Brotli ) โดยได้ถูกบรรจุลงในมาตรฐาน IEFT หมายเลข RFC 7932 และในปัจจุบัน Brotli นั้นรองรับโดย Browser ต่างๆดังนี้

1_q3taJBqfze_Q8EitkVn8bQ

Browser compatibility for Brotli support
จะเห็นได้ว่าใน Modern Browser นั้นได้รองรับ Brotli แล้วเรียบร้อย แล้ว Brotli Format นั้นมีประสิทธิภาพอย่างไรในการใช้งานบ้าง ลองมาดูรายงานจาก Paper เกี่ยวกับ Brotli ของ Google กันนะครับ

1_UzkEUASmIY3yyJv0FT2d7A

Comparing Brotli compression with lzma, zopfli, bzip and deflate
จะเห็นได้ว่า Brotli นั้นสามารถทำได้ดีทั้งอัตราการบีบอัด(Compression Ratio) ซึ่งส่งผลถึงขนาดของ content ที่เรามักวางไว้ใน CDN ซึ่งหมายถึงเงินค่า bandwidth ทุกบาททุกสตางค์ที่เราจ่ายออกไปเมื่อมีคนเข้าใช้งานเว็บไซต์ของเรา และ Decompression speed ซึ่งหมายถึงความเร็วในการแสดงผลของ Web Assets ของเราบน Browser ของผู้ใช้งานนั่นเอง

ทีนี้ลองมาเปรียบเทียบขนาดที่เราจะเซฟได้จาก library ต่างๆดูนะครับจากภาพด้านล่าง จะเห็นได้ว่า Brotli นั้นจะช่วยลดขนาดของ JS library ต่างได้เป็นอย่างมาก โดยเฉพาะเมื่อเปรียบเทียบกับ gzip9 ซึ่งเป็น Algorithm ในการบีบอัดที่เราใช้กันอย่างแพร่หลายที่สุดในปัจจุบัน

1_mZ6Fb8lvGo14tnaSwL2I5A

comparing result from Brotli in popular JS library
สำหรับการใช้งานนั้น เราสามารถทำได้หลายวิธีด้วยกัน โดยวิธีที่ง่ายที่สุดนั้นก็คือ ผ่าน Nginx โดยให้ Nginx ซึ่งเราอาจใช้เป็น Origin Server ในการ serve static content ให้กับ CDN ได้เลยโดย ทำการติดตั้ง library brotli และ nginx module สำหรับ brotli

git clone https://github.com/bagder/libbrotli 
cd libbrotli 
./autogen.sh 
./configure make 
sudo make install
git clone https://github.com/google/ngx_brotli
cd /path/to/nginx/
./configure --add-module=/path/to/nginx/ngx_brotli ... configure ไปตามปกติ
make 
sudo make install 
sudo service nginx restart

และ เราก็สามารถติดตั้ง nginx brotli compression ให้กับเว็บของเราได้ใน nginx.conf ดังนี้

http {     
    ...     
    brotli on;     
    brotli_static on;     
    brotli_types *;     
    ... 
}

และเมื่อเราลองสังเกตุดูใน Web Developer Tools เราก็จะพบว่า bundle ของเราถูกส่งให้กับ Browser ด้วย Brotli compression เรียบร้อยแล้ว

1_JcaYsslPbblfeRxF8UiD7A

และสำหรับคนที่ไม่ได้ใช้ Web Server ที่รองรับ Brotli ที่ฝั่ง server ในระดับ module นั้น เราเองก็สามารถใช้ Brotli ได้ผ่านทาง Webpack plugin ที่ชื่อว่า brotli-webpack-plugin

โดยวิธีการใช้งานนั้นสามารถทำได้ดังนี้

#ติดตั้ง brotli webpack
yarn add -D brotli-webpack-plugin --save
#ติดตั้ง compression plugin เพื่อเปรียบเทียบเท่านั้น
yarn add -D compression-webpack-plugin --save

และจากนั้น เราต้องทำการติดตั้ง plugin ลงไปใน webpack config เพื่อให้ generate content ที่เราต้องการ (Brotli และ Gzip เพื่อเอามาเปรียบเทียบกันได้ดังนี้)

// โหลด compression-webpack-plugin เพื่อสร้าง output แบบ gzip 
var CompressionPlugin = require("compression-webpack-plugin");

// โหลด brotli-webpack-plugin เพื่อสร้าง output แบบ brotli
var BrotliPlugin = require('brotli-webpack-plugin');

#เพิ่ม Compression และ Brotli ลงไปใน webpack config plugin
module.exports = {
 plugins: [
  new CompressionPlugin({
     asset: "[path].gz[query]",
     algorithm: "gzip",
     test: /\.(js|html)$/,
     threshold: 10240,
     minRatio: 0.8
  }),
  new BrotliPlugin({
     asset: '[path].br[query]',
     test: /\.(js|css|html|svg)$/,
     threshold: 10240,
     minRatio: 0.8
  })
  ]
}

เมื่อทำการติดตั้ง webpack plugin เรียบร้อยแล้ว เราสามารถสร้าง bundle ได้ด้วย command line เหมือนเดิมด้วยคำสั่งต่อไปนี้ :

webpack --config webpack.config.js -p
หรือ
./node-modules/.bin/webpack --config webpack.config.js -p

เมื่อเราดู output ของ webpack ก็จะพบว่าสามารถสร้าง output ได้อย่างถูกต้อง และเห็นขนาดที่เราสามารถประหยัดได้จาก webpack bundle ด้วย brotli format มากถึง 8–10 % ทีเดียว

1_FoHH4DRrO-Y_kgjCLFdauw

สำหรับ Brotli นั้นถือว่าเป็นทางเลือกที่น่าสนใจทีเดียวสำหรับ Web Developer ที่สนใจเรื่องประสิทธิภาพ (และค่าใช้จ่าย) ของเว็บไซต์ มารีดให้ได้ถึง 100% กันครับ

References: