Progressive Web App: การทำงานแบบออฟไลน์

Progressive Web App:
การทำงานแบบออฟไลน์

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ ก.ย. 18, 2024
account_circleเขียนโดย Googler

1 ยินดีต้อนรับ

ในแล็บนี้ คุณจะได้นำเว็บแอปพลิเคชันที่มีอยู่มาทำให้ทำงานแบบออฟไลน์ได้ Codelab นี้เป็น Codelab แรกในชุด Codelab ที่ใช้ร่วมกันสำหรับเวิร์กชอป Progressive Web App ยังมี Codelab อีก 7 รายการในชุดนี้

  • เขียน Service Worker ด้วยตนเอง
  • เพิ่ม Service Worker ลงในเว็บแอปพลิเคชันที่มีอยู่
  • ใช้ Service Worker และ Cache Storage API เพื่อให้ทรัพยากรพร้อมใช้งานแบบออฟไลน์
  • HTML และ JavaScript พื้นฐาน

2 เตรียมตัว

เริ่มต้นด้วยการโคลนหรือดาวน์โหลดโค้ดเริ่มต้นที่จำเป็นต่อการทำ Codelab นี้ให้เสร็จสมบูรณ์

หากโคลนที่เก็บ โปรดตรวจสอบว่าคุณอยู่ในสาขา starter ไฟล์ ZIP มีโค้ดสำหรับสาขานั้นด้วย

โค้ดเบสนี้ต้องใช้ Node.js 14 ขึ้นไป เมื่อมีโค้ดแล้ว ให้เรียกใช้ npm ci จากบรรทัดคำสั่งในโฟลเดอร์ของโค้ดเพื่อติดตั้งการอ้างอิงทั้งหมดที่คุณต้องใช้ จากนั้นเรียกใช้ npm start เพื่อเริ่มเซิร์ฟเวอร์สำหรับพัฒนาสำหรับโค้ดแล็บ

ไฟล์ README.md ของซอร์สโค้ดจะอธิบายไฟล์ที่เผยแพร่ทั้งหมด นอกจากนี้ ไฟล์สำคัญที่มีอยู่ซึ่งคุณจะต้องใช้ตลอดทั้งโค้ดแล็บนี้มีดังนี้

ไฟล์สำคัญ

  • js/main.js - ไฟล์ JavaScript ของแอปพลิเคชันหลัก
  • service-worker.js - ไฟล์ Service Worker ของแอปพลิเคชัน

3 ทดสอบแบบออฟไลน์

ก่อนทำการเปลี่ยนแปลงใดๆ มาทดสอบเพื่อแสดงว่าปัจจุบันเว็บแอปทำงานแบบออฟไลน์ไม่ได้ โดยคุณสามารถทำได้โดยปิดคอมพิวเตอร์และโหลดเว็บแอปซ้ำ หรือหากใช้ Chrome ให้ทำดังนี้

  1. เปิดเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
  2. เปลี่ยนไปที่แท็บแอปพลิเคชัน
  3. เปลี่ยนไปที่ส่วน Service Worker
  4. เลือกช่องทำเครื่องหมายออฟไลน์
  5. รีเฟรชหน้าเว็บโดยไม่ต้องปิดเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

แท็บแอปพลิเคชันเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome เปิดอยู่สำหรับ Service Worker โดยเลือกช่องทำเครื่องหมายออฟไลน์

เมื่อทดสอบเว็บไซต์และโหลดแบบออฟไลน์ไม่สำเร็จแล้ว ก็ถึงเวลาเพิ่มฟังก์ชันการทำงานออนไลน์แล้ว ยกเลิกการเลือกช่องทำเครื่องหมายออฟไลน์ แล้วดำเนินการต่อในขั้นตอนถัดไป

4 คุยกันนอก YouTube

ได้เวลาเพิ่ม Service Worker พื้นฐานแล้ว โดยจะเกิดขึ้นใน 2 ขั้นตอน ได้แก่ การลงทะเบียน Service Worker และการแคชทรัพยากร

ลงทะเบียน Service Worker

เนื่องจากมีไฟล์ Service Worker ว่างอยู่แล้ว เราจึงต้องลงทะเบียนไฟล์ดังกล่าวในแอปพลิเคชันเพื่อให้การเปลี่ยนแปลงแสดงขึ้น โดยเพิ่มโค้ดต่อไปนี้ที่ด้านบนของ js/main.js

