Đưa trình chạy dịch vụ đến Google Tìm kiếm

Câu chuyện về những gì đã được triển khai, cách đo lường mức tác động và những điểm đánh đổi đã được thực hiện.

Ngày xuất bản: 20 tháng 6 năm 2019

Tìm kiếm hầu hết mọi chủ đề trên Google, bạn sẽ thấy ngay một trang kết quả có ý nghĩa và liên quan mà bạn có thể nhận ra ngay lập tức. Có thể bạn không nhận ra rằng trong một số trường hợp, trang kết quả tìm kiếm này được cung cấp bởi một công nghệ web mạnh mẽ có tên là service worker.

Việc triển khai tính năng hỗ trợ trình chạy dịch vụ cho Google Tìm kiếm mà không ảnh hưởng tiêu cực đến hiệu suất đòi hỏi hàng chục kỹ sư làm việc trên nhiều nhóm. Đây là câu chuyện về những gì đã được vận chuyển, cách đo lường hiệu suất và những điểm đánh đổi đã được thực hiện.

Những lý do chính để khám phá service worker

Việc thêm một worker dịch vụ vào ứng dụng web, giống như việc thực hiện bất kỳ thay đổi nào về cấu trúc đối với trang web của bạn, cần được thực hiện với một mục tiêu rõ ràng. Đối với nhóm Google Tìm kiếm, có một số lý do chính khiến việc thêm một worker dịch vụ đáng để khám phá.

Hạn chế lưu kết quả tìm kiếm vào bộ nhớ đệm

Nhóm Google Tìm kiếm nhận thấy rằng người dùng thường tìm kiếm cùng một cụm từ nhiều lần trong một khoảng thời gian ngắn. Thay vì kích hoạt một yêu cầu phụ trợ mới chỉ để nhận được những kết quả có khả năng giống nhau, nhóm Tìm kiếm muốn tận dụng tính năng lưu vào bộ nhớ đệm và thực hiện những yêu cầu lặp lại đó cục bộ.

Bạn không thể bỏ qua tầm quan trọng của tính mới mẻ. Đôi khi, người dùng tìm kiếm cùng một cụm từ nhiều lần vì đó là một chủ đề đang phát triển và họ mong đợi sẽ thấy kết quả mới. Việc sử dụng một worker dịch vụ cho phép nhóm Tìm kiếm triển khai logic chi tiết để kiểm soát thời gian tồn tại của kết quả tìm kiếm được lưu vào bộ nhớ đệm cục bộ và đạt được sự cân bằng chính xác giữa tốc độ và độ mới mà họ tin rằng sẽ phục vụ người dùng tốt nhất.

Trải nghiệm ngoại tuyến có ý nghĩa

Ngoài ra, nhóm Google Tìm kiếm muốn mang đến trải nghiệm ngoại tuyến có ý nghĩa. Khi muốn tìm hiểu về một chủ đề, người dùng muốn truy cập thẳng vào trang Google Tìm kiếm và bắt đầu tìm kiếm mà không cần lo lắng về việc có kết nối Internet hay không.

Nếu không có service worker, việc truy cập vào trang tìm kiếm của Google khi không có mạng sẽ chỉ dẫn đến trang lỗi mạng tiêu chuẩn của trình duyệt và người dùng sẽ phải nhớ quay lại và thử lại khi có kết nối trở lại. Với một service worker, bạn có thể phân phát phản hồi HTML tuỳ chỉnh khi không có mạng và cho phép người dùng nhập cụm từ tìm kiếm ngay lập tức.

Ảnh chụp màn hình giao diện thử lại trong nền.

Kết quả sẽ không có sẵn cho đến khi có kết nối Internet, nhưng service worker cho phép hoãn lại và gửi cụm từ tìm kiếm đến các máy chủ của Google ngay khi thiết bị kết nối lại với Internet bằng API đồng bộ hoá trong nền.

Lưu và phân phát JavaScript thông minh hơn

