Codelab นี้เป็นส่วนขยายของ ลดขนาดและบีบอัดเพย์โหลด Codelab และจะถือว่าคุณคุ้นเคยกับแนวคิดพื้นฐานของการบีบอัด Codelab นี้จะสำรวจว่าการบีบอัด Brotli ช่วยลดอัตราส่วนการบีบอัดและขนาดโดยรวมของแอปได้อย่างไรเมื่อเทียบกับอัลกอริทึมการบีบอัดอื่นๆ อย่าง gzip
วัดระยะทาง
ก่อนจะเจาะลึกเพื่อเพิ่มการเพิ่มประสิทธิภาพ คุณควรวิเคราะห์สถานะปัจจุบันของแอปพลิเคชันก่อน
- คลิกรีมิกซ์เพื่อแก้ไขเพื่อทำให้โปรเจ็กต์แก้ไขได้
- หากต้องการดูตัวอย่างเว็บไซต์ ให้กดดูแอป แล้วกด เต็มหน้าจอ
ใน ลดขนาดและบีบอัดเพย์โหลด Codelab ก่อนหน้านี้ เราได้ลดขนาด main.js
จาก 225 KB เป็น 61.6 KB ใน Codelab นี้ คุณจะได้สำรวจว่าการบีบอัด Brotli สามารถลดขนาด Bundle นี้ลงไปอีกได้อย่างไร
การบีบอัด Brotli
Brotli เป็นอัลกอริทึมการบีบอัดที่ใหม่กว่าซึ่งให้ผลลัพธ์การบีบอัดข้อความที่ดีกว่าการใช้ gzip
จากข้อมูลของ CertSimple ประสิทธิภาพของ Brotli มีดังต่อไปนี้
- น้อยกว่า
gzip
14% สำหรับ JavaScript - มีขนาดเล็กกว่า
gzip
21% สำหรับ HTML - น้อยกว่า
gzip
17% สำหรับ CSS
หากต้องการใช้ Brotli เซิร์ฟเวอร์ของคุณต้องรองรับ HTTPS Brotli ได้รับการสนับสนุนในเบราว์เซอร์ส่วนใหญ่ในเวอร์ชันล่าสุด เบราว์เซอร์ที่รองรับ Brotli จะรวม br
ไว้ในส่วนหัว Accept-Encoding
ดังนี้
Accept-Encoding: gzip, deflate, br
คุณระบุได้ว่าจะใช้อัลกอริทึมการบีบอัดใดผ่านช่อง Content-Encoding
ในแท็บเครือข่ายเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome (Command+Option+I
หรือ Ctrl+Alt+I
) โดยทำดังนี้
การเปิดใช้ Brotli
การบีบอัดแบบไดนามิก
การบีบอัดแบบไดนามิกเกี่ยวข้องกับการบีบอัดเนื้อหาแบบเรียลไทม์ตามที่เบราว์เซอร์ขอ
ข้อดี
- คุณไม่จำเป็นต้องสร้างและอัปเดตเนื้อหาเวอร์ชันบีบอัดที่บันทึกไว้
- การบีบอัดทันทีทำงานได้ดีเป็นพิเศษสำหรับหน้าเว็บที่สร้างขึ้นแบบไดนามิก
ข้อเสีย
- การบีบอัดไฟล์ในระดับที่สูงขึ้นเพื่อให้ได้อัตราส่วนการบีบอัดที่ดีขึ้นจะใช้เวลานานขึ้น ซึ่งอาจทำให้เกิด Conversion ด้านประสิทธิภาพเนื่องจากผู้ใช้รอให้เนื้อหาบีบอัดก่อนที่จะส่งโดยเซิร์ฟเวอร์
การบีบอัดแบบไดนามิกด้วยโหนด/ด่วน
ไฟล์ 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)
การบีบอัดแบบคงที่
แนวคิดที่อยู่เบื้องหลังการบีบอัดแบบคงที่คือการบีบอัดเนื้อหาและบันทึกไว้ล่วงหน้า
ข้อดี
- ไม่ต้องกังวลเรื่องเวลาในการตอบสนองเนื่องจากระดับการบีบอัดที่สูงอีกต่อไป การบีบอัดไฟล์ไม่จำเป็นต้องทำได้ทันที เพราะปัจจุบันสามารถดึงข้อมูลโดยตรงได้แล้ว
ข้อเสีย
- ต้องบีบอัดเนื้อหาในทุกบิลด์ เวลาในการสร้างอาจเพิ่มขึ้นอย่างมากหากใช้ระดับการบีบอัดที่สูง
การบีบอัดแบบคงที่ด้วย 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');
และรวมไว้ในอาร์เรย์ปลั๊กอิน
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
สำหรับปลายทางที่เฉพาะเจาะจง จากนั้นจะมีการใช้ฟังก์ชัน Callback เพื่อกำหนดวิธีจัดการคำขอนี้ โดยเส้นทางจะทำงานดังนี้
- การระบุ
'*.js'
เป็นอาร์กิวเมนต์แรกหมายความว่าระบบได้ผลกับปลายทางทุกปลายทางที่เริ่มทำงานเพื่อดึงไฟล์ JS - ภายใน Callback จะมีการแนบ
.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