Đăng ký trình chạy dịch vụ

Các phương pháp hay nhất để xác định thời gian đăng ký worker dịch vụ.

Trình làm việc dịch vụ có thể tăng tốc đáng kể số lượt truy cập lại vào ứng dụng web của bạn, nhưng bạn nên thực hiện các bước để đảm bảo rằng quá trình cài đặt ban đầu của trình làm việc dịch vụ không làm giảm trải nghiệm của người dùng trong lần truy cập đầu tiên.

Nhìn chung, việc trì hoãn đăng ký trình chạy dịch vụ cho đến sau khi trang ban đầu tải xong sẽ mang lại trải nghiệm tốt nhất cho người dùng, đặc biệt là những người dùng trên thiết bị di động có kết nối mạng chậm hơn.

Mã nguyên mẫu đăng ký phổ biến

Nếu từng đọc về worker dịch vụ, có thể bạn đã gặp phải đoạn mã nguyên mẫu tương tự như sau:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js');
}

Đôi khi, việc này có thể đi kèm với một vài câu lệnh console.log() hoặc phát hiện nội dung cập nhật cho một lượt đăng ký trình chạy dịch vụ trước đó, như một cách để cho người dùng biết cần làm mới trang. Nhưng đó chỉ là những biến thể nhỏ trên vài dòng mã tiêu chuẩn.

Vậy navigator.serviceWorker.register có gì khác biệt không? Có phương pháp hay nhất nào để làm theo không? Không có gì đáng ngạc nhiên (vì bài viết này chưa kết thúc ngay tại đây), câu trả lời cho cả hai câu hỏi đều là "có!"

Lượt truy cập đầu tiên của người dùng

Hãy xem xét lần truy cập đầu tiên của người dùng vào một ứng dụng web. Chưa có worker nào và trình duyệt không thể biết trước liệu cuối cùng có cài đặt worker nào hay không.

Là nhà phát triển, bạn nên ưu tiên đảm bảo trình duyệt nhanh chóng nhận được bộ tài nguyên tối thiểu cần thiết để hiển thị một trang tương tác. Bất cứ điều gì làm chậm quá trình truy xuất các phản hồi đó đều là kẻ thù của trải nghiệm tương tác nhanh.

Bây giờ, hãy tưởng tượng trong quá trình tải JavaScript hoặc hình ảnh mà trang của bạn cần hiển thị, trình duyệt của bạn quyết định bắt đầu một luồng hoặc quy trình trong nền (để ngắn gọn, chúng ta sẽ giả định đó là một luồng). Giả sử bạn không dùng máy tính để bàn mạnh mẽ mà dùng loại điện thoại di động có cấu hình thấp mà nhiều người trên thế giới coi là thiết bị chính của họ. Việc tạo thêm luồng này sẽ làm tăng mức tranh chấp về thời gian CPU và bộ nhớ mà trình duyệt của bạn có thể dành để hiển thị một trang web tương tác.

Luồng ở chế độ nền rảnh có thể sẽ không tạo ra sự khác biệt đáng kể. Nhưng nếu luồng đó không ở trạng thái rảnh mà quyết định sẽ bắt đầu tải tài nguyên xuống từ mạng thì sao? Mọi lo ngại về xung đột CPU hoặc bộ nhớ đều phải nhường chỗ cho những lo ngại về băng thông bị giới hạn trên nhiều thiết bị di động. Băng thông rất quý giá, vì vậy, đừng làm suy yếu tài nguyên quan trọng bằng cách tải tài nguyên phụ xuống cùng một lúc.

Tất cả những điều này có nghĩa là việc tạo một luồng worker dịch vụ mới để tải xuống và lưu các tài nguyên vào bộ nhớ đệm ở chế độ nền có thể không phù hợp với mục tiêu của bạn là cung cấp trải nghiệm tương tác ngắn nhất trong lần đầu tiên người dùng truy cập vào trang web của bạn.

Cải thiện mã nguyên mẫu

Giải pháp là kiểm soát việc bắt đầu trình chạy dịch vụ bằng cách chọn thời điểm gọi navigator.serviceWorker.register(). Một quy tắc đơn giản là trì hoãn việc đăng ký cho đến khi load event kích hoạt trên window, như sau:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}

Tuy nhiên, thời điểm thích hợp để bắt đầu đăng ký worker dịch vụ cũng có thể phụ thuộc vào việc ứng dụng web của bạn đang làm gì ngay sau khi tải. Ví dụ: ứng dụng web Google I/O 2016 có một ảnh động ngắn trước khi chuyển sang màn hình chính. Nhóm của chúng tôi nhận thấy việc bắt đầu quy trình đăng ký worker dịch vụ trong ảnh động có thể dẫn đến tình trạng giật trên các thiết bị di động cấp thấp. Thay vì mang đến trải nghiệm kém cho người dùng, chúng tôi đã trì hoãn việc đăng ký worker dịch vụ cho đến sau khi ảnh động kết thúc, khi trình duyệt có nhiều khả năng sẽ có vài giây rảnh.

Tương tự, nếu ứng dụng web của bạn sử dụng một khung thực hiện việc thiết lập bổ sung sau khi tải trang, hãy tìm một sự kiện dành riêng cho khung để báo hiệu thời điểm hoàn tất công việc đó.

Lượt truy cập tiếp theo

Cho đến nay, chúng ta đã tập trung vào trải nghiệm lượt truy cập đầu tiên, nhưng việc trì hoãn đăng ký worker dịch vụ sẽ ảnh hưởng như thế nào đến các lượt truy cập lại vào trang web của bạn? Mặc dù điều này có thể khiến một số người ngạc nhiên, nhưng việc này sẽ không ảnh hưởng gì cả.