Một động lực khác là tối ưu hoá việc lưu vào bộ nhớ đệm và tải mã JavaScript theo mô-đun, giúp cung cấp năng lượng cho nhiều loại tính năng trên trang kết quả tìm kiếm. Việc kết hợp JavaScript mang lại một số lợi ích hợp lý khi không có sự tham gia của service worker, vì vậy, nhóm Tìm kiếm không muốn chỉ đơn giản là ngừng kết hợp hoàn toàn.

Bằng cách sử dụng khả năng phân phiên bản và lưu vào bộ nhớ đệm các đoạn JavaScript chi tiết của trình chạy dịch vụ trong thời gian chạy, nhóm Tìm kiếm nghi ngờ rằng họ có thể giảm lượng thay đổi bộ nhớ đệm và đảm bảo rằng JavaScript được dùng lại trong tương lai có thể được lưu vào bộ nhớ đệm một cách hiệu quả. Logic bên trong trình chạy dịch vụ của họ có thể phân tích một yêu cầu HTTP đi ra cho một gói chứa nhiều mô-đun JavaScript và thực hiện yêu cầu đó bằng cách ghép nhiều mô-đun được lưu vào bộ nhớ đệm cục bộ – "huỷ gói" một cách hiệu quả khi có thể. Điều này giúp tiết kiệm băng thông cho người dùng và cải thiện khả năng phản hồi tổng thể.

Việc sử dụng JavaScript được lưu vào bộ nhớ đệm do một worker dịch vụ phân phát cũng mang lại lợi ích về hiệu suất: trong Chrome, một bản trình bày mã byte đã phân tích cú pháp của JavaScript đó được lưu trữ và sử dụng lại, dẫn đến việc giảm lượng công việc cần thực hiện trong thời gian chạy để thực thi JavaScript trên trang.

Thử thách và giải pháp

Sau đây là một số trở ngại cần phải vượt qua để đạt được các mục tiêu đã nêu của nhóm. Mặc dù một số thách thức trong số này chỉ dành riêng cho Google Tìm kiếm, nhưng nhiều thách thức trong số đó có thể áp dụng cho nhiều trang web có thể đang cân nhắc việc triển khai service worker.

Vấn đề: chi phí của trình chạy dịch vụ

Thách thức lớn nhất và cũng là thách thức duy nhất cản trở việc ra mắt một worker dịch vụ trên Google Tìm kiếm là phải đảm bảo rằng worker đó không làm tăng độ trễ mà người dùng cảm nhận được. Google Tìm kiếm rất coi trọng hiệu suất và trước đây, Google đã chặn việc ra mắt chức năng mới nếu chức năng đó làm tăng thêm dù chỉ vài chục mili giây độ trễ cho một nhóm người dùng nhất định.

Khi nhóm bắt đầu thu thập dữ liệu hiệu suất trong những thử nghiệm đầu tiên, họ nhận thấy rõ ràng sẽ có vấn đề. HTML được trả về để phản hồi các yêu cầu điều hướng cho trang kết quả tìm kiếm là động và thay đổi rất nhiều tuỳ thuộc vào logic cần chạy trên máy chủ web của Tìm kiếm. Hiện tại, không có cách nào để trình chạy dịch vụ sao chép logic này và trả về HTML được lưu vào bộ nhớ đệm ngay lập tức. Cách tốt nhất mà trình chạy dịch vụ có thể làm là truyền các yêu cầu điều hướng đến máy chủ web phụ trợ, điều này đòi hỏi phải có một yêu cầu mạng.

Nếu không có worker dịch vụ, yêu cầu mạng này sẽ xảy ra ngay khi người dùng điều hướng. Khi được đăng ký, service worker luôn cần được khởi động và có cơ hội thực thi trình xử lý sự kiện fetch, ngay cả khi không có cơ hội để các trình xử lý tìm nạp đó làm bất cứ điều gì khác ngoài việc truy cập vào mạng. Khoảng thời gian cần thiết để khởi động và chạy mã của worker dịch vụ là mức hao tổn thuần tuý được thêm vào trên mỗi thao tác điều hướng:

Hình minh hoạ về việc SW khởi động chặn yêu cầu điều hướng.

Điều này khiến việc triển khai worker dịch vụ gặp quá nhiều bất lợi về độ trễ để biện minh cho bất kỳ lợi ích nào khác. Ngoài ra, nhóm này nhận thấy rằng, dựa trên việc đo thời gian khởi động trình chạy dịch vụ trên các thiết bị thực tế, có sự phân phối rộng rãi về thời gian khởi động, với một số thiết bị di động cấp thấp mất gần như nhiều thời gian để khởi động trình chạy dịch vụ như thời gian cần thiết để thực hiện yêu cầu mạng cho HTML của trang kết quả.

Giải pháp: sử dụng tính năng tải trước điều hướng

Tính năng duy nhất và quan trọng nhất cho phép nhóm Google Tìm kiếm tiến hành ra mắt service worker là tính năng tải trước điều hướng. Việc sử dụng tính năng tải trước điều hướng là một điểm cải thiện hiệu suất quan trọng đối với mọi worker dịch vụ cần sử dụng phản hồi từ mạng để đáp ứng các yêu cầu điều hướng. Thao tác này cung cấp một gợi ý cho trình duyệt để bắt đầu thực hiện yêu cầu điều hướng ngay lập tức, cùng lúc với khi service worker khởi động:

Hình minh hoạ về quá trình khởi động SW được thực hiện song song với yêu cầu điều hướng.

Miễn là khoảng thời gian cần thiết để trình chạy dịch vụ khởi động nhỏ hơn khoảng thời gian cần thiết để nhận được phản hồi từ mạng, thì trình chạy dịch vụ sẽ không gây ra bất kỳ độ trễ nào.

Nhóm Tìm kiếm cũng cần tránh sử dụng service worker trên các thiết bị di động cấp thấp, nơi thời gian khởi động service worker có thể vượt quá yêu cầu điều hướng. Vì không có quy tắc cụ thể nào về những gì tạo nên một thiết bị "cấp thấp", nên họ đã đưa ra phương pháp phỏng đoán là kiểm tra tổng bộ nhớ truy cập ngẫu nhiên (RAM) được cài đặt trên thiết bị. Mọi thiết bị có bộ nhớ dưới 2 gigabyte đều thuộc danh mục thiết bị cấp thấp, trong đó thời gian khởi động worker dịch vụ sẽ không được chấp nhận.

Dung lượng lưu trữ còn trống là một yếu tố khác cần cân nhắc, vì toàn bộ tập hợp tài nguyên cần lưu vào bộ nhớ đệm để sử dụng sau này có thể lên đến vài megabyte. Giao diện navigator.storage cho phép trang Google Tìm kiếm biết trước liệu các nỗ lực lưu dữ liệu vào bộ nhớ đệm có nguy cơ thất bại do hạn ngạch lưu trữ không đủ hay không.

Điều này giúp nhóm Tìm kiếm có nhiều tiêu chí để xác định xem có nên sử dụng một worker dịch vụ hay không: nếu người dùng truy cập vào trang Google Tìm kiếm bằng một trình duyệt hỗ trợ tính năng tải trước điều hướng, có ít nhất 2 gigabyte RAM và đủ dung lượng lưu trữ trống, thì một worker dịch vụ sẽ được đăng ký. Những trình duyệt hoặc thiết bị không đáp ứng tiêu chí đó sẽ không có trình chạy dịch vụ, nhưng vẫn sẽ thấy trải nghiệm Google Tìm kiếm như trước đây.

