Đă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ể các 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ề trình chạy dịch vụ, có thể bạn đã gặp các nguyên mẫu đáng kể tương tự như sau:

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

Đôi khi, điều 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 bản cập nhật cho đăng ký trình chạy dịch vụ trước đó, như một cách cho phép người dùng biết 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 đầu tiên người dùng truy cập vào một ứng dụng web. Chưa có trình chạy dịch vụ nào và trình duyệt không có cách nào để biết trước liệu có một trình chạy dịch vụ được cài đặt hay không.

Là nhà phát triển, bạn cầ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. Mọi thứ 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 sử dụng máy tính để bàn mạnh mẽ mà là 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 chỉnh sửa luồng bổ sung này sẽ thêm tranh chấp về thời gian và bộ nhớ của CPU 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 mối lo ngại về xung đột CPU hoặc bộ nhớ đều phải nhường chỗ cho những lo lắng 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 giảm 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 phù hợp để bắt đầu đăng ký trình chạy dịch vụ cũng có thể phụ thuộc vào hoạt động của ứng dụng web 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 đăng ký worker dịch vụ trong ảnh động có thể dẫn đến hiện tượ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 đó.

Các lần 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ý, một 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ụ này 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ụ này bắt đầu trước khi thực hiện yêu cầu đối với bất kỳ trang nào thuộc phạm vi của trình chạy dịch vụ đó. Điều này hợp lý khi bạn xem xét việc này. 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ụ càng sớm càng tốt 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 đó, có lợi ích là giúp trình chạy dịch vụ hoạt động nhanh nhất có thể, nhằm cố gắng điền vào bộ nhớ đệm trong 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, thì bạn nên dừng lại để đảm bảo rằng trình xử lý install của trình chạy dịch vụ không yêu cầu các tài nguyên đấu tranh để giành 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ó trình chạy dịch vụ và bộ nhớ đệm được điền đầy đủ, bạn sẽ không nhận được trải nghiệm giống như người dùng mới và dễ bỏ qua 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 ứng dụng mẫu ở Chế độ ẩn danh bằng cách đ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 đăng ký trình chạy dịch vụ càng sớm càng tốt. Bạn có thể thấy các yêu cầu lưu trữ trước (các mục nhập 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 trình chạy dịch vụ) được 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 chương trình 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ần 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');
    });
}