Ứng dụng web tiến bộ đầu tiên của bạn

Lần cập nhật gần đây nhất: Ngày 30 tháng 4 năm 2019

Điều gì tạo nên ứng dụng web, Ứng dụng web tiến bộ?

Ứng dụng web tiến bộ cung cấp trải nghiệm giống như ứng dụng, có thể cài đặt trên máy tính và thiết bị di động được xây dựng và phân phối trực tiếp qua web. Chúng là ứng dụng web nhanh và đáng tin cậy. Và quan trọng nhất, đó là các ứng dụng web hoạt động trên bất kỳ trình duyệt nào. Nếu bạn đang xây dựng một ứng dụng web ngày hôm nay, thì bạn đang trên con đường xây dựng Ứng dụng web tiến bộ.

Nhanh chóng và đáng tin cậy

Mọi trải nghiệm web đều phải nhanh và điều này đặc biệt đúng với Ứng dụng web tiến bộ. Nhanh là thời gian cần để có nội dung có ý nghĩa trên màn hình và cung cấp trải nghiệm tương tác.

Và nó phải nhanh chóng đáng tin cậy. Khó có thể biết được hiệu suất đáng tin cậy ở mức nào. Hãy suy nghĩ theo cách này: lần tải ứng dụng gốc đầu tiên thật khó chịu. Nó được kiểm soát bởi một cửa hàng ứng dụng và số lượt tải xuống lớn, nhưng khi bạn đến một nơi đã cài đặt ứng dụng, chi phí trả trước đó được phân bổ cho tất cả các lần khởi động ứng dụng và không có sự kiện nào trong số đó bắt đầu có độ trễ biến đổi. Mỗi lần khởi động ứng dụng đều nhanh như cuối cùng, không có sự khác biệt. Ứng dụng web tiến bộ phải mang lại hiệu suất đáng tin cậy mà người dùng có thể mong đợi từ mọi trải nghiệm đã cài đặt.

Có thể cài đặt

Ứng dụng web tiến bộ có thể chạy trong một thẻ trình duyệt nhưng cũng có thể cài đặt. Việc đánh dấu trang web chỉ thêm một lối tắt, nhưng Ứng dụng web tiến bộ (PWA) đã cài đặt sẽ trông và hoạt động giống như tất cả các ứng dụng đã cài đặt khác. Dịch vụ này khởi chạy từ cùng nơi với các ứng dụng khác. Bạn có thể kiểm soát trải nghiệm phát hành, bao gồm màn hình chờ, biểu tượng và các nội dung khác được tùy chỉnh. Quảng cáo này chạy dưới dạng một ứng dụng, trong một cửa sổ ứng dụng mà không có thanh địa chỉ hoặc một giao diện người dùng khác của trình duyệt. Giống như tất cả những ứng dụng khác đã cài đặt, đây là ứng dụng cấp cao nhất trong trình chuyển đổi việc cần làm.

Hãy nhớ rằng điều quan trọng là PWA có thể cài đặt phải nhanh và ổn định. Người dùng cài đặt PWA mong muốn rằng ứng dụng của họ hoạt động, bất kể họ đang sử dụng loại kết nối mạng nào. Đây là kỳ vọng cơ bản mà mọi ứng dụng đã cài đặt phải đáp ứng.

Mobile & Máy tính

Bằng cách sử dụng các kỹ thuật thiết kế thích ứng, PWA hoạt động trên cả thiết bị di động máy tính, đồng thời sử dụng một cơ sở mã duy nhất giữa các nền tảng. Nếu bạn đang cân nhắc viết một ứng dụng gốc, hãy xem những lợi ích mà PWA cung cấp.

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ xây dựng một ứng dụng thời tiết trên web bằng cách sử dụng các kỹ thuật của PWA. Ứng dụng này sẽ:

  • Hãy sử dụng thiết kế thích ứng để thiết bị này hoạt động trên máy tính hoặc thiết bị di động.
  • Nhanh, sử dụng trình chạy dịch vụ để lưu trước các tài nguyên ứng dụng (HTML, CSS, JavaScript, hình ảnh) cần để chạy và lưu vào bộ nhớ đệm dữ liệu thời tiết vào thời gian chạy để cải thiện hiệu suất.
  • Có thể cài đặt bằng cách sử dụng tệp kê khai ứng dụng web và sự kiện beforeinstallprompt để thông báo cho người dùng rằng ứng dụng có thể cài đặt.

Kiến thức bạn sẽ học được

  • Cách tạo và thêm tệp kê khai ứng dụng web
  • Cách cung cấp trải nghiệm ngoại tuyến đơn giản
  • Cách cung cấp trải nghiệm ngoại tuyến đầy đủ
  • Cách cài đặt ứng dụng của bạn

Lớp học lập trình này tập trung vào Ứng dụng web tiến bộ. Các khái niệm và khối mã không liên quan sẽ được tô bóng và được cung cấp để bạn chỉ cần sao chép và dán.

Bạn cần có

  • Phiên bản Chrome gần đây (phiên bản 74 trở lên). PWA hoạt động trong tất cả các trình duyệt, nhưng chúng tôi sẽ sử dụng một vài tính năng của Công cụ dành cho nhà phát triển Chrome để hiểu rõ hơn những gì đang xảy ra ở cấp trình duyệt và sử dụng tính năng đó để kiểm tra trải nghiệm cài đặt.
  • Kiến thức về HTML, CSS, JavaScript và Công cụ của Chrome cho nhà phát triển.

Nhận khoá dành cho API Sky Sky

Dữ liệu thời tiết của chúng tôi được lấy từ API Sky Sky. Để sử dụng khóa này, bạn cần yêu cầu khóa API. Dễ dàng sử dụng và miễn phí cho các dự án phi thương mại.

Đăng ký Khóa API

Xác minh rằng khóa API đang hoạt động đúng cách

Để kiểm tra xem Khóa API của bạn có đang hoạt động đúng cách hay không, hãy gửi một yêu cầu HTTP tới API DarkSky. Cập nhật URL dưới đây để thay thế DARKSKY_API_KEY bằng khóa API của bạn. Nếu mọi thứ hoạt động, bạn sẽ thấy dự báo thời tiết mới nhất tại Thành phố New York.

https://api.darksky.net/forecast/DARKSKY_API_KEY/40.7720232,-73.9732319

Lấy mã

Chúng tôi đã đặt mọi thứ bạn cần cho dự án này vào Git repo. Để bắt đầu, bạn cần lấy mã và mở mã đó trong môi trường nhà phát triển yêu thích của mình. Đối với lớp học lập trình này, bạn nên sử dụng Glail.

Nên dùng: Sử dụng tính năng Ghép nối để nhập kho lưu trữ

Bạn nên sử dụng Glrick để làm việc qua lớp học lập trình này.

  1. Mở một thẻ trình duyệt mới rồi truy cập vào https://glcab.com.
  2. Nếu bạn chưa có tài khoản, bạn sẽ cần đăng ký.
  3. Nhấp vào Dự án mới rồi nhấp vào Sao chép từ Git Repo.
  4. Sao chép https://github.com/googlecodelabs/your-first-pwapp.git rồi nhấp vào OK.
  5. Sau khi hệ thống tải lại, hãy chỉnh sửa tệp .env và cập nhật tệp đó bằng khóa API DarkSky của bạn.
  6. Nhấp vào nút Hiển thị, sau đó chọn Trong cửa sổ mới để xem PWA đang hoạt động.

Cách khác: Tải mã và amp; làm việc cục bộ

Nếu muốn tải mã xuống và làm việc tại địa phương, bạn cần có phiên bản Node.js và thiết lập trình soạn thảo mã gần đây và sẵn sàng hoạt động.

Tải mã nguồn xuống

  1. Giải nén tệp zip đã tải xuống.
  2. Hãy chạy npm install để cài đặt các phần phụ thuộc cần thiết để chạy máy chủ.
  3. Chỉnh sửa server.js và đặt khóa API DarkSky của bạn.
  4. Chạy node server.js để khởi động máy chủ trên cổng 8000.
  5. Mở thẻ trình duyệt để http://localhost:8000

Điểm khởi đầu của chúng tôi là gì?