Một lợi ích phụ của việc đăng ký có chọn lọc này là khả năng vận chuyển một trình thực thi dịch vụ nhỏ hơn và hiệu quả hơn. Việc nhắm đến các trình duyệt khá hiện đại để chạy mã trình chạy dịch vụ sẽ loại bỏ chi phí chung của việc chuyển đổi và polyfill cho các trình duyệt cũ. Điều này giúp giảm khoảng 8 kilobyte mã JavaScript chưa nén khỏi tổng kích thước của việc triển khai worker dịch vụ.

Vấn đề: phạm vi của trình chạy dịch vụ

Sau khi nhóm Tìm kiếm chạy đủ các thử nghiệm về độ trễ và tin rằng việc sử dụng tính năng tải trước điều hướng mang đến cho họ một cách thức khả thi, không có độ trễ để sử dụng một trình chạy dịch vụ, một số vấn đề thực tế bắt đầu nổi lên. Một trong những vấn đề đó liên quan đến quy tắc về phạm vi của worker dịch vụ. Phạm vi của trình chạy dịch vụ xác định những trang mà trình chạy dịch vụ có thể kiểm soát.

Phạm vi hoạt động dựa trên tiền tố đường dẫn URL. Đối với những miền lưu trữ một ứng dụng web duy nhất, đây không phải là vấn đề, vì bạn thường chỉ sử dụng một trình chạy dịch vụ có phạm vi tối đa là /, có thể kiểm soát mọi trang trong miền. Tuy nhiên, cấu trúc URL của Google Tìm kiếm phức tạp hơn một chút.

Nếu được cấp phạm vi tối đa là /, trình chạy dịch vụ sẽ có thể kiểm soát mọi trang được lưu trữ trong www.google.com (hoặc phạm vi tương đương theo khu vực) và có những URL trong miền đó không liên quan gì đến Google Tìm kiếm. Phạm vi hạn chế hợp lý hơn sẽ là /search, ít nhất là sẽ loại bỏ hoàn toàn những URL không liên quan đến kết quả tìm kiếm.

Rất tiếc, ngay cả đường dẫn URL /search đó cũng được chia sẻ giữa các loại kết quả trên Google Tìm kiếm, trong đó các tham số truy vấn URL sẽ xác định loại kết quả tìm kiếm cụ thể được hiển thị. Một số phiên bản sử dụng cơ sở mã hoàn toàn khác so với trang kết quả tìm kiếm truyền thống trên web. Ví dụ: Tìm kiếm hình ảnh và Tìm kiếm mua sắm đều được phân phát trong đường dẫn URL /search với các tham số truy vấn khác nhau, nhưng cả hai giao diện đó đều chưa sẵn sàng cung cấp trải nghiệm trình chạy dịch vụ riêng (tại thời điểm đó).

Giải pháp: tạo một khung điều phối và định tuyến

Mặc dù có một số đề xuất cho phép sử dụng một phương thức mạnh mẽ hơn tiền tố đường dẫn URL để xác định phạm vi của trình chạy dịch vụ, nhưng nhóm Google Tìm kiếm đã gặp khó khăn khi triển khai một trình chạy dịch vụ không làm gì cho một nhóm trang mà trình chạy đó kiểm soát.

Để giải quyết vấn đề này, nhóm Google Tìm kiếm đã xây dựng một khung điều phối và định tuyến riêng biệt có thể được định cấu hình để kiểm tra các tiêu chí như tham số truy vấn của trang ứng dụng và sử dụng các tiêu chí đó để xác định đường dẫn mã cụ thể cần thực hiện. Thay vì mã hoá cứng các quy tắc, hệ thống được xây dựng để linh hoạt và cho phép các nhóm chia sẻ không gian URL (chẳng hạn như Tìm kiếm hình ảnh và Tìm kiếm mua sắm) giảm logic của trình chạy dịch vụ của riêng họ xuống dòng, nếu họ quyết định triển khai logic đó.

Vấn đề: kết quả và chỉ số được cá nhân hoá

