Bạn không bao giờ cần gửi nhiều mã hơn mức cần thiết cho người dùng, vì vậy hãy chia các gói để đảm bảo điều này không bao giờ xảy ra!
Phương thức React.lazy
giúp bạn dễ dàng phân tách mã một ứng dụng React trên một
cấp thành phần bằng cách sử dụng tính năng nhập động.
import React, { lazy } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const DetailsComponent = () => (
<div>
<AvatarComponent />
</div>
)
Tại sao tính năng này hữu ích?
Một ứng dụng React lớn thường sẽ bao gồm nhiều thành phần, phần mềm tiện ích và thư viện của bên thứ ba. Nếu bạn không cố gắng tải các phần khác nhau của một ứng dụng chỉ khi chúng được cần đến, một phần lớn gói JavaScript sẽ được chuyển đến người dùng của bạn ngay khi họ tải trang đầu tiên. Điều này có thể ảnh hưởng đáng kể đến hiệu suất trang.
Hàm React.lazy
cung cấp một cách tích hợp để phân tách các thành phần trong một
thành các phần JavaScript riêng biệt mà không cần nhiều công sức. Bạn có thể
thì hãy xử lý trạng thái tải khi bạn ghép nối nó với Suspense
thành phần.
Suspense (Hồi hộp)
Vấn đề khi vận chuyển một tải trọng JavaScript lớn đến người dùng là thời lượng thời gian cần để hoàn tất việc tải trang, đặc biệt là trên các thiết bị yếu hơn và kết nối mạng. Đây là lý do tại sao việc chia tách mã và tải từng phần là cực kỳ hữu ích.
Tuy nhiên, sẽ luôn có đôi chút chậm trễ mà người dùng phải thực hiện khi
thành phần phân tách mã đang được tìm nạp trên mạng, vì vậy điều quan trọng là
hiển thị trạng thái tải hữu ích. Sử dụng React.lazy
với Suspense
giúp giải quyết vấn đề này.
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const renderLoader = () => <p>Loading</p>;
const DetailsComponent = () => (
<Suspense fallback={renderLoader()}>
<AvatarComponent />
</Suspense>
)
Suspense
chấp nhận thành phần fallback
cho phép bạn hiển thị mọi React
làm trạng thái tải. Ví dụ sau đây minh hoạ cách hoạt động của chế độ này.
Hình đại diện chỉ hiển thị khi người dùng nhấp vào nút, trong đó người dùng có yêu cầu
sau đó thực hiện để truy xuất mã cần thiết cho AvatarComponent
bị tạm ngưng.
Trong thời gian chờ đợi, thành phần tải dự phòng sẽ xuất hiện.
Ở đây, mã tạo nên AvatarComponent
rất nhỏ, tức là
tại sao vòng quay tải chỉ hiển thị trong một khoảng thời gian ngắn. Lớn hơn
có thể mất nhiều thời gian hơn để tải, đặc biệt là trên
kết nối mạng yếu.
Để minh hoạ rõ hơn về cách hoạt động của quy trình này, hãy làm như sau:
- Để 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.
- Nhấp vào trình đơn thả xuống Điều tiết, được đặt thành Không điều tiết theo mặc định. Chọn 3G nhanh.
- Nhấp vào nút Nhấp vào tôi trong ứng dụng.
Chỉ báo tải sẽ hiển thị lâu hơn. Lưu ý cách tất cả các mã
tạo nên AvatarComponent
được tìm nạp dưới dạng một phân đoạn riêng biệt.
![Bảng điều khiển mạng Công cụ cho nhà phát triển cho thấy một tệp chunk.js đang được tải xuống](https://web.dev/static/articles/code-splitting-suspense/image/devtools-network-panel-sh-bab60da5120ad.png?authuser=5&hl=vi)
Tạm ngưng nhiều thành phần
Một tính năng khác của Suspense
là cho phép bạn tạm ngưng nhiều
thành phần từ khi tải, ngay cả khi tất cả các thành phần đó đều được tải từng phần.
Ví dụ:
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));
const renderLoader = () => <p>Loading</p>;
const DetailsComponent = () => (
<Suspense fallback={renderLoader()}>
<AvatarComponent />
<InfoComponent />
<MoreInfoComponent />
</Suspense>
)
Đây là một cách cực kỳ hữu ích để trì hoãn việc kết xuất nhiều thành phần trong khi chỉ hiển thị một trạng thái tải duy nhất. Sau khi hoàn tất tất cả các thành phần tìm nạp, người dùng sẽ thấy tất cả các quảng cáo đó hiển thị cùng một lúc.
Bạn có thể xem điều này với nhúng sau đây:
Nếu không, bạn sẽ dễ gặp phải vấn đề tải ngẫu nhiên hoặc các phần khác nhau của giao diện người dùng sẽ tải lần lượt, trong đó mỗi phần đều có chỉ báo đang tải. Điều này có thể khiến người dùng cảm thấy khó chịu hơn.
Xử lý lỗi tải
Suspense
cho phép bạn hiển thị trạng thái tải tạm thời trong khi mạng
các yêu cầu được đưa ra một cách nâng cao. Nhưng nếu các yêu cầu mạng đó không thành công thì sao
vì lý do nào đó? Có thể bạn đang không kết nối mạng hoặc có thể ứng dụng web của bạn đang tìm cách
tải từng phần một URL được tạo phiên bản
đã lỗi thời và không còn dùng được sau khi triển khai lại máy chủ.
React có một mẫu tiêu chuẩn để xử lý linh hoạt các kiểu tải này
lỗi: sử dụng ranh giới lỗi. Như được mô tả trong tài liệu,
bất kỳ thành phần React nào cũng có thể đóng vai trò là ranh giới lỗi nếu thành phần đó triển khai (hoặc
cả hai) của phương thức vòng đời static getDerivedStateFromError()
hoặc
componentDidCatch()
.
Để phát hiện và xử lý các lỗi tải từng phần, bạn có thể gói Suspense
của mình
thành phần có một thành phần mẹ đóng vai trò là ranh giới lỗi. Bên trong
phương thức render()
của error scope, bạn có thể hiển thị phần tử con như nguyên trạng nếu có
không có lỗi hoặc hiển thị thông báo lỗi tuỳ chỉnh nếu xảy ra sự cố:
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));
const renderLoader = () => <p>Loading</p>;
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {hasError: false};
}
static getDerivedStateFromError(error) {
return {hasError: true};
}
render() {
if (this.state.hasError) {
return <p>Loading failed! Please reload.</p>;
}
return this.props.children;
}
}
const DetailsComponent = () => (
<ErrorBoundary>
<Suspense fallback={renderLoader()}>
<AvatarComponent />
<InfoComponent />
<MoreInfoComponent />
</Suspense>
</ErrorBoundary>
)
Kết luận
Nếu bạn không biết nên bắt đầu áp dụng chế độ phân tách mã cho thư viện React ở đâu đăng ký, hãy làm theo các bước sau:
- Bắt đầu ở cấp tuyến đường. Tuyến đường là cách đơn giản nhất để xác định các điểm
ứng dụng của bạn. Chiến lược phát hành đĩa đơn
Tài liệu phản ứng
cho biết cách sử dụng
Suspense
cùng vớireact-router
. - Xác định mọi thành phần lớn trên một trang trong trang web của bạn chỉ hiển thị trên một số tương tác nhất định của người dùng (như nhấp vào nút). Tách sẽ giảm thiểu tải trọng JavaScript của bạn.
- Cân nhắc việc tách bất kỳ nội dung nào khác nằm ngoài màn hình và không quan trọng đối với người dùng.