Điểm xuất phát của chúng tôi là một ứng dụng thời tiết cơ bản được thiết kế cho lớp học lập trình này. Mã này đã được đơn giản hóa để hiển thị các khái niệm trong lớp học lập trình này và xử lý ít lỗi hơn. Nếu bạn chọn sử dụng lại bất kỳ mã nào trong ứng dụng đang được tạo, hãy nhớ xử lý mọi lỗi và kiểm tra đầy đủ tất cả mã.

Hãy thử một số nội dung sau...

  1. Thêm một thành phố mới với nút + màu xanh dương ở góc dưới cùng bên phải.
  2. Làm mới dữ liệu bằng nút làm mới ở góc trên bên phải.
  3. Xóa một thành phố bằng cách sử dụng dấu x ở phía trên bên phải của mỗi thẻ thành phố.
  4. Sử dụng thanh công cụ bật/tắt thiết bị trong Công cụ dành cho nhà phát triển của Chrome, xem cách công cụ này hoạt động trên máy tính để bàn và thiết bị di động.
  5. Sử dụng bảng điều khiển Mạng trong Công cụ của Chrome cho nhà phát triển để xem điều gì xảy ra khi bạn ngoại tuyến.
  6. Dùng bảng điều khiển Mạng trong Công cụ của Chrome cho nhà phát triển để xem điều gì sẽ xảy ra khi mạng bị điều tiết xuống mạng 3G chậm.
  7. Thêm độ trễ vào máy chủ dự báo bằng cách thay đổi giá trị cho FORECAST_DELAY trong server.js

Kiểm tra bằng Lighthouse

Lighthouse là một công cụ dễ sử dụng, giúp cải thiện chất lượng của các trang và trang web của bạn. Lighthouse chạy kiểm tra hiệu suất, khả năng truy cập, ứng dụng web tiến bộ và hơn thế nữa. Mỗi quá trình kiểm tra có một tài liệu tham khảo giải thích lý do quá trình kiểm tra quan trọng và cách khắc phục sự cố.

Chúng tôi sẽ sử dụng Lighthouse để kiểm tra ứng dụng Thời tiết và xác minh những thay đổi mà chúng tôi đã thực hiện.

Hãy chạy Lighthouse

  1. Mở dự án của bạn trong một thẻ mới.
  2. Mở Công cụ của Chrome cho nhà phát triển và chuyển sang bảng Kiểm tra. Bật tất cả các loại kiểm tra.
  3. Nhấp vào Chạy kiểm tra. Sau một thời gian, Lighthouse sẽ cung cấp cho bạn báo cáo trên trang.

Kiểm tra ứng dụng web tiến bộ

Chúng tôi sẽ tập trung vào kết quả của quá trình kiểm tra Ứng dụng web tiến bộ.

Và có rất nhiều màu đỏ để tập trung vào:

  • ❗FAILED: Trang hiện tại không trả về mã 200 khi không có mạng.
  • ❗FAILED: start_url không phản hồi bằng 200 khi không có mạng.
  • ❗FAILED: Không đăng ký một trình chạy dịch vụ kiểm soát trang và start_url.
  • ❗FAILED: Tệp kê khai ứng dụng web không đáp ứng các yêu cầu về khả năng cài đặt.
  • ❗FAILED: Chưa định cấu hình màn hình chờ tùy chỉnh.
  • ❗FAILED: Không đặt màu giao diện thanh địa chỉ.

Hãy cùng tìm hiểu một số vấn đề này và bắt đầu khắc phục nhé!

Khi kết thúc phần này, ứng dụng thời tiết sẽ vượt qua những bài kiểm tra sau:

  • Tệp kê khai ứng dụng web không đáp ứng các yêu cầu về khả năng cài đặt.
  • Chưa được định cấu hình cho màn hình chờ tùy chỉnh.
  • Không đặt màu giao diện của thanh địa chỉ.

Tạo tệp kê khai ứng dụng web

Tệp kê khai ứng dụng web là một tệp JSON đơn giản cho phép bạn (nhà phát triển) kiểm soát cách ứng dụng của bạn xuất hiện cho người dùng.

Khi sử dụng tệp kê khai ứng dụng web, ứng dụng web của bạn có thể:

  • Yêu cầu trình duyệt bạn muốn ứng dụng mở trong một cửa sổ độc lập (display).
  • Xác định trang nào sẽ mở khi ứng dụng được chạy lần đầu tiên (start_url).
  • Xác định hình thức của ứng dụng trên thanh Dock hoặc trình chạy ứng dụng (short_name, icons).
  • Tạo màn hình chờ (name, icons, colors).
  • Yêu cầu trình duyệt mở cửa sổ ở chế độ ngang hoặc chế độ dọc (orientation).
  • nhiều nội dung khác.

Tạo một tệp có tên public/manifest.json trong dự án của bạn. Sao chép và dán các nội dung sau:

public/manifest.json