Khi được đăng ký, trình chạy dịch vụ sẽ trải qua các sự kiện vòng đời installactivate. Sau khi được kích hoạt, trình chạy dịch vụ có thể xử lý các sự kiện fetch cho mọi lượt truy cập tiếp theo vào ứng dụng web của bạn. Trình chạy dịch vụ bắt đầu trước khi yêu cầu bất kỳ trang nào trong phạm vi của trình chạy dịch vụ được thực hiện. Điều này rất hợp lý khi bạn nghĩ về nó. Nếu worker dịch vụ hiện tại chưa chạy trước khi truy cập vào một trang, thì worker dịch vụ sẽ không có cơ hội thực hiện các sự kiện fetch cho các yêu cầu điều hướng.

Vì vậy, khi có một worker dịch vụ đang hoạt động, bạn không cần quan tâm đến thời điểm gọi navigator.serviceWorker.register() hay thực tế là liệu bạn có gọi worker đó hay không. Trừ phi bạn thay đổi URL của tập lệnh worker dịch vụ, navigator.serviceWorker.register() sẽ thực sự là không hoạt động trong các lượt truy cập tiếp theo. Thời điểm gọi không liên quan.

Lý do nên đăng ký sớm

Có tình huống nào mà bạn nên đăng ký worker dịch vụ sớm nhất có thể không? Một ví dụ có thể kể đến là khi worker dịch vụ sử dụng clients.claim() để kiểm soát trang trong lần truy cập đầu tiên và worker dịch vụ tích cực thực hiện lưu vào bộ nhớ đệm thời gian chạy bên trong trình xử lý fetch. Trong trường hợp đó, bạn nên kích hoạt trình chạy dịch vụ nhanh nhất có thể để cố gắng điền vào bộ nhớ đệm thời gian chạy bằng các tài nguyên có thể hữu ích sau này. Nếu ứng dụng web của bạn thuộc danh mục này, bạn nên xem lại để đảm bảo trình xử lý install của worker dịch vụ không yêu cầu tài nguyên cạnh tranh băng thông với các yêu cầu của trang chính.

Thử nghiệm

Một cách hay để mô phỏng lượt truy cập đầu tiên là mở ứng dụng web trong cửa sổ Chrome Ẩn danh và xem lưu lượng truy cập mạng trong DevTools của Chrome. Là một nhà phát triển web, bạn có thể tải lại một thực thể cục bộ của ứng dụng web hàng chục lần mỗi ngày. Tuy nhiên, khi truy cập lại trang web của bạn khi đã có worker dịch vụ và bộ nhớ đệm được điền đầy đủ, bạn sẽ không có được trải nghiệm giống như người dùng mới và dễ dàng bỏ qua một vấn đề tiềm ẩn.

Sau đây là ví dụ minh hoạ sự khác biệt mà thời gian đăng ký có thể tạo ra. Cả hai ảnh chụp màn hình đều được chụp khi truy cập vào một ứng dụng mẫu ở chế độ Ẩn danh bằng cách sử dụng tính năng điều tiết mạng để mô phỏng kết nối chậm.

Lưu lượng truy cập mạng có đăng ký sớm.

Ảnh chụp màn hình ở trên phản ánh lưu lượng truy cập mạng khi mẫu được sửa đổi để thực hiện việc đăng ký worker dịch vụ sớm nhất có thể. Bạn có thể thấy các yêu cầu lưu vào bộ nhớ đệm trước (các mục có biểu tượng bánh răng bên cạnh, bắt nguồn từ trình xử lý install của worker dịch vụ) xen kẽ với các yêu cầu về các tài nguyên khác cần thiết để hiển thị trang.

Lưu lượng truy cập mạng có đăng ký muộn.

Trong ảnh chụp màn hình ở trên, quá trình đăng ký trình chạy dịch vụ bị trì hoãn cho đến khi trang tải xong. Bạn có thể thấy rằng các yêu cầu lưu vào bộ nhớ đệm trước không bắt đầu cho đến khi tất cả tài nguyên được tìm nạp từ mạng, loại bỏ mọi tranh chấp về băng thông. Hơn nữa, vì một số mục mà chúng ta đang lưu vào bộ nhớ đệm trước đã có trong bộ nhớ đệm HTTP của trình duyệt (các mục có (from disk cache) trong cột Kích thước), nên chúng ta có thể điền sẵn bộ nhớ đệm của worker dịch vụ mà không cần phải truy cập lại vào mạng.

Bạn sẽ nhận được điểm thưởng nếu chạy loại kiểm thử này trên một thiết bị thực tế, cấp thấp trên mạng di động thực. Bạn có thể tận dụng các tính năng gỡ lỗi từ xa của Chrome để đính kèm điện thoại Android vào máy tính để bàn qua USB và đảm bảo rằng các bài kiểm thử bạn đang chạy thực sự phản ánh trải nghiệm thực tế của nhiều người dùng.

Kết luận

Tóm lại, bạn cần ưu tiên hàng đầu việc đảm bảo người dùng có trải nghiệm tốt nhất trong lần truy cập đầu tiên. Việc trì hoãn việc đăng ký trình chạy dịch vụ cho đến sau khi trang tải trong lượt truy cập đầu tiên có thể giúp đảm bảo điều đó. Bạn vẫn sẽ nhận được tất cả lợi ích của việc sử dụng worker dịch vụ cho các lượt truy cập lặp lại.

Một cách đơn giản để đảm bảo trì hoãn việc đăng ký ban đầu của worker dịch vụ cho đến sau khi trang đầu tiên tải xong là sử dụng các bước sau:

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}