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

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

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

Nhìn chung, việc trì hoãn đăng ký trình chạy dịch vụ cho đến khi trang đầu tiên 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ẫu đăng ký phổ biến

Nếu đã từng đọc về trình chạy dịch vụ, có thể bạn sẽ bắt gặp mã nguyên mẫu tương tự như sau:

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

Đôi khi, thao tá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 bản cập nhật cho đăng ký trình chạy dịch vụ trước đó, nhằm cho người dùng biết để làm mới trang. Nhưng đó chỉ là các biến thể nhỏ trong một vài dòng mã tiêu chuẩn.

Vậy có sự khác biệt nào đối với navigator.serviceWorker.register không? Có phương pháp hay nhất nào cần áp dụng không? Không có gì đáng ngạc nhiên (vì bài viết này không kết thúc ngay tại đây) thì câu trả lời cho cả hai 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ó trình chạy dịch vụ nào được cài đặt hay không.

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

Bây giờ, hãy tưởng tượng rằng trong quá trình tải JavaScript hoặc hình ảnh xuống mà trang của bạn cần hiển thị, trình duyệt của bạn sẽ quyết định bắt đầu một luồng hoặc quy trình trong nền (nói 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ột chiếc máy tính để bàn cường độ cao mà thay vào đó là loại điện thoại di động yếu mà phần lớn thế giới coi là thiết bị chính của họ. Việc tăng luồng bổ sung này sẽ làm tăng 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ể phải dùng để hiển thị một trang web tương tác.

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

Nói tóm lại, việc xây dựng một luồng worker dịch vụ mới để tải xuống và lưu tài nguyên vào bộ nhớ đệm ở chế độ nền có thể đi ngược lại với mục tiêu của bạn là cung cấp trải nghiệm tương tác có thời gian ngắn nhất vào lần đầu người dùng truy cập trang web.

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

Giải pháp cho yêu cầu này 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 chung là trì hoãn việc đăng ký cho đến khi load event kích hoạt vào 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 của bạn 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 chúng tôi nhận thấy rằng việc bắt đầu đăng ký trình chạy dịch vụ trong khi tạo ảnh động có thể dẫn đến hiện tượng giật trên thiết bị di động cấp thấp. Thay vì cung cấp cho người dùng trải nghiệm không tốt, chúng tôi trì hoãn đăng ký trình chạy dịch vụ cho đến sau khi tạo ảnh động, khi mà trình duyệt có nhiều khả năng sẽ có vài giây không hoạt động.

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 trang tải, hãy tìm một sự kiện dành riêng cho khung, báo hiệu khi công việc đó hoàn tất.

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

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

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, mộ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ụ này sẽ bắt đầu trước khi thực hiện yêu cầu cho bất kỳ trang nào thuộc phạm vi của nó. Điều này là hợp lý khi bạn nghĩ về nó. Nếu trình chạy dịch vụ hiện có không chạy trước khi truy cập vào một trang, trình chạy 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 trình chạy dịch vụ đang hoạt động, thì việc bạn gọi navigator.serviceWorker.register() hay thực tế là có gọi trình chạy đó hay không. Trừ phi bạn thay đổi URL của tập lệnh trình chạy dịch vụ, navigator.serviceWorker.register() thực sự sẽ là trạng thái không hoạt động trong các lượt truy cập tiếp theo. Khi hàm được gọi không liên quan.

Lý do đăng ký sớm

Có trường hợp nào mà việc đăng ký trình chạy dịch vụ càng sớm càng tốt không? Một điều cần lưu ý là khi trình chạy dịch vụ sử dụng clients.claim() để kiểm soát trang trong lần truy cập đầu tiên, và trình chạy dịch vụ này thực hiện tích cực lưu vào bộ nhớ đệm trong thời gian chạy bên trong trình xử lý fetch. Trong trường hợp đó, sẽ có lợi cho việc giúp trình chạy dịch vụ hoạt động nhanh nhất có thể để cố gắng điền sẵn 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 lùi lại một bước để đả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 tranh giành băng thông với các yêu cầu của trang chính.

Thử nghiệm mọi thứ

Một cách hữu hiệu để mô phỏng lần truy cập đầu tiên là mở ứng dụng web trong cửa sổ Ẩn danh của Chrome và xem lưu lượng truy cập mạng trong Công cụ cho nhà phát triển của Chrome. Là nhà phát triển web, bạn có thể phải tải lại một phiên bản cục bộ của ứng dụng web của mình hàng chục lần mỗi ngày. Tuy nhiên, bằng cách truy cập lại trang web khi đã có một trình chạy 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à cũng dễ dàng bỏ qua vấn đề tiềm ẩn.

Dưới đâ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 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ụ sớm nhất có thể. Bạn có thể thấy các yêu cầu lưu 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ụ) xen kẽ với các yêu cầu về 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. Bạn có thể thấy rằng các yêu cầu lưu trước vào bộ nhớ đệm không bắt đầu cho đến khi tất cả tài nguyên được tìm nạp từ mạng, giúp loại bỏ mọi tranh chấp về băng thông. Hơn nữa, do một số mục chúng ta đang lưu trước vào bộ nhớ đệm đã 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 vào bộ nhớ đệm của trình chạy dịch vụ mà không cần phải truy cập lại vào mạng.

Sẽ là một điểm cộng nếu bạn chạy loại hình kiểm thử này trên một thiết bị cấp thấp thực tế trên mạng di động thực. Bạn có thể tận dụng tính năng gỡ lỗi từ xa của Chrome để gắn điện thoại Android vào máy tính 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, ưu tiên hàng đầu nên đảm bảo người dùng có được trải nghiệm tốt nhất khi truy cập lần đầu. Việc trì hoãn đăng ký trình chạy dịch vụ cho đến 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 có một trình chạy dịch vụ cho các lần truy cập lặp lại.

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

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