{
  "name": "Weather",
  "short_name": "Weather",
  "icons": [{
    "src": "/images/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    }, {
      "src": "/images/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    }, {
      "src": "/images/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    }, {
      "src": "/images/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    }, {
      "src": "/images/icons/icon-256x256.png",
      "sizes": "256x256",
      "type": "image/png"
    }, {
      "src": "/images/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }],
  "start_url": "/index.html",
  "display": "standalone",
  "background_color": "#3E4EB8",
  "theme_color": "#2F3BA2"
}

Tệp kê khai hỗ trợ một loạt biểu tượng, dành cho các kích thước màn hình khác nhau. Đối với lớp học lập trình này, chúng tôi đã đưa một số tính năng khác vào việc tích hợp iOS.

Tiếp theo, chúng tôi cần thông báo cho trình duyệt về tệp kê khai của chúng tôi bằng cách thêm <link rel="manifest"... vào mỗi trang trong ứng dụng của chúng tôi. Thêm dòng sau vào phần tử <head> trong tệp index.html của bạn.

public/index.html

<!-- CODELAB: Add link rel manifest -->
<link rel="manifest" href="/manifest.json">

Đường vòng của Công cụ cho nhà phát triển

Công cụ cho nhà phát triển cung cấp một cách nhanh chóng, dễ dàng để kiểm tra tệp manifest.json của bạn. Mở ngăn Thao tác trên bảng điều khiển Ứng dụng. Nếu bạn thêm thông tin tệp kê khai một cách chính xác, bạn sẽ có thể thấy thông tin đó được phân tích cú pháp và hiển thị theo định dạng thân thiện với con người trên ngăn này.

Thêm thẻ meta &amp trên iOS; các biểu tượng

Safari trên iOS chưa hỗ trợ tệp kê khai ứng dụng web (chưa), vì vậy, bạn sẽ cần thêm thẻ meta truyền thống vào <head> của tệp index.html:

public/index.html

<!-- CODELAB: Add iOS meta tags and icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Weather PWA">
<link rel="apple-touch-icon" href="/images/icons/icon-152x152.png">

Điểm thưởng: Sửa lỗi Lighthouse dễ dàng

Bài kiểm tra của chúng tôi trên Lighthouse đã nêu ra một số vấn đề khá dễ khắc phục, vì vậy hãy xử lý những vấn đề đó khi chúng ta có mặt ở đây.

Đặt đoạn mô tả meta

Trong quá trình kiểm tra SEO, Lighthouse đã ghi lại "Tài liệu không có nội dung mô tả meta." Nội dung mô tả có thể hiển thị trong kết quả của Google Tìm kiếm. Nội dung mô tả chất lượng cao, độc đáo có thể giúp kết quả của bạn phù hợp hơn với người dùng tìm kiếm và có thể làm tăng lưu lượng truy cập tìm kiếm.

Để thêm mô tả, hãy thêm thẻ meta sau vào <head> của tài liệu:

public/index.html

<!-- CODELAB: Add description here -->
<meta name="description" content="A sample weather app">

Đặt màu giao diện trên thanh địa chỉ

Trong quá trình kiểm tra PWA, Lighthouse đã ghi lại ứng dụng của chúng tôi và Không đặt màu giao diện trên thanh địa chỉ" Việc tạo giao diện thanh địa chỉ phù hợp với màu sắc của thương hiệu sẽ mang lại trải nghiệm phong phú hơn cho người dùng.

Để đặt màu giao diện trên thiết bị di động, hãy thêm thẻ meta sau vào <head> của tài liệu:

public/index.html

<!-- CODELAB: Add meta theme-color -->
<meta name="theme-color" content="#2F3BA2" />

Xác minh các thay đổi bằng Lighthouse

Chạy lại Lighthouse (bằng cách nhấp vào dấu + ở góc trên bên trái của bảng Kiểm tra) và xác minh nội dung thay đổi của bạn.

Kiểm tra SEO

  • ✔ ĐÃ ĐẠT: Tài liệu có phần mô tả meta.

Kiểm tra ứng dụng web tiến bộ

  • ❗FAILED: Trang hiện tại không trả về mã 200 khi không có mạng.
  • ❗FAILED: start_url không phản hồi bằng 200 khi không có mạng.
  • ❗FAILED: Không đăng ký một trình chạy dịch vụ kiểm soát trang và start_url.
  • ✔ ĐÃ ĐẠT: Tệp kê khai ứng dụng web đáp ứng các yêu cầu về khả năng cài đặt.
  • ✔ ĐÃ ĐẠT: Được định cấu hình cho màn hình chờ tùy chỉnh.
  • ✔ ĐÃ ĐẠT: Đặt màu giao diện thanh địa chỉ.

Người dùng mong đợi rằng các ứng dụng đã cài đặt sẽ luôn có trải nghiệm cơ bản nếu họ không có kết nối mạng. Đó là lý do tại sao các ứng dụng web có thể cài đặt không bao giờ hiển thị trò chơi khủng long ngoại tuyến của Chrome. Trải nghiệm ngoại tuyến có thể từ một trang ngoại tuyến đơn giản, đến một trải nghiệm chỉ có thể đọc bằng dữ liệu lưu trong bộ nhớ đệm trước đó, cho đến một trải nghiệm ngoại tuyến hoạt động bình thường, tự động đồng bộ hóa khi kết nối mạng được khôi phục.

Trong phần này, chúng ta sẽ thêm một trang ngoại tuyến đơn giản vào ứng dụng thời tiết. Nếu người dùng cố gắng tải ứng dụng khi không có kết nối mạng, ứng dụng sẽ hiển thị trang tùy chỉnh của chúng ta, thay vì trang ngoại tuyến thông thường mà trình duyệt hiển thị. Khi kết thúc phần này, ứng dụng thời tiết sẽ vượt qua những bài kiểm tra sau:

  • Trang hiện tại không phản hồi bằng mã 200 khi không có kết nối mạng.
  • start_url không phản hồi bằng mã 200 khi không có kết nối mạng.
  • Không đăng ký một trình chạy dịch vụ kiểm soát trang và start_url.

Trong phần tiếp theo, chúng tôi sẽ thay thế trang tùy chỉnh ngoại tuyến của mình bằng trải nghiệm ngoại tuyến đầy đủ. Điều này sẽ giúp cải thiện trải nghiệm tại cửa hàng thực tế, nhưng quan trọng hơn là giúp cải thiện đáng kể hiệu suất của chúng tôi, vì hầu hết các tài sản của chúng tôi (HTML, CSS và JavaScript) đều sẽ được lưu trữ và phân phát tại địa phương, loại bỏ mạng như nút thắt cổ chai tiềm ẩn.

Nhân viên dịch vụ cứu hộ

Nếu không quen với nhân viên dịch vụ, bạn có thể hiểu kiến thức cơ bản về những việc họ có thể làm, cách vòng đời của họ hoạt động và nhiều thông tin khác bằng cách đọc Giới thiệu về Trình chạy dịch vụ.

Các tính năng được cung cấp qua trình chạy dịch vụ sẽ được xem là tính năng nâng cao cải tiến và chỉ được thêm vào nếu trình duyệt hỗ trợ. Ví dụ: với các trình chạy dịch vụ, bạn có thể lưu vào bộ nhớ đệm ứng dụng và dữ liệu vào ứng dụng của bạn để bộ nhớ này có sẵn ngay cả khi mạng không được hỗ trợ. Khi trình chạy dịch vụ không được hỗ trợ, mã ngoại tuyến sẽ không được gọi và người dùng sẽ có được trải nghiệm cơ bản. Việc sử dụng tính năng phát hiện tính năng để cung cấp tính năng nâng cao cải tiến có mức chi phí thấp và sẽ không làm hỏng các trình duyệt cũ không hỗ trợ tính năng đó.

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

Bước đầu tiên là đăng ký trình chạy dịch vụ. Thêm mã sau vào tệp index.html của bạn:

public/index.html

// CODELAB: Register service worker.
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
        .then((reg) => {
          console.log('Service worker registered.', reg);
        });
  });
}

Mã này sẽ kiểm tra để xem có API trình chạy dịch vụ hay không, và nếu có, thì trình chạy dịch vụ của /service-worker.js sẽ được đăng ký sau khi trang được tải.

Lưu ý rằng trình chạy dịch vụ được phân phát từ thư mục gốc, chứ không phải từ thư mục /scripts/. Đây là cách dễ nhất để đặt scope cho trình chạy dịch vụ. scope của trình chạy dịch vụ sẽ xác định tệp mà trình chạy dịch vụ kiểm soát, nói cách khác là từ đường dẫn mà trình chạy dịch vụ sẽ chặn các yêu cầu. scope mặc định là vị trí của tệp trình chạy dịch vụ và mở rộng tới tất cả các thư mục bên dưới. Vì vậy, nếu service-worker.js nằm trong thư mục gốc, thì trình chạy dịch vụ sẽ kiểm soát các yêu cầu từ tất cả trang web tại miền này.

Lưu trước trang ngoại tuyến

Trước tiên, chúng ta cần cho trình chạy dịch vụ biết nội dung cần lưu vào bộ nhớ đệm. Chúng tôi đã tạo một trang ngoại tuyến đơn giản (public/offline.html) mà chúng tôi sẽ hiển thị bất cứ lúc nào không có kết nối mạng.

Trong service-worker.js, hãy thêm '/offline.html', vào mảng FILES_TO_CACHE, kết quả cuối cùng sẽ trông như sau:

public/service-worker.js

// CODELAB: Add list of files to cache here.
const FILES_TO_CACHE = [
  '/offline.html',
];

Tiếp theo, chúng ta cần thêm mã sau vào sự kiện install để yêu cầu trình chạy dịch vụ lưu trước trang ngoại tuyến vào bộ nhớ đệm:

public/service-worker.js

// CODELAB: Precache static resources here.
evt.waitUntil(
    caches.open(CACHE_NAME).then((cache) => {
      console.log('[ServiceWorker] Pre-caching offline page');
      return cache.addAll(FILES_TO_CACHE);
    })
);

Sự kiện install của chúng ta sẽ mở bộ nhớ đệm cùng với caches.open() và cung cấp tên bộ nhớ đệm. Việc cung cấp tên bộ nhớ đệm cho phép chúng tôi tạo phiên bản cho các tệp hoặc tách dữ liệu khỏi các tài nguyên được lưu trong bộ nhớ đệm để chúng tôi có thể dễ dàng cập nhật tệp này nhưng không ảnh hưởng đến tệp khác.

Sau khi bộ nhớ đệm mở, chúng ta có thể gọi cache.addAll(), phiên bản này sẽ lấy danh sách các URL, tìm nạp từ máy chủ và thêm phản hồi vào bộ nhớ đệm. Lưu ý rằng cache.addAll() không thành công nếu bất kỳ yêu cầu riêng lẻ nào không thành công. Điều đó có nghĩa là bạn đảm bảo rằng nếu bước cài đặt thành công, bộ nhớ đệm sẽ ở trạng thái nhất quán. Tuy nhiên, nếu không sao chép được, hệ thống sẽ tự động thử lại vào lần tới khi trình chạy dịch vụ khởi động.

Đường vòng của Công cụ cho nhà phát triển

Hãy xem cách bạn có thể sử dụng Công cụ cho nhà phát triển để hiểu và gỡ lỗi trình chạy dịch vụ. Trước khi tải lại trang, hãy mở Công cụ cho nhà phát triển, rồi chuyển đến ngăn Trình chạy dịch vụ trên bảng Ứng dụng. Phần khai báo sẽ có dạng như sau:

Khi bạn thấy một trang trống như thế này, điều đó có nghĩa là trang hiện đang mở không có bất kỳ trình chạy dịch vụ nào đã đăng ký.

Bây giờ, hãy tải lại trang của bạn. Ngăn Công nhân dịch vụ giờ đây sẽ có dạng như sau:

Khi bạn thấy thông tin như thế này, có nghĩa là trang có trình chạy dịch vụ đang chạy.

Bên cạnh nhãn Trạng thái, có một số (34251 trong trường hợp này). Hãy chú ý đến số điện thoại đó khi bạn đang làm việc với nhân viên dịch vụ. Đây là cách dễ dàng để biết liệu nhân viên dịch vụ của bạn đã được cập nhật hay chưa.

Dọn dẹp các trang ngoại tuyến cũ

Chúng tôi sẽ dùng sự kiện activate để dọn dẹp mọi dữ liệu cũ trong bộ nhớ đệm. Mã này đảm bảo rằng trình chạy dịch vụ của bạn sẽ cập nhật bộ nhớ đệm mỗi khi có bất kỳ tệp giao diện ứng dụng nào thay đổi. Để tính năng này hoạt động, bạn cần tăng biến CACHE_NAME ở đầu tệp trình chạy dịch vụ.

Thêm mã sau vào sự kiện activate của bạn:

public/service-worker.js

// CODELAB: Remove previous cached data from disk.
evt.waitUntil(
    caches.keys().then((keyList) => {
      return Promise.all(keyList.map((key) => {
        if (key !== CACHE_NAME) {
          console.log('[ServiceWorker] Removing old cache', key);
          return caches.delete(key);
        }
      }));
    })
);

Đường vòng của Công cụ cho nhà phát triển

Khi ngăn Trình chạy dịch vụ mở, hãy làm mới trang. Bạn sẽ thấy trình chạy dịch vụ mới được cài đặt và số trạng thái tăng lên.

Trình chạy dịch vụ đã cập nhật sẽ kiểm soát ngay lập tức vì sự kiện install của chúng ta sẽ kết thúc bằng self.skipWaiting(), và sự kiện activate sẽ kết thúc bằng self.clients.claim(). Nếu không có những trình chạy này, trình chạy dịch vụ cũ sẽ tiếp tục kiểm soát trang miễn là có thẻ đang mở cho trang đó.

Xử lý các yêu cầu mạng không thành công

Cuối cùng, chúng ta cần xử lý các sự kiện fetch. Chúng tôi sẽ sử dụng chiến lược Mạng quay lại lưu vào bộ nhớ đệm. Trước tiên, trình chạy dịch vụ sẽ cố gắng tìm nạp tài nguyên từ mạng. Nếu không được, trình chạy dịch vụ sẽ trả về trang ngoại tuyến từ bộ nhớ đệm.

public/service-worker.js

// CODELAB: Add fetch event handler here.
if (evt.request.mode !== 'navigate') {
  // Not a page navigation, bail.
  return;
}
evt.respondWith(
    fetch(evt.request)
        .catch(() => {
          return caches.open(CACHE_NAME)
              .then((cache) => {
                return cache.match('offline.html');
              });
        })
);

Trình xử lý fetch chỉ cần xử lý các thao tác di chuyển trên trang, do đó, các yêu cầu khác có thể được đóng khỏi trình xử lý và được trình duyệt xử lý bình thường. Tuy nhiên, nếu yêu cầu .modenavigate, hãy dùng fetch để cố gắng lấy mục đó từ mạng. Nếu không thành công, trình xử lý catch sẽ mở bộ nhớ đệm bằng caches.open(CACHE_NAME) và sử dụng cache.match('offline.html') để tải trang ngoại tuyến đã lưu trước trong bộ nhớ đệm. Sau đó, kết quả được chuyển trở lại trình duyệt bằng evt.respondWith().

Đường vòng của Công cụ cho nhà phát triển

Hãy kiểm tra để đảm bảo mọi thứ hoạt động như mong đợi. Khi ngăn Nhân viên dịch vụ mở ra, hãy làm mới trang. Bạn sẽ thấy trình chạy dịch vụ mới được cài đặt và số trạng thái tăng lên.

Chúng tôi cũng có thể kiểm tra xem nội dung nào được lưu vào bộ nhớ đệm. Chuyển đến ngăn Bộ nhớ đệm trên bảng điều khiển Ứng dụng của Công cụ cho nhà phát triển. Nhấp chuột phải vào Bộ nhớ đệm, chọn Làm mới bộ nhớ đệm và mở rộng phần. Bạn sẽ thấy tên bộ nhớ đệm tĩnh ở bên trái. Nhấp vào tên bộ nhớ đệm để xem tất cả các tệp đã lưu vào bộ nhớ đệm.

Bây giờ, hãy thử chế độ ngoại tuyến. Quay lại ngăn WorkWorker trong bảng điều khiển Application của Công cụ cho nhà phát triển và chọn hộp đánh dấu Offline. Sau khi kiểm tra, bạn sẽ thấy một biểu tượng cảnh báo nhỏ màu vàng bên cạnh thẻ bảng điều khiển Mạng. Biểu tượng này cho biết bạn đang ngoại tuyến.

Tải lại trang của bạn và... trang này hoạt động! Chúng tôi nhận được gấu trúc ngoại tuyến của chúng tôi, thay vì trò chơi khủng long ngoại tuyến của Chrome!

Mẹo dành cho trình chạy dịch vụ thử nghiệm

Gỡ lỗi dịch vụ dịch vụ có thể là một thách thức, và khi việc này liên quan đến việc lưu vào bộ nhớ đệm, mọi thứ thậm chí có thể trở thành một cơn ác mộng hơn nếu bộ nhớ đệm không được cập nhật khi bạn mong đợi. Giữa vòng đời của trình chạy dịch vụ thông thường và lỗi trong mã, bạn có thể nhanh chóng thấy khó chịu. Tuy nhiên, không cần chia sẻ.

Sử dụng Công cụ cho nhà phát triển

Trong ngăn Nhân viên dịch vụ của bảng Ứng dụng, có một vài hộp đánh dấu sẽ giúp bạn làm việc dễ dàng hơn nhiều.

  • Ngoại tuyến – Khi được đánh dấu, mô phỏng một trải nghiệm ngoại tuyến và ngăn mọi yêu cầu truy cập vào mạng.
  • Cập nhật khi tải lại – Khi được đánh dấu, sẽ nhận được trình chạy dịch vụ mới nhất, cài đặt trình duyệt này và kích hoạt ngay.
  • Bỏ qua đối với mạng – Khi được chọn, các yêu cầu sẽ bỏ qua trình chạy dịch vụ và được gửi trực tiếp đến mạng.

Bắt đầu lại

Trong một số trường hợp, bạn có thể thấy mình đang tải dữ liệu đã lưu vào bộ nhớ đệm hoặc mọi thứ không được cập nhật như bạn mong đợi. Để xóa tất cả dữ liệu đã lưu (localStorage, dữ liệu đã lập chỉ mục, các tệp đã lưu vào bộ nhớ đệm) và xóa mọi trình chạy dịch vụ, hãy sử dụng ngăn Xóa bộ nhớ trong bảng Ứng dụng. Hoặc, bạn cũng có thể làm việc trong Cửa sổ ẩn danh.

Các mẹo khác:

  • Sau khi đã hủy đăng ký, một trình chạy dịch vụ có thể tiếp tục được liệt kê cho đến khi đóng cửa sổ trình duyệt.
  • Nếu nhiều cửa sổ trên ứng dụng của bạn đang mở, một trình chạy dịch vụ mới sẽ không có hiệu lực cho đến khi tất cả các cửa sổ được tải lại và cập nhật lên trình chạy dịch vụ mới nhất.
  • Việc hủy đăng ký một trình chạy dịch vụ sẽ không xóa bộ nhớ đệm!
  • Nếu một trình chạy dịch vụ tồn tại và một trình chạy dịch vụ mới đã được đăng ký, thì trình chạy dịch vụ mới sẽ không kiểm soát được cho đến khi trang được tải lại, trừ khi bạn kiểm soát ngay.

Xác minh các thay đổi bằng Lighthouse