Người dùng có thể đăng nhập vào Google Tìm kiếm bằng Tài khoản Google của họ và trải nghiệm kết quả tìm kiếm của họ có thể được tuỳ chỉnh dựa trên dữ liệu tài khoản cụ thể của họ. Người dùng đã đăng nhập được xác định bằng cookie trình duyệt cụ thể, đây là một tiêu chuẩn đáng tin cậy và được hỗ trợ rộng rãi.

Tuy nhiên, một nhược điểm của việc sử dụng cookie trình duyệt là chúng không được hiển thị bên trong một trình chạy dịch vụ và không có cách nào để tự động kiểm tra các giá trị của chúng và đảm bảo rằng chúng không thay đổi do người dùng đăng xuất hoặc chuyển đổi tài khoản. (Hiện tại, chúng tôi đang nỗ lực cung cấp quyền truy cập cookie cho các worker dịch vụ, nhưng tại thời điểm viết bài này, phương pháp này vẫn đang trong giai đoạn thử nghiệm và chưa được hỗ trợ rộng rãi.)

Sự không khớp giữa chế độ xem của worker dịch vụ về người dùng hiện đang đăng nhập và người dùng thực tế đã đăng nhập vào giao diện web của Google Tìm kiếm có thể dẫn đến kết quả tìm kiếm được cá nhân hoá không chính xác hoặc số liệu và nhật ký bị gán sai. Bất kỳ trường hợp nào trong số những trường hợp thất bại đó đều là một vấn đề nghiêm trọng đối với nhóm Google Tìm kiếm.

Giải pháp: gửi cookie bằng postMessage

Thay vì chờ các API thử nghiệm ra mắt và cung cấp quyền truy cập trực tiếp vào cookie của trình duyệt trong một worker dịch vụ, nhóm Google Tìm kiếm đã chọn một giải pháp tạm thời: bất cứ khi nào một trang do worker dịch vụ kiểm soát được tải, trang đó sẽ đọc các cookie có liên quan và sử dụng postMessage() để gửi các cookie đó đến worker dịch vụ.

Sau đó, service worker sẽ kiểm tra giá trị cookie hiện tại với giá trị mà nó mong đợi. Nếu có sự không khớp, service worker sẽ thực hiện các bước để xoá mọi dữ liệu dành riêng cho người dùng khỏi bộ nhớ của mình và tải lại trang kết quả tìm kiếm mà không có bất kỳ hoạt động cá nhân hoá không chính xác nào.

Các bước cụ thể mà worker dịch vụ thực hiện để đặt lại mọi thứ về trạng thái ban đầu là theo yêu cầu của Google Tìm kiếm, nhưng phương pháp chung tương tự có thể hữu ích cho những nhà phát triển khác xử lý dữ liệu được cá nhân hoá dựa trên cookie của trình duyệt.

Vấn đề: thử nghiệm và tính linh động

Như đã đề cập, nhóm Google Tìm kiếm rất chú trọng việc chạy các thử nghiệm trong quá trình sản xuất và kiểm tra tác động của mã và tính năng mới trong thực tế trước khi bật chúng theo mặc định. Đây có thể là một thách thức đối với service worker tĩnh dựa nhiều vào dữ liệu được lưu vào bộ nhớ đệm, vì việc chọn tham gia và không tham gia thử nghiệm của người dùng thường yêu cầu giao tiếp với máy chủ phụ trợ.

Giải pháp: tập lệnh trình chạy dịch vụ được tạo động

Giải pháp mà nhóm đã chọn là sử dụng một tập lệnh worker dịch vụ được tạo động, do máy chủ web tuỳ chỉnh cho từng người dùng riêng lẻ, thay vì một tập lệnh worker dịch vụ tĩnh duy nhất được tạo trước. Thông tin về các thử nghiệm có thể ảnh hưởng đến hành vi của worker dịch vụ hoặc các yêu cầu mạng nói chung được đưa trực tiếp vào các tập lệnh worker dịch vụ tuỳ chỉnh này. Việc thay đổi các nhóm trải nghiệm đang hoạt động cho người dùng được thực hiện thông qua sự kết hợp giữa các kỹ thuật truyền thống (chẳng hạn như cookie của trình duyệt) cũng như việc phân phát mã đã cập nhật trong URL của trình chạy dịch vụ đã đăng ký.

