Lớp học lập trình này là phần mở rộng của Lớp học lập trình về việc rút gọn và nén tải trọng mạng và giả định rằng bạn đã nắm được các khái niệm cơ bản về việc nén. So với các thuật toán nén khác như gzip
, lớp học lập trình này khám phá cách nén Brotli (br
) có thể giảm tỷ lệ nén và kích thước tổng thể của ứng dụng hơn nữa.
Đo
Trước khi bắt đầu thêm các tính năng tối ưu hoá, bạn nên phân tích trạng thái hiện tại của ứng dụng.
- Nhấp vào Remix to Edit (Trộn lại để chỉnh sửa) để có thể chỉnh sửa dự án.
- Để xem trước trang web, hãy nhấn vào Xem ứng dụng. Sau đó, nhấn vào biểu tượng Toàn màn hình .
Trong Lớp học lập trình về việc rút gọn và nén tải trọng mạng trước đó, chúng ta đã giảm kích thước của main.js
từ 225 KB xuống còn 61,6 KB. Trong lớp học lập trình này, bạn sẽ khám phá cách tính năng nén Brotli có thể giảm kích thước gói này hơn nữa.
Nén Brotli
Brotli là một thuật toán nén mới hơn có thể cung cấp kết quả nén văn bản tốt hơn so với gzip
. Theo CertSimple, hiệu suất của Brotli là:
- Nhỏ hơn 14% so với
gzip
cho JavaScript - Nhỏ hơn 21% so với
gzip
đối với HTML - Nhỏ hơn
gzip
17% đối với CSS
Để sử dụng Brotli, máy chủ của bạn phải hỗ trợ HTTPS. Brotli được hỗ trợ trong tất cả trình duyệt hiện đại. Các trình duyệt hỗ trợ Brotli sẽ đưa br
vào tiêu đề Accept-Encoding
:
Accept-Encoding: gzip, deflate, br
Bạn có thể xác định thuật toán nén được sử dụng bằng cách sử dụng trường Content-Encoding
trong thẻ Mạng của Công cụ cho nhà phát triển Chrome (Command+Option+I
hoặc Ctrl+Alt+I
):
Cách bật Brotli
Cách bạn thiết lập máy chủ web để gửi tài nguyên được mã hoá bằng Brotli phụ thuộc vào cách bạn dự định mã hoá các tài nguyên đó. Bạn có thể tự động nén tài nguyên bằng Brotli tại thời điểm yêu cầu (động) hoặc mã hoá trước để tài nguyên đã được nén vào thời điểm người dùng yêu cầu (tĩnh).
Nén động
Nén động là quá trình nén các thành phần ngay khi trình duyệt yêu cầu.
Ưu điểm
- Bạn không cần tạo và cập nhật các phiên bản nén đã lưu của thành phần.
- Tính năng nén nhanh đặc biệt hiệu quả đối với các trang web được tạo động.
Nhược điểm
- Việc nén tệp ở cấp cao hơn để đạt được tỷ lệ nén tốt hơn sẽ mất nhiều thời gian hơn. Điều này có thể làm giảm hiệu suất khi người dùng chờ các thành phần nén trước khi máy chủ gửi.
Nén động bằng Node và Express
Tệp server.js
chịu trách nhiệm thiết lập máy chủ Node lưu trữ ứng dụng.
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}`);
});
Tất cả những gì bạn cần làm là nhập express
và sử dụng phần mềm trung gian express.static
để tải tất cả các tệp HTML, JS và CSS tĩnh trong public/directory
(và các tệp đó được tạo bằng webpack với mọi bản dựng).
Để đảm bảo tất cả tài sản được nén bằng brotli mỗi khi được yêu cầu, bạn có thể sử dụng mô-đun shrink-ray
. Bắt đầu bằng cách thêm thành phần này dưới dạng devDependency
trong package.json
:
"devDependencies": {
// ...
"shrink-ray": "^0.1.3"
},
Sau đó, nhập tệp này vào tệp máy chủ server.js
:
const express = require('express');
const shrinkRay = require('shrink-ray');
Và thêm lớp này làm phần mềm trung gian trước khi gắn express.static
:
// ...
const app = express();
// Compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
Bây giờ, hãy tải lại ứng dụng và xem kích thước gói trong bảng điều khiển Mạng:
Giờ đây, bạn có thể thấy brotli
được áp dụng từ bz
trong tiêu đề Content-Encoding
.
main.bundle.js
giảm từ 225 KB xuống còn 53,1 KB! Kích thước này nhỏ hơn khoảng 14% so với gzip
(61,6 KB).
Nén tĩnh
Ý tưởng đằng sau việc nén tĩnh là nén và lưu các thành phần trước.
Ưu điểm
- Bạn không còn phải lo lắng về độ trễ do mức độ nén cao nữa. Không cần làm gì trực tiếp để nén tệp vì giờ đây, bạn có thể tìm nạp trực tiếp các tệp đó.
Nhược điểm
- Các tài sản cần được nén với mọi bản dựng. Thời gian tạo bản dựng có thể tăng lên đáng kể nếu bạn sử dụng mức độ nén cao.
Nén tĩnh bằng Node và Express với webpack
Vì nén tĩnh liên quan đến việc nén các tệp trước, nên bạn có thể sửa đổi chế độ cài đặt webpack để nén các thành phần trong bước tạo bản dựng. Bạn có thể sử dụng brotli-webpack-plugin
cho việc này.
Bắt đầu bằng cách thêm thành phần này dưới dạng devDependency
trong package.json
:
"devDependencies": {
// ...
"brotli-webpack-plugin": "^1.1.0"
},
Giống như mọi trình bổ trợ webpack khác, hãy nhập trình bổ trợ này vào tệp cấu hình webpack.config.js
:
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
Và đưa vào mảng trình bổ trợ:
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
Mảng trình bổ trợ sử dụng các đối số sau:
asset
: Tên thành phần mục tiêu.[file]
được thay thế bằng tên tệp thành phần ban đầu.test
: Tất cả thành phần khớp với RegExp này (tức là các thành phần JavaScript có đuôi là.js
) đều được xử lý.
Ví dụ: main.js
sẽ được đổi tên thành main.js.br
.
Khi ứng dụng tải lại và tạo lại, một phiên bản nén của gói chính sẽ được tạo. Mở Glitch Console để xem nội dung bên trong thư mục public/
cuối cùng do máy chủ Node phân phát.
- Nhấp vào nút Công cụ.
- Nhấp vào nút Bảng điều khiển.
- Trong bảng điều khiển, hãy chạy các lệnh sau để chuyển sang thư mục
public
và xem tất cả tệp của thư mục đó:
cd public
ls -lh
Phiên bản nén brotli của gói, main.bundle.js.br
, hiện cũng được lưu tại đây và có kích thước nhỏ hơn khoảng 76% (225 KB so với 53 KB) so với main.bundle.js
.
Tiếp theo, hãy yêu cầu máy chủ gửi các tệp được nén bằng brotli này bất cứ khi nào phiên bản JS gốc của chúng được yêu cầu. Bạn có thể thực hiện việc này bằng cách xác định một tuyến mới trong server.js
trước khi các tệp được phân phát bằng 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
được dùng để cho máy chủ biết cách phản hồi yêu cầu GET
cho một điểm cuối cụ thể. Sau đó, một hàm gọi lại được dùng để xác định cách xử lý yêu cầu này. Tuyến đường này hoạt động như sau:
- Việc chỉ định
'*.js'
làm đối số đầu tiên có nghĩa là đối số này sẽ hoạt động cho mọi điểm cuối được kích hoạt để tìm nạp tệp JS. - Trong lệnh gọi lại,
.br
được đính kèm vào URL của yêu cầu và tiêu đề phản hồiContent-Encoding
được đặt thànhbr
. - Tiêu đề
Content-Type
được đặt thànhapplication/javascript; charset=UTF-8
để chỉ định loại MIME. - Cuối cùng,
next()
đảm bảo rằng trình tự tiếp tục với bất kỳ lệnh gọi lại nào có thể là lệnh gọi tiếp theo.
Vì một số trình duyệt có thể không hỗ trợ tính năng nén brotli, hãy xác nhận rằng brotli được hỗ trợ trước khi trả về tệp được nén brotli bằng cách kiểm tra tiêu đề yêu cầu Accept-Encoding
có chứa 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'));
Sau khi ứng dụng tải lại, hãy xem lại bảng điều khiển Mạng.
Thành công! Bạn đã sử dụng tính năng nén Brotli để nén thêm các thành phần của mình!
Kết luận
Lớp học lập trình này minh hoạ cách brotli
có thể giảm thêm kích thước tổng thể của ứng dụng. brotli
là một thuật toán nén mạnh mẽ hơn gzip
(nếu được hỗ trợ).