Chạy lại Lighthouse và xác minh các thay đổi của bạn. Đừng quên bỏ chọn hộp đánh dấu Ngoại tuyến trước khi bạn xác minh các thay đổi của mình!

Kiểm tra SEO

  • ✔ ĐÃ ĐẠT: Tài liệu có phần mô tả meta.

Kiểm tra ứng dụng web tiến bộ

  • ✔ ĐÃ ĐẠT: Trang hiện tại phản hồi bằng 200 khi không có mạng.
  • ✔ ĐÃ ĐẠT: start_url phản hồi bằng 200 khi không có mạng.
  • ✔ ĐÃ ĐẠT: Đăng ký một trình chạy dịch vụ kiểm soát trang và start_url.
  • ✔ ĐÃ ĐẠT: Tệp kê khai ứng dụng web đáp ứng các yêu cầu về khả năng cài đặt.
  • ✔ ĐÃ ĐẠT: Được định cấu hình cho màn hình chờ tùy chỉnh.
  • ✔ ĐÃ ĐẠT: Đặt màu giao diện thanh địa chỉ.

Hãy dành ít phút để đặt điện thoại của bạn ở chế độ trên máy bay và thử chạy một số ứng dụng yêu thích. Trong hầu hết các trường hợp, các tính năng này cung cấp trải nghiệm ngoại tuyến khá mạnh mẽ. Người dùng mong đợi có được trải nghiệm mạnh mẽ từ các ứng dụng của họ. Và web cũng vậy. Ứng dụng web tiến bộ nên được thiết kế ngoại tuyến dưới dạng một tình huống cốt lõi.

Chu kỳ hoạt động của trình chạy dịch vụ

Vòng đời của trình chạy dịch vụ là phần phức tạp nhất. Nếu bạn không biết nó đang cố gắng làm gì và lợi ích là gì, thì có thể cảm thấy như nó đang chống lại bạn. Nhưng khi đã biết cách hoạt động, bạn có thể cung cấp cho người dùng các bản cập nhật liền mạch, không phô trương cho người dùng, kết hợp những điểm ưu việt nhất của web và mẫu gốc.

install sự kiện

Sự kiện đầu tiên mà một trình chạy dịch vụ nhận được là install. Hàm này được kích hoạt ngay khi trình chạy thực thi và chỉ được gọi một lần cho mỗi trình chạy dịch vụ. Nếu bạn thay đổi tập lệnh trình chạy dịch vụ của mình, thì trình duyệt sẽ coi trình chạy dịch vụ đó là một trình chạy dịch vụ khác và trình duyệt đó sẽ nhận được sự kiện install của riêng mình.

Thông thường, sự kiện install được dùng để lưu vào bộ nhớ đệm mọi thứ bạn cần để ứng dụng của bạn chạy.

activate sự kiện

Trình chạy dịch vụ sẽ nhận được một sự kiện activate mỗi khi sự kiện khởi động. Mục đích chính của sự kiện activate là định cấu hình hành vi của trình chạy dịch vụ, dọn dẹp mọi tài nguyên bị sao chép từ những lần chạy trước (ví dụ: bộ nhớ đệm cũ) và giúp trình chạy dịch vụ sẵn sàng xử lý các yêu cầu mạng (ví dụ: sự kiện fetch được mô tả bên dưới).

fetch sự kiện

Sự kiện tìm nạp cho phép trình chạy dịch vụ chặn mọi yêu cầu mạng và xử lý các yêu cầu. Nó có thể truy cập vào mạng để lấy tài nguyên, lấy tài nguyên từ bộ nhớ đệm của riêng mình, tạo phản hồi tùy chỉnh hoặc bất kỳ tùy chọn nào khác nhau. Hãy xem Sách hướng dẫn ngoại tuyến để biết những chiến lược khác nhau mà bạn có thể sử dụng.

Cập nhật trình chạy dịch vụ

Trình duyệt kiểm tra xem có phiên bản mới nào của trình chạy dịch vụ trong mỗi lần tải trang hay không. Nếu tìm thấy phiên bản mới, phiên bản mới sẽ được tải xuống và cài đặt trong nền, nhưng chưa được kích hoạt. Phiên bản mới của trình chạy dịch vụ ở trạng thái chờ cho đến khi không còn trang nào mở trình sử dụng trình chạy dịch vụ cũ nữa. Sau khi tất cả các cửa sổ sử dụng trình chạy dịch vụ cũ đã bị đóng, trình chạy dịch vụ mới này sẽ được kích hoạt và có thể kiểm soát. Tham khảo phần Cập nhật trình chạy dịch vụ của tài liệu Vòng đời trình chạy dịch vụ để biết thêm thông tin chi tiết.

Chọn chiến lược lưu vào bộ nhớ đệm phù hợp

Việc chọn chiến lược lưu vào bộ nhớ đệm phù hợp tùy thuộc vào loại tài nguyên mà bạn đang cố gắng lưu vào bộ nhớ đệm cũng như cách bạn có thể cần truy cập vào bộ nhớ đó sau này. Đối với ứng dụng thời tiết, chúng tôi sẽ chia các tài nguyên cần lưu vào bộ nhớ đệm thành hai danh mục: tài nguyên mà chúng tôi muốn lưu vào bộ nhớ đệm trước và dữ liệu mà chúng tôi sẽ lưu vào bộ nhớ đệm vào thời gian chạy.

Lưu tài nguyên tĩnh vào bộ nhớ đệm

Việc chuẩn bị tài nguyên của bạn là một khái niệm tương tự như điều gì xảy ra khi người dùng cài đặt ứng dụng trên máy tính hoặc thiết bị di động. Các tài nguyên chính cần thiết cho việc chạy ứng dụng cần được cài đặt hoặc lưu vào bộ nhớ đệm trên thiết bị để có thể tải sau này. Cho dù có kết nối mạng hay không.

Đối với ứng dụng, chúng tôi sẽ lưu trước tất cả tài nguyên tĩnh khi được cài đặt trình chạy dịch vụ để mọi thứ chúng tôi cần để chạy ứng dụng đều được lưu trữ trên thiết bị của người dùng. Để đảm bảo ứng dụng của chúng tôi tải nhanh, chúng tôi sẽ sử dụng chiến lược ưu tiên bộ nhớ đệm. Thay vì truy cập vào mạng để lấy các tài nguyên, chúng được lấy từ bộ nhớ đệm trên máy; chỉ khi không có mạng, chúng tôi mới cố gắng tải ứng dụng từ mạng.

Việc lấy dữ liệu từ bộ nhớ đệm trên máy sẽ loại bỏ mọi biến thể mạng. Cho dù người dùng thuộc loại mạng nào (WiFi, 5G, 3G hay thậm chí là 2G), thì các tài nguyên chính mà chúng tôi cần chạy đều có sẵn gần như ngay lập tức.

Lưu dữ liệu ứng dụng vào bộ nhớ đệm

Chiến lược xác thực lại theo thời gian là lựa chọn lý tưởng cho một số loại dữ liệu nhất định và hoạt động hiệu quả cho ứng dụng của chúng tôi. Chiến lược này nhận dữ liệu trên màn hình nhanh nhất có thể và sau đó cập nhật khi mạng đã trả về dữ liệu mới nhất. Trong khi xác thực lại, chúng tôi cần khởi động hai yêu cầu không đồng bộ, một yêu cầu đến bộ nhớ đệm và một yêu cầu đối với mạng.

Trong những trường hợp bình thường, dữ liệu đã lưu vào bộ nhớ đệm sẽ được trả lại gần như ngay lập tức, cung cấp dữ liệu gần đây cho ứng dụng mà ứng dụng có thể sử dụng. Sau đó, khi yêu cầu mạng trả về, ứng dụng sẽ được cập nhật bằng dữ liệu mới nhất từ mạng.

Đối với ứng dụng của chúng tôi, điều này mang lại trải nghiệm tốt hơn mạng, rơi vào chiến lược bộ nhớ đệm vì người dùng không phải đợi cho đến khi mạng yêu cầu hết thời gian để xem nội dung trên màn hình. Ban đầu, họ có thể thấy dữ liệu cũ, nhưng sau khi yêu cầu mạng trả về, ứng dụng sẽ được cập nhật dữ liệu mới nhất.