Việc sử dụng một tập lệnh trình chạy dịch vụ được tạo động cũng giúp bạn dễ dàng cung cấp một lối thoát trong trường hợp không mong muốn là quá trình triển khai trình chạy dịch vụ có một lỗi nghiêm trọng cần phải tránh. Phản hồi của worker động trên máy chủ có thể là một triển khai không hoạt động, vô hiệu hoá worker dịch vụ cho một số hoặc tất cả người dùng hiện tại một cách hiệu quả.

Vấn đề: phối hợp cập nhật

Một trong những thách thức khó khăn nhất mà mọi hoạt động triển khai worker dịch vụ trong thế giới thực phải đối mặt là đưa ra một sự thoả hiệp hợp lý giữa việc tránh mạng để chuyển sang bộ nhớ đệm, đồng thời đảm bảo rằng người dùng hiện tại nhận được các bản cập nhật và thay đổi quan trọng ngay sau khi các bản cập nhật và thay đổi đó được triển khai cho bản phát hành công khai. Sự cân bằng phù hợp phụ thuộc vào nhiều yếu tố:

  • Ứng dụng web của bạn có phải là một ứng dụng một trang tồn tại lâu dài mà người dùng luôn mở vô thời hạn mà không chuyển đến các trang mới hay không.
  • Tần suất triển khai các bản cập nhật cho máy chủ web phụ trợ.
  • Liệu người dùng trung bình có chấp nhận sử dụng phiên bản hơi cũ của ứng dụng web hay không, hoặc liệu tính mới mẻ có phải là ưu tiên hàng đầu hay không.

Trong khi thử nghiệm với các worker dịch vụ, nhóm Google Tìm kiếm đã đảm bảo rằng các thử nghiệm vẫn chạy trong một số bản cập nhật phụ trợ theo lịch trình, để đảm bảo rằng các chỉ số và trải nghiệm người dùng sẽ phù hợp hơn với những gì người dùng quay lại sẽ thấy trong thực tế.

Giải pháp: cân bằng độ mới và mức sử dụng bộ nhớ đệm

Sau khi thử nghiệm một số lựa chọn cấu hình khác nhau, nhóm Google Tìm kiếm nhận thấy rằng chế độ thiết lập sau đây mang lại sự cân bằng phù hợp giữa tính mới mẻ và việc sử dụng bộ nhớ đệm.

URL tập lệnh của worker dịch vụ được phân phát bằng tiêu đề phản hồi Cache-Control: private, max-age=1500 (1500 giây hoặc 25 phút) và được đăng ký với updateViaCache được đặt thành "all" để đảm bảo tiêu đề được tuân thủ. Như bạn có thể tưởng tượng, phần phụ trợ web của Google Tìm kiếm là một tập hợp lớn các máy chủ được phân phối trên toàn cầu và yêu cầu thời gian hoạt động gần như 100%. Việc triển khai một thay đổi ảnh hưởng đến nội dung của tập lệnh worker dịch vụ được thực hiện theo cách thức cuốn chiếu.

Nếu người dùng truy cập vào một phần phụ trợ đã được cập nhật, rồi nhanh chóng chuyển đến một trang khác truy cập vào một phần phụ trợ chưa nhận được trình chạy dịch vụ đã cập nhật, thì họ sẽ liên tục chuyển đổi giữa các phiên bản nhiều lần. Do đó, việc yêu cầu trình duyệt chỉ kiểm tra một tập lệnh đã cập nhật nếu 25 phút đã trôi qua kể từ lần kiểm tra gần nhất không có nhược điểm đáng kể. Lợi ích của việc chọn sử dụng hành vi này là giảm đáng kể lưu lượng truy cập mà điểm cuối nhận được. Điểm cuối này sẽ tự động tạo tập lệnh worker dịch vụ.

