Codelab นี้เป็นส่วนขยายของ Minify และบีบอัด Network Payloads Codelab และจะถือว่าคุณคุ้นเคยกับแนวคิดพื้นฐานของการบีบอัด เมื่อเปรียบเทียบกับอัลกอริทึมการบีบอัดอื่นๆ เช่น gzip
แล้ว Codelab นี้จะสำรวจว่าการบีบอัด Brotli ช่วยลดอัตราส่วนการบีบอัดและขนาดโดยรวมของแอปได้อย่างไร
วัดระยะทาง
ก่อนเจาะลึกเพื่อเพิ่มการเพิ่มประสิทธิภาพ คุณควรวิเคราะห์สถานะปัจจุบันของแอปพลิเคชันก่อน
- คลิกรีมิกซ์เพื่อแก้ไขเพื่อทำให้โปรเจ็กต์แก้ไขได้
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
ใน Minify และบีบอัดข้อมูล Payload ของเครือข่ายก่อนหน้านี้ เราได้ลดขนาด main.js
จาก 225 KB เป็น 61.6 KB ใน Codelab นี้ คุณจะได้ดูวิธีที่การบีบอัดของ Brotli ช่วยลดขนาด Bundle นี้ได้มากขึ้น
การบีบอัด Brotli
Brotli เป็นอัลกอริทึมการบีบอัดแบบใหม่ซึ่งให้ผลของการบีบอัดข้อความได้ดีกว่า gzip
จากข้อมูลใน
CertSimple ประสิทธิภาพของ Brotli มีดังต่อไปนี้
- น้อยกว่า
gzip
14% สำหรับ JavaScript - น้อยกว่า
gzip
21% สำหรับ HTML - น้อยกว่า
gzip
17% สำหรับ CSS
เซิร์ฟเวอร์ของคุณต้องรองรับ HTTPS จึงจะใช้ Brotli ได้ เบราว์เซอร์เวอร์ชันล่าสุดส่วนใหญ่รองรับ Brotli เบราว์เซอร์ที่รองรับ Brotli จะรวม br
ในส่วนหัว Accept-Encoding
ดังนี้
Accept-Encoding: gzip, deflate, br
คุณระบุได้ว่าจะใช้อัลกอริทึมการบีบอัดใดผ่านช่อง Content-Encoding
ในแท็บเครือข่ายเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome (Command+Option+I
หรือ Ctrl+Alt+I
) โดยทำดังนี้
การเปิดใช้งาน Brotli
การบีบอัดแบบไดนามิก
การบีบอัดแบบไดนามิกเกี่ยวข้องกับการบีบอัดเนื้อหาในทันทีเมื่อได้รับการร้องขอจากเบราว์เซอร์
ข้อดี
- คุณไม่จำเป็นต้องสร้างและอัปเดตเนื้อหาเวอร์ชันบีบอัดที่บันทึกไว้
- การบีบอัดอย่างรวดเร็วเหมาะสำหรับหน้าเว็บที่สร้างขึ้นแบบไดนามิก
ข้อเสีย
- การบีบอัดไฟล์ในระดับที่สูงขึ้นเพื่อให้ได้อัตราส่วนการบีบอัดที่ดียิ่งขึ้นจะใช้เวลานานขึ้น ซึ่งอาจทำให้เกิด Hit ด้านประสิทธิภาพเนื่องจากผู้ใช้รอให้เนื้อหาบีบอัดก่อนที่เซิร์ฟเวอร์จะส่งเนื้อหา
การบีบอัดแบบไดนามิกด้วยโหนด/ด่วน
ไฟล์ server.js
มีหน้าที่ตั้งค่าเซิร์ฟเวอร์โหนดที่โฮสต์แอปพลิเคชัน
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);
});
ซึ่งในปัจจุบันคือการนำเข้า express
และใช้มิดเดิลแวร์ express.static
เพื่อโหลดไฟล์ HTML, JS และ CSS แบบคงที่ทั้งหมดใน public/directory
(และไฟล์เหล่านั้นสร้างขึ้นโดย Webpack ที่มีทุกบิลด์)
คุณใช้โมดูล shrink-ray
ได้ เพื่อให้แน่ใจว่ามีการบีบอัดเนื้อหาทั้งหมดโดยใช้ Brotli ทุกครั้งที่มีการขอ เริ่มต้นด้วยการเพิ่มเป็น devDependency
ใน package.json
:
"devDependencies": {
//...
"shrink-ray": "^0.1.3"
},
และนำเข้าไปยังไฟล์เซิร์ฟเวอร์ server.js
:
var express = require('express');
var shrinkRay = require('shrink-ray');
และเพิ่มเป็นมิดเดิลแวร์ก่อนต่อเชื่อม express.static
ดังนี้
//...
var app = express();
// compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
คราวนี้ให้โหลดแอปซ้ำและดูขนาดกลุ่มในแผงเครือข่าย ดังนี้
ตอนนี้คุณจะเห็นว่ามีการใช้ brotli
จาก bz
ในส่วนหัว Content-Encoding
main.bundle.js
ลดลงจาก 225 KB เหลือ 53.1 KB! ซึ่งเล็กกว่าประมาณ 14% เมื่อเทียบกับ gzip
(61.6 KB)
การบีบอัดแบบคงที่
แนวคิดที่อยู่เบื้องหลังการบีบอัดแบบคงที่คือให้มีการบีบอัดเนื้อหาและบันทึกไว้ล่วงหน้า
ข้อดี
- คุณจึงไม่ต้องกังวลเรื่องเวลาในการตอบสนองเนื่องจากระดับการบีบอัดในระดับสูงอีกต่อไป การบีบอัดไฟล์ไม่จําเป็นต้องเกิดขึ้นทันที เนื่องจากสามารถดึงข้อมูลได้โดยตรงแล้ว
ข้อเสีย
- ต้องบีบอัดเนื้อหาพร้อมกับบิลด์ทั้งหมด เวลาบิลด์อาจเพิ่มขึ้นอย่างมากหากใช้ระดับการบีบอัดสูง
การบีบอัดแบบคงที่ด้วยโหนด/Express และ Webpack
เนื่องจากการบีบอัดแบบคงที่เกี่ยวข้องกับการบีบอัดไฟล์ล่วงหน้า คุณจึงแก้ไขการตั้งค่า Webpack ให้บีบอัดเนื้อหาได้ในขั้นตอนการสร้าง คุณใช้ brotli-webpack-plugin
เพื่อดำเนินการนี้ได้
เริ่มต้นด้วยการเพิ่มเป็น devDependency
ใน package.json
:
"devDependencies": {
//...
"brotli-webpack-plugin": "^1.1.0"
},
เช่นเดียวกับปลั๊กอิน Webpack อื่นๆ ให้นำเข้าไปยังไฟล์การกำหนดค่า
webpack.config.js
:
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
และรวมไว้ในอาร์เรย์ปลั๊กอิน:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
อาร์เรย์ปลั๊กอินใช้อาร์กิวเมนต์ต่อไปนี้
asset
: ชื่อชิ้นงานเป้าหมาย[file]
จะแทนที่ด้วยชื่อไฟล์ชิ้นงานต้นฉบับtest
: ระบบจะประมวลผลชิ้นงานทั้งหมดที่ตรงกับนิพจน์ทั่วไปนี้ (ซึ่งก็คือเนื้อหา JavaScript ที่ลงท้ายด้วย.js
)
เช่น main.js
จะเปลี่ยนชื่อเป็น main.js.br
เมื่อแอปโหลดซ้ำและสร้างใหม่ ระบบจะสร้างเวอร์ชันบีบอัดของ Bundle หลักทันที เปิดคอนโซล Glitch เพื่อดูว่ามีอะไรอยู่ในไดเรกทอรี public/
สุดท้ายที่เซิร์ฟเวอร์โหนดแสดง
- คลิกปุ่มเครื่องมือ
- คลิกปุ่มคอนโซล
- ในคอนโซล ให้เรียกใช้คำสั่งต่อไปนี้เพื่อเปลี่ยนเป็นไดเรกทอรี
public
และดูไฟล์ทั้งหมดของไดเรกทอรี
cd public
ls -lh
ตอนนี้ระบบจะบันทึกแพ็กเกจ main.bundle.js.br
เวอร์ชันที่บีบอัดด้วย Brotli ไว้ที่นี่เช่นกัน โดยไฟล์ดังกล่าวมีขนาดเล็กกว่าประมาณ 76% (225 KB เทียบกับ 53 KB) เมื่อเทียบกับ main.bundle.js
ถัดไป ให้แจ้งเซิร์ฟเวอร์ให้ส่งไฟล์ที่บีบอัดด้วย Brotli เหล่านี้เมื่อใดก็ตามที่มีการขอเวอร์ชัน JS ต้นฉบับ ซึ่งทำได้โดยกำหนดเส้นทางใหม่ใน server.js
ก่อนที่ไฟล์จะแสดงด้วย 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
ใช้เพื่อบอกเซิร์ฟเวอร์เกี่ยวกับวิธีตอบกลับคำขอ GET
สำหรับปลายทางหนึ่งๆ จากนั้นระบบจะใช้ฟังก์ชันเรียกกลับเพื่อกำหนดวิธีจัดการคำขอนี้ เส้นทางมีการทำงานดังนี้
- การระบุ
'*.js'
เป็นอาร์กิวเมนต์แรกหมายความว่าวิธีนี้ได้ผลกับทุกปลายทางที่เริ่มทำงานเพื่อดึงข้อมูลไฟล์ JS - ภายในโค้ดเรียกกลับ ระบบจะแนบ
.br
กับ URL ของคำขอและตั้งค่าส่วนหัวการตอบกลับContent-Encoding
เป็นbr
- ส่วนหัว
Content-Type
ได้รับการตั้งค่าเป็นapplication/javascript; charset=UTF-8
เพื่อระบุประเภท MIME - สุดท้าย
next()
จะดูแลให้ลำดับยังคงเป็นโค้ดเรียกกลับที่อาจอยู่ในลำดับถัดไป
เนื่องจากบางเบราว์เซอร์อาจไม่รองรับการบีบอัด Brotli ให้ยืนยันว่าระบบรองรับ brotli ก่อนส่งคืนไฟล์ที่บีบอัดโดย brotli โดยการตรวจสอบส่วนหัวของคำขอ Accept-Encoding
ประกอบด้วย 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'));
เมื่อแอปโหลดซ้ำแล้ว ให้ดูที่แผงเครือข่ายอีกครั้ง
สำเร็จ! คุณได้ใช้การบีบอัด Brotli ในการบีบอัดเนื้อหาของคุณเพิ่มเติม!
บทสรุป
Codelab นี้แสดงให้เห็นว่า brotli
จะลดขนาดโดยรวมของแอปมากขึ้นได้อย่างไร หากรองรับ brotli
จะเป็นอัลกอริทึมการบีบอัดที่มีประสิทธิภาพมากกว่า gzip