Cập nhật logic trong ứng dụng

Như đã đề cập trước đó, ứng dụng cần khởi động hai yêu cầu không đồng bộ, một yêu cầu đến bộ nhớ đệm và một yêu cầu đối với mạng. Ứng dụng này dùng đối tượng caches có sẵn trong window để truy cập bộ nhớ đệm và truy xuất dữ liệu mới nhất. Đây là một ví dụ hay về tính năng nâng cao lũy tiến vì đối tượng caches có thể không có sẵn trong tất cả các trình duyệt và nếu không, yêu cầu mạng vẫn sẽ hoạt động.

Hãy cập nhật hàm getForecastFromCache() để kiểm tra xem đối tượng caches có trong đối tượng window toàn cầu hay không và nếu có, hãy yêu cầu dữ liệu từ bộ nhớ đệm.

public/scripts/app.js

// CODELAB: Add code to get weather forecast from the caches object.
if (!('caches' in window)) {
  return null;
}
const url = `${window.location.origin}/forecast/${coords}`;
return caches.match(url)
    .then((response) => {
      if (response) {
        return response.json();
      }
      return null;
    })
    .catch((err) => {
      console.error('Error getting data from cache', err);
      return null;
    });

Sau đó, chúng ta cần sửa đổi updateData() để thực hiện 2 lệnh gọi, 1 đến getForecastFromNetwork() để nhận thông tin dự đoán từ mạng và 1 thành getForecastFromCache() để nhận thông tin dự đoán mới nhất trong bộ nhớ đệm:

public/scripts/app.js

// CODELAB: Add code to call getForecastFromCache.
getForecastFromCache(location.geo)
    .then((forecast) => {
      renderForecast(card, forecast);
    });

Ứng dụng thời tiết của chúng tôi hiện thực hiện hai yêu cầu không đồng bộ về dữ liệu, một yêu cầu từ bộ nhớ đệm và một yêu cầu qua fetch. Nếu có dữ liệu trong bộ nhớ đệm, dữ liệu đó sẽ được trả về và hiển thị cực kỳ nhanh (hàng chục mili giây). Sau đó, khi fetch phản hồi, thẻ sẽ được cập nhật dữ liệu mới nhất ngay từ API thời tiết.

Hãy lưu ý cách yêu cầu bộ nhớ đệm và yêu cầu fetch kết thúc bằng một lệnh gọi để cập nhật thẻ dự báo. Làm cách nào để ứng dụng biết liệu có hiển thị dữ liệu mới nhất hay không? URL này được xử lý trong mã sau của renderForecast():

public/scripts/app.js

// If the data on the element is newer, skip the update.
if (lastUpdated >= data.currently.time) {
  return;
}

Mỗi khi thẻ được cập nhật, ứng dụng sẽ lưu trữ dấu thời gian của dữ liệu trong một thuộc tính ẩn trên thẻ. Ứng dụng này chỉ được lưu giữ nếu dấu thời gian tồn tại trên thẻ mới hơn so với dữ liệu được chuyển vào hàm.

Lưu trước các tài nguyên ứng dụng của chúng tôi vào bộ nhớ đệm

Trong trình chạy dịch vụ, hãy thêm DATA_CACHE_NAME để chúng ta có thể tách dữ liệu của ứng dụng khỏi giao diện ứng dụng. Khi giao diện ứng dụng được cập nhật và bộ nhớ đệm cũ hơn sẽ bị xóa hoàn toàn, dữ liệu của chúng tôi sẽ vẫn chưa bị ảnh hưởng, sẵn sàng cho một tốc độ tải siêu nhanh. Xin lưu ý rằng nếu định dạng dữ liệu của bạn thay đổi trong tương lai, bạn sẽ cần một cách xử lý điều đó và đảm bảo giao diện ứng dụng và nội dung luôn đồng bộ hóa.

public/service-worker.js

// CODELAB: Update cache names any time any of the cached files change.
const CACHE_NAME = 'static-cache-v2';
const DATA_CACHE_NAME = 'data-cache-v1';

Đừng quên cập nhật CACHE_NAME; chúng tôi cũng sẽ thay đổi tất cả tài nguyên tĩnh của chúng tôi.

Để có thể hoạt động khi không có mạng, ứng dụng của chúng ta cần lưu trước một số tài nguyên cần thiết vào bộ nhớ đệm. Điều này cũng sẽ giúp cải thiện hiệu suất của chúng tôi. Thay vì phải lấy tất cả tài nguyên từ mạng, ứng dụng sẽ có thể tải tất cả tài nguyên từ bộ nhớ đệm trên máy, loại bỏ mọi trường hợp không ổn định mạng.

Cập nhật mảng FILES_TO_CACHE bằng danh sách tệp:

public/service-worker.js

// CODELAB: Add list of files to cache here.
const FILES_TO_CACHE = [
  '/',
  '/index.html',
  '/scripts/app.js',
  '/scripts/install.js',
  '/scripts/luxon-1.11.4.js',
  '/styles/inline.css',
  '/images/add.svg',
  '/images/clear-day.svg',
  '/images/clear-night.svg',
  '/images/cloudy.svg',
  '/images/fog.svg',
  '/images/hail.svg',
  '/images/install.svg',
  '/images/partly-cloudy-day.svg',
  '/images/partly-cloudy-night.svg',
  '/images/rain.svg',
  '/images/refresh.svg',
  '/images/sleet.svg',
  '/images/snow.svg',
  '/images/thunderstorm.svg',
  '/images/tornado.svg',
  '/images/wind.svg',
];

Vì chúng ta đang tạo danh sách các tệp để lưu vào bộ nhớ đệm theo cách thủ công, nên mỗi lần cập nhật một tệp, chúng ta phải cập nhật CACHE_NAME. Chúng tôi có thể xóa offline.html khỏi danh sách các tệp đã lưu vào bộ nhớ đệm vì ứng dụng của chúng tôi hiện có tất cả các tài nguyên cần thiết để hoạt động khi không có mạng và sẽ không bao giờ hiển thị lại trang ngoại tuyến.

Cập nhật trình xử lý sự kiện kích hoạt