Ngoài ra, tiêu đề ETag được đặt trên phản hồi HTTP của tập lệnh trình chạy dịch vụ, đảm bảo rằng khi một quy trình kiểm tra bản cập nhật được thực hiện sau 25 phút, máy chủ có thể phản hồi hiệu quả bằng phản hồi HTTP 304 nếu không có bản cập nhật nào cho trình chạy dịch vụ được triển khai trong thời gian chờ.

Mặc dù một số hoạt động tương tác trong ứng dụng web Google Tìm kiếm sử dụng chế độ điều hướng theo kiểu ứng dụng một trang (tức là thông qua API Lịch sử), nhưng phần lớn Google Tìm kiếm là một ứng dụng web truyền thống sử dụng chế độ điều hướng "thực". Điều này có hiệu quả khi nhóm quyết định rằng việc sử dụng 2 lựa chọn giúp tăng tốc vòng đời cập nhật của worker dịch vụ sẽ hiệu quả: clients.claim()skipWaiting(). Việc nhấp vào giao diện của Google Tìm kiếm thường dẫn đến việc chuyển đến các tài liệu HTML mới. Việc gọi skipWaiting đảm bảo rằng một service worker đã cập nhật sẽ có cơ hội xử lý những yêu cầu điều hướng mới đó ngay sau khi cài đặt. Tương tự, việc gọi clients.claim() có nghĩa là service worker đã cập nhật sẽ có cơ hội bắt đầu kiểm soát mọi trang Google Tìm kiếm đang mở không được kiểm soát, sau khi service worker được kích hoạt.

Phương pháp mà Google Tìm kiếm đã chọn không nhất thiết là giải pháp phù hợp với tất cả mọi người. Đó là kết quả của quá trình thử nghiệm A/B cẩn thận nhiều kiểu kết hợp các lựa chọn phân phát cho đến khi họ tìm thấy kiểu kết hợp phù hợp nhất với mình. Những nhà phát triển có cơ sở hạ tầng phụ trợ cho phép họ triển khai các bản cập nhật nhanh hơn có thể muốn trình duyệt kiểm tra tập lệnh trình chạy dịch vụ đã cập nhật thường xuyên nhất có thể bằng cách luôn bỏ qua bộ nhớ đệm HTTP. Nếu bạn đang tạo một ứng dụng một trang mà người dùng có thể giữ mở trong một khoảng thời gian dài, thì có lẽ việc sử dụng skipWaiting() không phải là lựa chọn phù hợp với bạn – bạn có nguy cơ gặp phải tình trạng không nhất quán về bộ nhớ đệm nếu cho phép trình chạy dịch vụ mới kích hoạt trong khi có các ứng dụng khách hoạt động trong thời gian dài.

Những điểm chính cần ghi nhớ

Theo mặc định, trình chạy dịch vụ không có hiệu suất trung tính

Việc thêm một trình chạy dịch vụ vào ứng dụng web của bạn có nghĩa là bạn sẽ chèn thêm một đoạn JavaScript cần được tải và thực thi trước khi ứng dụng web của bạn nhận được các phản hồi cho yêu cầu của ứng dụng. Nếu những phản hồi đó đến từ bộ nhớ đệm cục bộ thay vì từ mạng, thì chi phí hoạt động của worker dịch vụ thường không đáng kể so với hiệu suất đạt được khi sử dụng bộ nhớ đệm trước. Nhưng nếu bạn biết rằng trình chạy dịch vụ của bạn luôn phải tham khảo mạng khi xử lý các yêu cầu điều hướng, thì việc sử dụng tính năng tải trước điều hướng là một lợi thế quan trọng về hiệu suất.

Service worker (vẫn!) là một tính năng nâng cao tăng dần

