Hầu hết các trang web và ứng dụng đều được tạo thành từ nhiều phần khác nhau. Thay vì gửi tất cả JavaScript tạo nên ứng dụng ngay khi trang được tải thì chia JavaScript thành nhiều phần cải thiện hiệu suất của trang.
Lớp học lập trình này cho biết cách sử dụng tính năng phân tách mã để cải thiện hiệu suất của một ứng dụng đơn giản sắp xếp ba số.
Đo
Như thường lệ, trước tiên, bạn cần đo lường hiệu suất của một trang web trước khi cố gắng thêm bất kỳ cách tối ưu hoá nào.
- Để xem trước trang web, hãy nhấn vào Xem ứng dụng. Sau đó nhấn
Toàn màn hình
.
- Nhấn tổ hợp phím "Control + Shift + J" (hoặc "Command+Option+J" trên máy Mac) để mở Công cụ cho nhà phát triển.
- Nhấp vào thẻ Mạng.
- Chọn hộp kiểm Tắt bộ nhớ đệm.
- Tải lại ứng dụng.
JavaScript có giá trị 71,2 KB chỉ để sắp xếp một vài số trong ứng dụng đơn giản. What gives?
Trong mã nguồn (src/index.js
), thư viện lodash
được nhập và sử dụng
trong ứng dụng này. Lodash cung cấp nhiều tiện ích hữu ích
nhưng chỉ sử dụng một phương thức duy nhất trong gói ở đây.
Cài đặt và nhập toàn bộ các phần phụ thuộc của bên thứ ba chỉ trong đó một phần nhỏ
đang được sử dụng một phần là một sai lầm phổ biến.
Tối ưu hoá
Có một số cách để cắt kích thước gói:
- Viết một phương pháp sắp xếp tuỳ chỉnh thay vì nhập thư viện của bên thứ ba
- Dùng phương thức
Array.prototype.sort()
tích hợp sẵn để sắp xếp theo số - Chỉ nhập phương thức
sortBy
từlodash
chứ không phải toàn bộ thư viện - Tải mã xuống để chỉ sắp xếp khi người dùng nhấp vào nút
Phương án 1 và 2 là các phương pháp hoàn toàn thích hợp để giảm kích thước gói (và có thể sẽ phù hợp nhất với ứng dụng thực tế). Tuy nhiên, đó chính là không được sử dụng trong hướng dẫn này nhằm mục đích giảng dạy 😈.
Cả hai lựa chọn 3 và 4 đều giúp cải thiện hiệu suất của ứng dụng này. Chiến lược phát hành đĩa đơn một số phần tiếp theo của lớp học lập trình này sẽ đề cập đến các bước này. Giống như mọi đoạn mã lập trình khác hướng dẫn, luôn cố gắng tự viết mã thay vì sao chép và dán.
Chỉ nhập những thông tin bạn cần
Bạn cần sửa đổi một vài tệp để chỉ nhập phương thức duy nhất từ lodash
.
Để bắt đầu, hãy thay thế phần phụ thuộc này trong package.json
:
"lodash": "^4.7.0",
bằng cách:
"lodash.sortby": "^4.7.0",
Bây giờ, trong src/index.js
, hãy nhập mô-đun cụ thể này:
import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";
Và cập nhật cách các giá trị được sắp xếp:
form.addEventListener("submit", e => {
e.preventDefault();
const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
const sortedValues = _.sortBy(values);
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
});
Tải lại ứng dụng, mở Công cụ cho nhà phát triển và xem bảng điều khiển Mạng một lần nữa.
Đối với ứng dụng này, kích thước gói đã giảm hơn 4 lần với rất ít hiệu quả hơn, nhưng vẫn còn nhiều khía cạnh cần cải thiện.
Chia tách mã
webpack là một trong những nguồn mở phổ biến nhất các gói mô-đun được sử dụng hiện nay. Tóm lại, API này nhóm tất cả các mô-đun JavaScript (dưới dạng cũng như các nội dung khác) tạo nên một ứng dụng web thành các tệp tĩnh có thể trình duyệt đọc được.
Gói duy nhất được sử dụng trong ứng dụng này có thể được chia thành hai gói riêng biệt phân đoạn:
- Người chịu trách nhiệm về mã tạo nên tuyến ban đầu của chúng ta
- Phân đoạn phụ chứa mã sắp xếp
Với việc sử dụng tính năng nhập động, một phân đoạn phụ có thể được tải từng phần, hoặc được tải theo yêu cầu. Trong ứng dụng này, mã tạo nên phân đoạn có thể là chỉ được tải khi người dùng nhấn nút.
Bắt đầu bằng cách xoá lệnh nhập cấp cao nhất cho phương thức sắp xếp trong src/index.js
:
import sortBy from "lodash.sortby";
Sau đó, hãy nhập sự kiện đó vào trình nghe sự kiện để kích hoạt khi nhấn nút:
form.addEventListener("submit", e => {
e.preventDefault();
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
Tính năng import()
là một phần của
đề xuất (hiện đang ở giai đoạn
3 của quy trình TC39) để bao gồm khả năng nhập động một mô-đun.
webpack đã bao gồm tính năng hỗ trợ cho thao tác này và tuân theo cú pháp tương tự được đặt
theo đề xuất.
import()
trả về một lời hứa và khi giải quyết, biến được chọn
mô-đun được cung cấp được chia thành một phần riêng biệt. Sau khi mô-đun là
trả về, module.default
dùng để tham chiếu giá trị mặc định
dữ liệu xuất do lodash cung cấp. Lời hứa được xâu chuỗi bằng một .then
khác
gọi một phương thức sortInput
để sắp xếp 3 giá trị đầu vào. Ở cuối
chuỗi hứa hẹn, .catch()
dùng để xử lý các trường hợp lời hứa bị từ chối
do lỗi.
Việc cuối cùng cần làm là ghi phương thức sortInput
ở
cuối tệp. Đây phải là một hàm trả về một hàm
lấy phương thức đã nhập từ lodash.sortBy
. Sau đó, hàm được lồng có thể
sắp xếp ba giá trị đầu vào và cập nhật DOM.
const sortInput = () => {
return (sortBy) => {
const values = [
input1.valueAsNumber,
input2.valueAsNumber,
input3.valueAsNumber
];
const sortedValues = sortBy(values);
results.innerHTML = `
<h2>
${sortedValues}
</h2>
`
};
}
Giám Sát
Tải lại ứng dụng lần cuối và theo dõi kỹ Mạng bảng điều khiển. Chỉ một gói nhỏ ban đầu được tải xuống ngay khi ứng dụng tải.
Sau khi nhấn nút để sắp xếp các số đầu vào, đoạn chứa mã sắp xếp được tìm nạp và thực thi.
Hãy lưu ý cách các số vẫn được sắp xếp!
Kết luận
Tách mã và tải từng phần có thể là những kỹ thuật cực kỳ hữu ích để cắt giảm kích thước gói ban đầu của ứng dụng và điều này có thể trực tiếp dẫn đến thời gian tải trang nhanh hơn nhiều. Tuy nhiên, có một số điều quan trọng mà bạn cần được xem xét trước khi đưa tối ưu hoá này vào ứng dụng của bạn.
Giao diện người dùng tải từng phần
Khi tải từng phần của các mô-đun mã cụ thể, bạn cần xem xét cách trải nghiệm người dùng có kết nối mạng yếu hơn. Tách và khi tải một đoạn mã rất lớn khi người dùng gửi một hành động, có vẻ như ứng dụng đã ngừng hoạt động, vì vậy hãy cân nhắc hiển thị đang tải chỉ báo của một số loại.
Tải từng phần các mô-đun nút của bên thứ ba
Không phải lúc nào đây cũng là phương pháp tốt nhất để tải từng phần các phần phụ thuộc của bên thứ ba trong
ứng dụng của bạn và điều đó phụ thuộc vào nơi bạn sử dụng chúng. Thông thường, bên thứ ba
các phần phụ thuộc được tách thành một gói vendor
riêng biệt có thể được lưu vào bộ nhớ đệm
nhưng chúng không cập nhật thường xuyên. Đọc thêm về cách
SplitChunksPlugin có thể
giúp bạn làm việc này.
Tải từng phần bằng khung JavaScript
Nhiều khung và thư viện phổ biến sử dụng gói web cung cấp các thành phần trừu tượng thực hiện tải từng phần dễ dàng hơn so với sử dụng tính năng nhập động ở giữa .
- Các mô-đun tải từng phần bằng Angular
- Phân tách mã bằng React Router
- Tải từng phần bằng Bộ định tuyến Vue
Mặc dù rất hữu ích khi hiểu cách hoạt động của tính năng nhập động, nhưng hãy luôn sử dụng mà khung/thư viện của bạn đề xuất để tải từng phần các mô-đun cụ thể.
Tải trước và tìm nạp trước
Nếu có thể, hãy tận dụng gợi ý của trình duyệt như <link rel="preload">
hoặc <link rel="prefetch">
để thử và tải các mô-đun quan trọng thậm chí
sớm hơn. webpack hỗ trợ cả hai gợi ý thông qua việc sử dụng nhận xét thần kỳ trong quá trình nhập
tuyên bố. Điều này được giải thích chi tiết hơn trong
Hướng dẫn Tải trước các đoạn quan trọng.
Tải từng phần không chỉ áp dụng cho mã
Hình ảnh có thể tạo nên một phần quan trọng của ứng dụng. Tải từng phần những trang web nằm dưới màn hình đầu tiên hoặc bên ngoài khung nhìn của thiết bị, có thể tăng tốc độ trang web. Đã đọc tìm hiểu thêm về vấn đề này trong Hướng dẫn về Lazysize.