// Register the service worker
if ('serviceWorker' in navigator) {
  // Wait for the 'load' event to not block other work
  window.addEventListener('load', async () => {
    // Try to register the service worker.
    try {
      // Capture the registration for later use, if needed
      let reg;

      // Use ES Module version of our Service Worker in development
      if (import.meta.env?.DEV) {
        reg = await navigator.serviceWorker.register('/service-worker.js', {
          type: 'module',
        });
      } else {
        // In production, use the normal service worker registration
        reg = await navigator.serviceWorker.register('/service-worker.js');
      }

      console.log('Service worker registered! 😎', reg);
    } catch (err) {
      console.log('😥 Service worker registration failed: ', err);
    }
  });
}

คำอธิบาย

โค้ดนี้จะลงทะเบียนไฟล์ Service Worker service-worker.js ว่างเมื่อหน้าเว็บโหลดแล้ว และเฉพาะในกรณีที่เว็บไซต์รองรับ Service Worker

แคชทรัพยากรล่วงหน้า

หากต้องการให้เว็บแอปทำงานแบบออฟไลน์ได้ เบราว์เซอร์ต้องตอบสนองต่อคำขอเครือข่ายและเลือกเส้นทางที่จะส่งคำขอได้ โดยให้เพิ่มข้อความต่อไปนี้ลงใน service-worker.js

// Choose a cache name
const cacheName = 'cache-v1';
// List the files to precache
const precacheResources = ['/', '/index.html', '/css/style.css', '/js/main.js', '/js/app/editor.js', '/js/lib/actions.js'];

// When the service worker is installing, open the cache and add the precache resources to it
self.addEventListener('install', (event) => {
  console.log('Service worker install event!');
  event.waitUntil(caches.open(cacheName).then((cache) => cache.addAll(precacheResources)));
});

self.addEventListener('activate', (event) => {
  console.log('Service worker activate event!');
});

// When there's an incoming fetch request, try and respond with a precached resource, otherwise fall back to the network
self.addEventListener('fetch', (event) => {
  console.log('Fetch intercepted for:', event.request.url);
  event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
      if (cachedResponse) {
        return cachedResponse;
      }
      return fetch(event.request);
    }),
  );
});

ตอนนี้ให้กลับไปที่เบราว์เซอร์ ปิดแท็บแสดงตัวอย่าง แล้วเปิดอีกครั้ง คุณควรเห็น console.log ที่สอดคล้องกับเหตุการณ์ต่างๆ ใน Service Worker

จากนั้นให้กลับไปออฟไลน์อีกครั้งและรีเฟรชเว็บไซต์ คุณควรเห็นว่าวิดีโอโหลดได้แม้ว่าคุณจะออฟไลน์อยู่ก็ตาม

คำอธิบาย

ในระหว่างเหตุการณ์การติดตั้งของ Service Worker ระบบจะเปิดแคชที่มีชื่อโดยใช้ Cache Storage API จากนั้นระบบจะโหลดไฟล์และเส้นทางที่ระบุใน precacheResources ลงในแคชโดยใช้วิธี cache.addAll เราเรียกกระบวนการนี้ว่าการแคชล่วงหน้า เนื่องจากเป็นการแคชชุดไฟล์ล่วงหน้าในระหว่างการติดตั้ง ไม่ใช่การแคชเมื่อจำเป็นต้องใช้หรือมีการขอไฟล์

เมื่อ Service Worker ควบคุมเว็บไซต์แล้ว ทรัพยากรที่ขอจะผ่าน Service Worker เหมือนกับพร็อกซี คำขอแต่ละรายการจะทริกเกอร์เหตุการณ์การดึงข้อมูล ซึ่งใน Service Worker นี้จะค้นหาแคชเพื่อหารายการที่ตรงกัน หากมีรายการที่ตรงกัน ก็จะตอบกลับด้วยทรัพยากรที่แคชไว้ หากไม่มีรายการที่ตรงกัน ระบบจะขอทรัพยากรตามปกติ

การแคชทรัพยากรช่วยให้แอปทำงานแบบออฟไลน์ได้โดยไม่ต้องส่งคำขอของเครือข่าย ตอนนี้แอปสามารถตอบสนองด้วยรหัสสถานะ 200 เมื่อออฟไลน์ได้แล้ว

5 ยินดีด้วย

คุณได้เรียนรู้วิธีทำให้เว็บแอปทำงานแบบออฟไลน์ได้โดยใช้ Service Worker และ Cache Storage API

Codelab ถัดไปในชุดนี้คือการทำงานกับ Workbox