Câu chuyện về việc hỗ trợ service worker hiện nay tươi sáng hơn nhiều so với một năm trước. Hiện tại, tất cả trình duyệt hiện đại đều có ít nhất một số hỗ trợ cho service worker, nhưng rất tiếc là có một số tính năng nâng cao của service worker (chẳng hạn như đồng bộ hoá trong nền và tải trước điều hướng) chưa được triển khai trên toàn cầu. Kiểm tra tính năng cho một nhóm nhỏ cụ thể gồm các tính năng mà bạn biết mình cần và chỉ đăng ký một worker dịch vụ khi các tính năng đó xuất hiện vẫn là một cách tiếp cận hợp lý.

Tương tự, nếu đã chạy các thử nghiệm trong thực tế và biết rằng các thiết bị cấp thấp hoạt động kém hiệu quả do có thêm chi phí của một worker dịch vụ, thì bạn cũng có thể không đăng ký worker dịch vụ trong những trường hợp đó.

Bạn nên tiếp tục coi các worker dịch vụ là một nâng cao tiến bộ được thêm vào một ứng dụng web khi đáp ứng tất cả các điều kiện tiên quyết và worker dịch vụ mang lại điều gì đó tích cực cho trải nghiệm người dùng và hiệu suất tải tổng thể.

Đo lường mọi thứ

Cách duy nhất để biết liệu việc vận chuyển một worker dịch vụ có tác động tích cực hay tiêu cực đến trải nghiệm của người dùng là thử nghiệm và đo lường kết quả.

Thông tin cụ thể về việc thiết lập các phép đo có ý nghĩa phụ thuộc vào nhà cung cấp dịch vụ phân tích mà bạn đang sử dụng và cách bạn thường tiến hành thử nghiệm trong chế độ thiết lập triển khai. Một phương pháp sử dụng Google Analytics để thu thập chỉ số được trình bày chi tiết trong nghiên cứu điển hình này dựa trên trải nghiệm sử dụng service worker trong ứng dụng web Google I/O.

Không phải bàn thắng

Mặc dù nhiều người trong cộng đồng phát triển web liên kết trình chạy dịch vụ với Ứng dụng web tiến bộ, nhưng việc tạo "PWA của Google Tìm kiếm" không phải là mục tiêu ban đầu của nhóm. Ứng dụng web Google Tìm kiếm không cung cấp siêu dữ liệu trong tệp kê khai ứng dụng web, cũng như không khuyến khích người dùng thực hiện quy trình Thêm vào màn hình chính. Nhóm Tìm kiếm hài lòng với những người dùng truy cập vào ứng dụng web của họ bằng các điểm truy cập cổ điển cho Google Tìm kiếm.

Thay vì cố gắng biến trải nghiệm trên web của Google Tìm kiếm thành trải nghiệm tương đương với những gì bạn mong đợi ở một ứng dụng đã cài đặt, trọng tâm của bản phát hành ban đầu là cải thiện dần trang web hiện có.

Lời cảm ơn

Cảm ơn toàn bộ nhóm phát triển web của Google Tìm kiếm vì đã triển khai trình chạy dịch vụ và chia sẻ tài liệu cơ bản để viết bài này. Xin chân thành cảm ơn Philippe Golle, Rajesh Jagannathan, R. Samuel Klatchko, Andy Martone, Leonardo Peña, Rachel Shearer, Greg Terrono và Clay Woolam.

Nội dung cập nhật (tháng 10 năm 2021): Kể từ khi bài viết này được xuất bản lần đầu, nhóm Google Tìm kiếm đã đánh giá lại những lợi ích và hạn chế của cấu trúc worker dịch vụ hiện tại. Trình chạy dịch vụ được mô tả ở trên sẽ ngừng hoạt động. Khi cơ sở hạ tầng web của Google Tìm kiếm phát triển, nhóm có thể xem xét lại thiết kế trình chạy dịch vụ của họ.