Codelab นี้เป็นส่วนขยายของ Codelab การลดขนาดและบีบอัดเพย์โหลดเครือข่าย และถือว่าคุณคุ้นเคยกับแนวคิดพื้นฐานของการบีบอัด เมื่อเทียบกับอัลกอริทึมการบีบอัดอื่นๆ เช่น gzip Codelab นี้จะสำรวจว่าการบีบอัด Brotli (br) สามารถลดอัตราส่วนการบีบอัดและขนาดโดยรวมของแอปได้อย่างไร

วัดผล
ก่อนที่จะเริ่มเพิ่มการเพิ่มประสิทธิภาพ คุณควรวิเคราะห์สถานะปัจจุบันของแอปพลิเคชันก่อนเสมอ
- คลิกรีมิกซ์เพื่อแก้ไขเพื่อให้โปรเจ็กต์แก้ไขได้
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกดเต็มหน้าจอ
ในCodelab การลดขนาดและบีบอัดเพย์โหลดของเครือข่ายก่อนหน้านี้ เราได้ลดขนาดของ main.js จาก 225 KB เหลือ 61.6 KB ใน Codelab นี้ คุณจะได้สำรวจว่าการบีบอัด Brotli ช่วยลดขนาดแพ็กเกจนี้ได้มากยิ่งขึ้นได้อย่างไร
การบีบอัด Brotli
Brotli เป็นอัลกอริทึมการบีบอัดที่ใหม่กว่าซึ่งให้ผลลัพธ์การบีบอัดข้อความที่ดีกว่า gzip CertSimple ระบุว่าประสิทธิภาพของ Brotli มีดังนี้
- เล็กกว่า
gzip14% สำหรับ JavaScript - เล็กกว่า
gzipสำหรับ HTML 21% - เล็กกว่า
gzipสำหรับ CSS 17%
หากต้องการใช้ Brotli เซิร์ฟเวอร์ของคุณต้องรองรับ HTTPS Brotli รองรับในเบราว์เซอร์ที่ทันสมัยทั้งหมด เบราว์เซอร์ที่รองรับ Brotli จะมี br ในส่วนหัว Accept-Encoding:
Accept-Encoding: gzip, deflate, br
คุณสามารถระบุอัลกอริทึมการบีบอัดที่ใช้ได้โดยใช้ช่อง Content-Encoding ในแท็บเครือข่ายของเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome (Command+Option+I หรือ Ctrl+Alt+I)
วิธีเปิดใช้ Brotli
วิธีตั้งค่าเว็บเซิร์ฟเวอร์เพื่อส่งทรัพยากรที่เข้ารหัส Brotli จะขึ้นอยู่กับวิธีที่คุณวางแผนจะเข้ารหัส ตัวเลือกของคุณคือการบีบอัดทรัพยากรแบบไดนามิกด้วย Brotli ณ เวลาที่มีคำขอ (ไดนามิก) หรือเข้ารหัสทรัพยากรล่วงหน้าเพื่อให้ทรัพยากรได้รับการบีบอัดแล้วเมื่อผู้ใช้ส่งคำขอ (คงที่)
การบีบอัดแบบไดนามิก
การบีบอัดแบบไดนามิกเกี่ยวข้องกับการบีบอัดชิ้นงานแบบเรียลไทม์เมื่อเบราว์เซอร์ส่งคำขอ
ข้อดี
- คุณไม่จำเป็นต้องสร้างและอัปเดตชิ้นงานเวอร์ชันบีบอัดที่บันทึกไว้
- การบีบอัดแบบทันทีเหมาะอย่างยิ่งสำหรับหน้าเว็บที่สร้างขึ้นแบบไดนามิก
ข้อเสีย
- การบีบอัดไฟล์ในระดับที่สูงขึ้นเพื่อให้ได้อัตราส่วนการบีบอัดที่ดีขึ้นจะใช้เวลานานขึ้น ซึ่งอาจส่งผลต่อประสิทธิภาพเนื่องจากผู้ใช้ต้องรอให้เนื้อหาบีบอัดก่อนที่เซิร์ฟเวอร์จะส่ง
การบีบอัดแบบไดนามิกด้วย Node และ Express
ไฟล์ server.js มีหน้าที่ตั้งค่าเซิร์ฟเวอร์ Node ที่โฮสต์แอปพลิเคชัน
const express = require('express');
const app = express();
app.use(express.static('public'));
const 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 ดังนี้
const express = require('express');
const shrinkRay = require('shrink-ray');
และเพิ่มเป็นมิดเดิลแวร์ก่อนที่จะต่อเชื่อม express.static ดังนี้
// ...
const 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)
การบีบอัดแบบคงที่
แนวคิดเบื้องหลังการบีบอัดแบบคงที่คือการบีบอัดและบันทึกเนื้อหาไว้ล่วงหน้า
ข้อดี
- เวลาในการตอบสนองที่เกิดจากระดับการบีบอัดสูงจะไม่เป็นปัญหาอีกต่อไป ไม่จำเป็นต้องบีบอัดไฟล์แบบเรียลไทม์เนื่องจากสามารถดึงข้อมูลได้โดยตรงแล้ว
ข้อเสีย
- ชิ้นงานต้องได้รับการบีบอัดทุกครั้งที่บิลด์ เวลาในการสร้างอาจเพิ่มขึ้นอย่างมากหากใช้การบีบอัดระดับสูง
การบีบอัดแบบคงที่ด้วย Node และ 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');
และรวมไว้ในอาร์เรย์ plugins ดังนี้
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
อาร์เรย์ปลั๊กอินใช้อาร์กิวเมนต์ต่อไปนี้
asset: ชื่อชิ้นงานเป้าหมาย[file]จะแทนที่ด้วยชื่อไฟล์ชิ้นงานเดิมtest: ระบบจะประมวลผลชิ้นงานทั้งหมดที่ตรงกับ RegExp นี้ (ซึ่งก็คือชิ้นงาน JavaScript ที่ลงท้ายด้วย.js)
เช่น main.js จะเปลี่ยนชื่อเป็น main.js.br
เมื่อแอปโหลดซ้ำและสร้างใหม่ ระบบจะสร้างแพ็กเกจหลักเวอร์ชันที่บีบอัดแล้ว เปิด Glitch Console เพื่อดูสิ่งที่อยู่ภายในไดเรกทอรี public/ สุดท้ายที่เซิร์ฟเวอร์ Node แสดง
- คลิกปุ่มเครื่องมือ
- คลิกปุ่มคอนโซล
- ในคอนโซล ให้เรียกใช้คำสั่งต่อไปนี้เพื่อเปลี่ยนเป็นไดเรกทอรี
publicและดูไฟล์ทั้งหมด
cd public
ls -lh
ตอนนี้ระบบได้บันทึกแพ็กเกจเวอร์ชันที่บีบอัดด้วย Brotli (main.bundle.js.br) ไว้ที่นี่ด้วย และมีขนาดเล็กลงประมาณ 76% (225 KB เทียบกับ 53 KB) เมื่อเทียบกับ main.bundle.js
จากนั้นบอกให้เซิร์ฟเวอร์ส่งไฟล์ที่บีบอัดด้วย Brotli เหล่านี้เมื่อใดก็ตามที่มีการขอเวอร์ชัน JS ดั้งเดิม ซึ่งทำได้โดยกำหนดเส้นทางใหม่ใน server.js ก่อนที่จะแสดงไฟล์ด้วย express.static
const express = require('express');
const 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 สำหรับปลายทางที่เฉพาะเจาะจง จากนั้นระบบจะใช้ฟังก์ชัน Callback เพื่อกำหนดวิธีจัดการคำขอนี้ เส้นทางจะทำงานดังนี้
- การระบุ
'*.js'เป็นอาร์กิวเมนต์แรกหมายความว่าวิธีนี้ใช้ได้กับทุกปลายทางที่เริ่มทำงานเพื่อดึงข้อมูลไฟล์ JS - ภายใน Callback ระบบจะแนบ
.brไว้กับ URL ของคำขอ และตั้งค่าส่วนหัวการตอบกลับContent-Encodingเป็นbr - ส่วนหัว
Content-Typeตั้งค่าเป็นapplication/javascript; charset=UTF-8เพื่อระบุประเภท MIME - สุดท้าย
next()จะช่วยให้มั่นใจว่าลำดับจะดำเนินต่อไปยัง Callback ที่อาจเป็นลำดับถัดไป
เนื่องจากเบราว์เซอร์บางรายการอาจไม่รองรับการบีบอัด brotli โปรดยืนยันว่าระบบรองรับ brotli ก่อนที่จะแสดงผลไฟล์ที่บีบอัดด้วย brotli โดยตรวจสอบว่าส่วนหัวของคำขอ Accept-Encoding มี br:
const express = require('express');
const 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