Để đảm bảo sự kiện activate của chúng tôi không vô tình xóa dữ liệu, trong sự kiện activate của service-worker.js, hãy thay thế if (key !== CACHE_NAME) { bằng:

public/service-worker.js

if (key !== CACHE_NAME && key !== DATA_CACHE_NAME) {

Cập nhật trình xử lý sự kiện tìm nạp

Chúng ta cần phải sửa đổi trình chạy dịch vụ để chặn các yêu cầu đối với API thời tiết và lưu trữ các phản hồi của họ trong bộ nhớ đệm, để chúng ta có thể dễ dàng truy cập vào các yêu cầu đó sau này. Trong chiến lược xác thực lại cũ, chúng tôi hy vọng phản hồi của mạng là "nguồn đáng tin cậy", luôn cung cấp cho chúng tôi thông tin mới nhất. Nếu mạng không thể thì xảy ra lỗi vì chúng tôi đã truy xuất dữ liệu được lưu vào bộ nhớ đệm mới nhất trong ứng dụng của mình.

Cập nhật trình xử lý sự kiện fetch để xử lý các yêu cầu tới API dữ liệu riêng biệt với các yêu cầu khác.

public/service-worker.js

// CODELAB: Add fetch event handler here.
if (evt.request.url.includes('/forecast/')) {
  console.log('[Service Worker] Fetch (data)', evt.request.url);
  evt.respondWith(
      caches.open(DATA_CACHE_NAME).then((cache) => {
        return fetch(evt.request)
            .then((response) => {
              // If the response was good, clone it and store it in the cache.
              if (response.status === 200) {
                cache.put(evt.request.url, response.clone());
              }
              return response;
            }).catch((err) => {
              // Network request failed, try to get it from the cache.
              return cache.match(evt.request);
            });
      }));
  return;
}
evt.respondWith(
    caches.open(CACHE_NAME).then((cache) => {
      return cache.match(evt.request)
          .then((response) => {
            return response || fetch(evt.request);
          });
    })
);

Mã này sẽ chặn yêu cầu và kiểm tra xem đó có phải là thông tin dự báo thời tiết hay không. Nếu có, hãy dùng fetch để đưa ra yêu cầu. Sau khi phản hồi được trả về, hãy mở bộ nhớ đệm, sao chép phản hồi, lưu phản hồi đó trong bộ nhớ đệm và trả lại phản hồi cho người yêu cầu ban đầu.

Chúng tôi cần xóa công cụ kiểm tra evt.request.mode !== 'navigate' vì chúng tôi muốn trình chạy dịch vụ của mình xử lý tất cả các yêu cầu (bao gồm cả hình ảnh, tập lệnh, tệp CSS, v.v.), chứ không chỉ hoạt động điều hướng. Nếu chúng ta vẫn cho phép đăng ký, thì chỉ có HTML mới được phân phát từ bộ nhớ đệm của trình chạy dịch vụ. Mọi thứ khác sẽ được yêu cầu từ mạng.

Dùng thử

Ứng dụng hiện đã có đầy đủ chức năng ngoại tuyến. Làm mới trang này để đảm bảo rằng bạn đã cài đặt trình chạy dịch vụ mới nhất. Sau đó, lưu một vài thành phố và nhấn nút làm mới trên ứng dụng để nhận dữ liệu thời tiết mới.

Tiếp theo, chuyển tới ngăn Bộ nhớ đệm trên bảng điều khiển Ứng dụng của Công cụ cho nhà phát triển. Mở rộng phần này và bạn sẽ thấy tên của bộ nhớ đệm tĩnh và bộ nhớ đệm dữ liệu được liệt kê ở phía bên trái. Việc mở bộ nhớ đệm dữ liệu sẽ hiển thị dữ liệu được lưu trữ cho từng thành phố.

Chuyển sang ngăn Nhân viên dịch vụ rồi đánh dấu vào hộp Ngoại tuyến. Hãy thử tải lại trang rồi chuyển sang chế độ ngoại tuyến và tải lại trang.

Nếu bạn dùng mạng nhanh và muốn xem cách dữ liệu dự báo thời tiết được cập nhật trên kết nối chậm, hãy đặt thuộc tính FORECAST_DELAY trong server.js thành 5000. Tất cả yêu cầu đối với API dự báo sẽ bị chậm trễ 5.000 mili giây.

Xác minh các thay đổi bằng Lighthouse

Bạn cũng nên chạy lại Lighthouse.

Kiểm tra SEO

  • ✔ ĐÃ ĐẠT: Tài liệu có phần mô tả meta.

Kiểm tra ứng dụng web tiến bộ

  • ✔ ĐÃ ĐẠT: Trang hiện tại phản hồi bằng 200 khi không có mạng.
  • ✔ ĐÃ ĐẠT: start_url phản hồi bằng 200 khi không có mạng.
  • ✔ ĐÃ ĐẠT: Đăng ký một trình chạy dịch vụ kiểm soát trang và start_url.
  • ✔ ĐÃ ĐẠT: Tệp kê khai ứng dụng web đáp ứng các yêu cầu về khả năng cài đặt.
  • ✔ ĐÃ ĐẠT: Được định cấu hình cho màn hình chờ tùy chỉnh.
  • ✔ ĐÃ ĐẠT: Đặt màu giao diện thanh địa chỉ.

Khi một Ứng dụng web tiến bộ được cài đặt, ứng dụng này sẽ trông và hoạt động giống như tất cả các ứng dụng khác đã cài đặt. Dịch vụ này khởi chạy từ cùng nơi mà các ứng dụng khác phát hành. Hoạt động này chạy trong một ứng dụng mà không có thanh địa chỉ hoặc giao diện người dùng của trình duyệt khác. Giống như mọi ứng dụng đã cài đặt khác, đây là ứng dụng cấp cao nhất trong trình chuyển đổi tác vụ.

Trong Chrome, bạn có thể cài đặt một Ứng dụng web tiến bộ thông qua trình đơn theo bối cảnh ba dấu chấm, hoặc bạn có thể cung cấp cho người dùng một nút hoặc thành phần giao diện người dùng khác để nhắc họ cài đặt ứng dụng của bạn.

Kiểm tra bằng Lighthouse

Để có thể cài đặt Ứng dụng web tiến bộ, ứng dụng cần đáp ứng một số tiêu chí. Cách dễ nhất để kiểm tra là sử dụng Lighthouse và đảm bảo Lighthouse đáp ứng các tiêu chí có thể cài đặt.

Nếu bạn đã làm việc qua lớp học lập trình này, thì PWA của bạn phải đáp ứng các tiêu chí này.

Thêm install.js vào index.html

Trước tiên, hãy thêm install.js vào tệp index.html của chúng tôi.

public/index.html

<!-- CODELAB: Add the install script here -->
<script src="/scripts/install.js"></script>

Nghe sự kiện beforeinstallprompt

Nếu bạn đáp ứng các tiêu chí trên màn hình chính, Chrome sẽ kích hoạt một sự kiện beforeinstallprompt mà bạn có thể dùng để cho biết ứng dụng của bạn có thể được cài đặt & # 39; sau đó nhắc người dùng cài đặt ứng dụng đó. Thêm mã bên dưới để theo dõi sự kiện beforeinstallprompt:

public/scripts/install.js

// CODELAB: Add event listener for beforeinstallprompt event
window.addEventListener('beforeinstallprompt', saveBeforeInstallPromptEvent);

Lưu sự kiện và hiển thị nút cài đặt

Trong hàm saveBeforeInstallPromptEvent, chúng ta sẽ lưu một tệp tham chiếu đến sự kiện beforeinstallprompt để có thể gọi prompt() sau này và cập nhật giao diện người dùng để hiển thị nút cài đặt.

public/scripts/install.js

// CODELAB: Add code to save event & show the install button.
deferredInstallPrompt = evt;
installButton.removeAttribute('hidden');

Hiện lời nhắc và ẩn nút

Khi người dùng nhấp vào nút cài đặt, chúng ta cần gọi .prompt() trên sự kiện beforeinstallprompt đã lưu. Chúng ta cũng cần ẩn nút cài đặt vì .prompt() chỉ có thể được gọi một lần trong mỗi sự kiện đã lưu.

public/scripts/install.js

// CODELAB: Add code show install prompt & hide the install button.
deferredInstallPrompt.prompt();
// Hide the install button, it can't be called twice.
evt.srcElement.setAttribute('hidden', true);

Việc gọi .prompt() sẽ hiển thị hộp thoại kiểu cho người dùng, yêu cầu họ thêm ứng dụng của bạn vào màn hình chính của họ.

Ghi lại kết quả

Bạn có thể kiểm tra xem người dùng đã phản hồi hộp thoại cài đặt như thế nào bằng cách theo dõi lời hứa hẹn của thuộc tính userChoice của sự kiện beforeinstallprompt đã lưu trả về. Lời hứa này sẽ trả về một đối tượng có thuộc tính outcome sau khi lời nhắc hiển thị và người dùng đã phản hồi.

public/scripts/install.js

// CODELAB: Log user response to prompt.
deferredInstallPrompt.userChoice
    .then((choice) => {
      if (choice.outcome === 'accepted') {
        console.log('User accepted the A2HS prompt', choice);
      } else {
        console.log('User dismissed the A2HS prompt', choice);
      }
      deferredInstallPrompt = null;
    });

Một nhận xét về userChoice: thông số kỹ thuật xác định thuộc tính này là thuộc tính, không phải là hàm như bạn mong đợi.

Ghi lại tất cả các sự kiện cài đặt

Ngoài giao diện người dùng mà bạn thêm vào để cài đặt ứng dụng, người dùng cũng có thể cài đặt PWA của bạn thông qua các phương thức khác, chẳng hạn như trình đơn có biểu tượng ba dấu chấm của Chrome. Để theo dõi các sự kiện này, hãy theo dõi sự kiện đã cài đặt ứng dụng.

public/scripts/install.js

// CODELAB: Add event listener for appinstalled event
window.addEventListener('appinstalled', logAppInstalled);

Sau đó, chúng ta cần cập nhật hàm logAppInstalled. Đối với lớp học lập trình này, chúng ta sẽ chỉ dùng console.log, nhưng trong một ứng dụng thực tế, bạn có thể muốn ghi nhật ký sự kiện này dưới dạng một sự kiện bằng phần mềm phân tích của mình.

public/scripts/install.js

// CODELAB: Add code to log the event
console.log('Weather App was installed.', evt);

Cập nhật trình chạy dịch vụ

Đừng quên cập nhật CACHE_NAME trong tệp service-worker.js của bạn vì bạn đã thực hiện thay đổi đối với các tệp đã được lưu vào bộ nhớ đệm. Bật hộp đánh dấu Bỏ qua cho mạng trong ngăn Nhân viên dịch vụ của bảng Ứng dụng trong Công cụ cho nhà phát triển sẽ hoạt động nhưng không giúp ích trong thực tế.

Dùng thử

Hãy xem quá trình cài đặt của chúng tôi diễn ra như thế nào. Để đảm bảo an toàn, hãy sử dụng nút Xóa dữ liệu trang web trong bảng điều khiển Ứng dụng của Công cụ cho nhà phát triển để xóa mọi thứ và đảm bảo chúng tôi đang khởi động lại ứng dụng. Nếu bạn đã cài đặt ứng dụng trước đó, hãy nhớ gỡ cài đặt ứng dụng, nếu không biểu tượng cài đặt sẽ không hiển thị lại.

Xác minh rằng nút cài đặt đã hiển thị

Trước tiên, hãy xác minh biểu tượng cài đặt của chúng tôi hiển thị chính xác. Hãy nhớ dùng thử tính năng này trên cả máy tính và thiết bị di động.

  1. Mở URL trong một thẻ Chrome mới.
  2. Mở trình đơn có biểu tượng ba dấu chấm của Chrome (bên cạnh thanh địa chỉ).
    ▢ Xác minh rằng bạn thấy "Cài đặt thông tin thời tiết..." trong trình đơn.
  3. Làm mới dữ liệu thời tiết bằng nút làm mới ở góc trên bên phải để đảm bảo chúng tôi đáp ứng các phương pháp phỏng đoán của người dùng.
    ▢ Xác minh rằng biểu tượng cài đặt hiển thị trong tiêu đề ứng dụng.

Xác minh rằng nút cài đặt đang hoạt động

Tiếp theo, hãy đảm bảo mọi thứ đều được cài đặt đúng cách và các sự kiện của chúng ta được kích hoạt đúng cách. Bạn có thể thực hiện việc này trên máy tính hoặc thiết bị di động. Nếu bạn muốn kiểm tra điều này trên thiết bị di động, hãy đảm bảo rằng bạn đang sử dụng tính năng gỡ lỗi từ xa để có thể xem nội dung được đăng nhập vào bảng điều khiển.

  1. Mở Chrome và trong một thẻ trình duyệt mới, hãy chuyển đến PWA thời tiết.
  2. Mở Công cụ cho nhà phát triển và chuyển sang bảng điều khiển Bảng điều khiển.
  3. Nhấp vào nút cài đặt ở góc trên bên phải.
    ▢ Xác minh nút cài đặt sẽ biến mất
    ▢ Xác minh hộp thoại kiểu cài đặt được hiển thị.
  4. Nhấp vào Hủy.
    ▢ Xác minh "Người dùng đã đóng lời nhắc A2HS" hiển thị trong kết quả trên bảng điều khiển.
    ▢ Xác minh nút cài đặt sẽ xuất hiện lại.
  5. Nhấp lại vào nút cài đặt, sau đó nhấp vào nút cài đặt trong hộp thoại kiểu.
    ▢ Xác minh "Người dùng chấp nhận lời nhắc A2HS" hiển thị trong đầu ra bảng điều khiển.
    ▢ Xác minh "Ứng dụng thời tiết đã được cài đặt" hiển thị trong kết quả của bảng điều khiển.
    ▢ Xác minh ứng dụng Thời tiết được thêm vào nơi bạn thường tìm thấy ứng dụng.
  6. Chạy PWA thời tiết.
    ▢ Xác minh để mở ứng dụng dưới dạng một ứng dụng độc lập, trong cửa sổ ứng dụng trên máy tính hoặc trên toàn màn hình trên thiết bị di động.

.

Xác minh rằng quá trình cài đặt iOS hoạt động đúng cách

Hãy kiểm tra hành vi trên iOS. Nếu có thiết bị iOS, bạn có thể sử dụng thiết bị đó hoặc nếu bạn đang dùng máy Mac, hãy thử Trình mô phỏng iOS có sẵn với Xcode.

  1. Mở Safari và trong một thẻ trình duyệt mới, hãy chuyển đến PWA thời tiết.
  2. Nhấp vào nút Chia sẻ .
  3. Di chuyển sang phải rồi nhấp vào nút Thêm vào Màn hình chính.
    ▢ Xác minh tiêu đề, URL và biểu tượng là chính xác.
  4. Nhấp vào Thêm.
    ▢ Xác minh biểu tượng ứng dụng đã được thêm vào màn hình chính.
  5. Chạy PWA thời tiết từ màn hình chính.
    ▢ Xác minh ứng dụng chạy toàn màn hình.

Điểm thưởng: Phát hiện xem ứng dụng của bạn có đang chạy trên màn hình chính hay không

Truy vấn nội dung nghe nhìn display-mode giúp bạn có thể áp dụng kiểu tùy thuộc vào cách ứng dụng được chạy hoặc xác định cách khởi chạy bằng JavaScript.

@media all and (display-mode: standalone) {
  body {
    background-color: yellow;
  }
}

Bạn cũng có thể kiểm tra truy vấn đa phương tiện display-mode trong JavaScript để xem liệu bạn có đang chạy độc lập hay không.

Điểm thưởng: Gỡ cài đặt PWA của bạn

Hãy nhớ rằng beforeinstallevent không kích hoạt nếu ứng dụng đã được cài đặt, do đó, trong quá trình phát triển, bạn có thể muốn cài đặt và gỡ cài đặt ứng dụng nhiều lần để đảm bảo mọi thứ hoạt động như mong đợi.

Android

Trên Android, các ứng dụng web tiến bộ (PWA) được gỡ cài đặt giống như cách gỡ cài đặt các ứng dụng khác đã cài đặt.

  1. Mở ngăn ứng dụng.
  2. Di chuyển xuống để tìm biểu tượng Thời tiết.
  3. Kéo biểu tượng ứng dụng lên đầu màn hình.
  4. Chọn Gỡ cài đặt.

ChromeOS

Trên ChromeOS, PWA có thể dễ dàng gỡ cài đặt khỏi hộp tìm kiếm của trình chạy.

  1. Mở trình chạy.
  2. Nhập "Thời tiết" vào hộp tìm kiếm, PWA thời tiết sẽ xuất hiện trong kết quả.
  3. Nhấp chuột phải (nhấp để thay thế) trên PWA thời tiết.
  4. Nhấp vào Xóa khỏi Chrome...

macOS và Windows

Trên máy Mac và Windows, PWA có thể được gỡ cài đặt thông qua Chrome:

  1. Trong thẻ trình duyệt mới, hãy mở chrome://apps.
  2. Nhấp chuột phải (nhấp để thay thế) trên PWA thời tiết.
  3. Nhấp vào Xóa khỏi Chrome...

Bạn cũng có thể mở PWA đã cài đặt, nhấp vào trình đơn theo bối cảnh ba dấu chấm ở góc trên bên phải rồi chọn "Gỡ cài đặt PWA thời tiết..."

Xin chúc mừng, bạn đã xây dựng thành công Ứng dụng web tiến bộ đầu tiên của mình!

Bạn đã thêm tệp kê khai ứng dụng web để cho phép cài đặt tệp đó và bạn đã thêm một trình chạy dịch vụ để đảm bảo rằng PWA của bạn luôn nhanh và đáng tin cậy. Bạn đã tìm hiểu cách sử dụng Công cụ cho nhà phát triển để kiểm tra ứng dụng và cách ứng dụng đó có thể giúp bạn cải thiện trải nghiệm người dùng.

Giờ đây, bạn đã biết các bước chính cần thiết để biến bất kỳ ứng dụng web nào thành Ứng dụng web tiến bộ.

Tiếp theo là gì?

Hãy xem một số lớp học lập trình này...

Tài liệu đọc thêm

Tài liệu tham khảo