หัดทำ Progressive Web Apps ในปี 2020

เขียนครั้งเดียวเป็นทั้งเว็บ แอพมือถือ แอพคอม

Progressive Web Apps

มาแล้ววว

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

มีเทคโนโลยีน้องใหม่ที่ออกมาได้ซักพักแล้วก็เสถียรพอที่คนจะเริ่มเอามาใช้กันจริง ๆ และหลายคนก็คงจะเคยเห็นกันมาไม่มากก็น้อยแล้วแต่ไม่รู้ว่ามันคือตัวนี้ ก็คือ Progressive Web Apps หรือเรียกย่อ ๆ ว่า PWA

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

ข้อมูลออนไลน์ที่มีเยอะแยะมาก ต้องใช้ความพยายามมาก ๆ ในกลั่นกรองเอาสิ่งที่แก้ปัญหาที่เราไม่มีออกไป สุดท้ายก็... วิ้งงงง ออกมาเป็นเว็บนี้นั่นเอง ว่าจะทยอยเพิ่ม “ของเล่น” ลงที่นี่เรื่อย ๆ ถ้าใครอ่านจบจะลองเอาเว็บนี้ลงในคอมหรือมือถือดูก็ได้ ;P

PWA คือ?

คือเว็บไซต์/เว็บแอพที่

  1. สามารถลงเป็น application เหมือนของจริงได้ หมายความว่าทำครั้งเดียว จะได้เอาไปใช้บน
    • เว็บเบราเซอร์ทั้งคอมและมือถือ
    • ลงเป็นโปรแกรมบนเครื่อง
    • ลงเป็นแอพบนมือถือ
  2. ซึ่งความสามารถพิเศษที่ได้นอกเหนือไปจากเว็บแอพก็คือมันมีโมดูลที่เรียกว่า Service Worker ซึ่งมีสิทธิเรียกขอใช้ฟังก์ชันของ device ได้ น้ำจิ้มก็เช่น (เน้นว่าต้องขอก่อน)
    • ขอใช้ GPS ขอใช้ accelerometer
    • ขอใช้ระบบไฟล์บนเครื่อง (เช่นพวกแอพแนว drive ฝากไฟล์)
    • ขอใช้กล้อง
  3. สามารถใช้ออฟไลน์ได้ตามสมเหตุสมผล (เหมือนแอพทั่วไป) เช่น
    • ถ้าเป็นแอพคู่มือการใช้งาน จะให้ต้องต่อเน็ตตลอดเวลาก็ยังไงอยู่ เพราะงั้นคู่มือที่โหลดมาแล้วก็เซฟไว้ดูได้ตลอด เปิดโหมดเครื่องบินก็ยังดูได้

รวมแล้วก็เหมือนเป็นแอพอิสระไม่ผูกกับ app store หรือยักษ์ใหญ่คนกลางใด ๆ นั่นเอง (ซึ่งจากการค้นคว้าข้อมูลนิดหน่อย แอปเปิ้ลไม่ชอบด้วยเพราะมันขัด app store แต่ก็จำใจใส่ฟีเจอร์นี้ไป)

ดูยังไงว่าเป็น PWA?

การแยกแยะ PWA จากเว็บปกติ ไม่ได้แยกที่รูปร่างหน้าตาของเว็บแต่อย่างใด แต่แยกจากฟีเจอร์นี้คือ เวลาคนเรากดไปหาเว็บที่เป็น PWA ตัว browser จะรู้ว่ามันเป็นรึเปล่า และถ้าเป็นก็จะมีบอกใบ้มาให้เราลง ยกตัวอย่างเช่นเวลาเปิด outlook จะมีปุ่ม + ขึ้นมาบนฝั่งขวา address bar

กดปุ่ม + มันจะถามว่าจะลงรึเปล่า โอเค ลง

owa-install

ลงแล้วก็กลายเป็นคล้าย ๆ โปรแกรมของมันเองแบบนี้ (ย่อจอไม่ให้เห็นเมล)

owa-post-install

ส่วนบนมือถือก็จะมี add to home screen แต่รอบนี้ยกตัวอย่าง Uber บ้าง เริ่มจากไปเข้าเว็บมือถือของมันเลย m.uber.com

หลังล็อกอินก็จะใช้เว็บแอพได้ พอสังเกตดี ๆ มันจะมีปุ่ม + ซึ่งจะเด้งออกมาเป็น add to home screen

uber-pre-install

กลายเป็นแอพแล้ว เนียนเหมือนแอพปกติ ถ้า Add to home screen กับเว็บที่ไม่ใช่ PWA จะมีโลโก้ chrome/firefox ติดมาด้วย

uber-post-install

เปิดมาก็หน้าตาเหมือนตอนใช้ในเว็บ แต่ไม่มี address bar แล้ว

uber-in-app

เดี๋ยว ๆ 254 kB? เวอร์ชั่นบน app store ประมาณ 50 MB เลยนะ!

uber-pwa-size

ทั้งนี้ทั้งนั้นตั้งข้อสังเกตได้ข้อนึงว่า PWA สามารถทำให้ดูเหมือนแอพทั่วไปได้ แต่ขนาดเฉลี่ยจะน้อยกว่ามาก จริง ๆ แล้วขนาดมีมากกว่า 254 kB เพราะขนาดที่เหลือไปเก็บบนเบราเซอร์อย่าง chrome ที่เราใช้โหลดมา แต่ขนาดนั้นก็ไม่ต่างอะไรมากกับขนาดเว็บทั่ว ๆ ไป ซึ่งการเก็บเอาไว้กับเบราเซอร์แบบนี้ทำให้ได้ประโยชน์อีกเด้งคือ พวก asset ที่โหลดมาแล้วจะไม่ต้องโหลดซ้ำเวลาเปิดอีกทาง เช่นเปิด Uber ไปครั้งแรกบนเว็บพวก layout ก็โหลดมาหมดแล้ว ตัวแอพก็เอาไปใช้ซ้ำได้เลย
ประหยัดทรัพยากรเพราะคนใช้ก็จ่ายค่าเน็ตน้อยลง คนให้คอนเท้นก็จ่ายค่าเน็ตน้อยลง คอนเท้นก็โหลดไวขึ้น

ลองทำดู

ดูมีประโยชน์ เอ้า ลอง!

พอไปดูสเปคบน MDN แล้วจริง ๆ มันทำง่ายมาก คือถ้าสมมติใครมีเว็บไซต์อยู่แล้ว ก็สามารถแปลงเป็น PWA ได้ อย่างแรกก็คือต้องสร้างไฟล์ site.webmanifest ซึ่งจะลิสต์เอาดื้อ ๆ เลยว่า อยากให้แอพธีมสีอะไร ภาพไอคอนภาพอะไร แล้วก็ URL ไหนเป็น entry point ที่จะถือว่า “หน้านี้กับหน้าย่อยอื่น ๆ ถือเป็นส่วนนึงของแอพแล้วนะ” ซึ่งพอเข้าใจคอนเซปแล้วก็เริ่มเติมคำในช่องว่างออกมาได้ประมาณนี้

{
  "name":"pboribal",
  "short_name":"pboribal",
  "description": "Perut Boribalburephan",
  "icons":[
    {"src":"media/android-chrome-192x192.png", "sizes":"192x192","type":"image/png"},
    {"src":"media/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}
  ],
  "theme_color":"#001B44",
  "background_color":"#001B44",
  "display":"standalone",
  "start_url": "/",
  "scope": "/"
}

เสร็จแล้วก็แปะโค้ด HTML เล็ก ๆ บนหน้าหลัก เวลาเบราเซอร์จะโชว์เว็บเรามันจะได้รู้ว่าเว็บเราทำหน้าที่เป็นแอพได้

<link rel="manifest" href="site.webmanifest">

ซึ่งทำแค่นี้เราก็แปลงโฉมจากเว็บปกติกลายเป็นเว็บที่ลงเป็นแอพได้แล้ว พร้อมไอคอนแล้วก็ splash theme เวลาเปิดแอพ ตามโลโก้กับสี background ที่ใส่ไว้

ยังไม่หมด!!!

จุดเด่นอย่างนึงที่ว่าไว้เกี่ยวกับ PWA คือการที่มันสามารถมี service worker ซึ่งสามารถเซฟของที่ใช้บ่อย ๆ ไว้ได้จะได้ไม่ต้องโหลดใหม่ทุกครั้ง แถมยังเข้าถึงฟีเจอร์บนเครื่องได้ด้วย เช่น push notification!!! (ถ้าขอแล้วคนยอมให้ใช้ ก็เหมือนแอพทั่วไป) แต่มันจะรู้ได้ไงว่าต้องเซฟอะไรบ้าง

ซึ่ง service worker นี้พอค้น ๆ ไปเรื่อย ๆ ก็ลงเอยด้วยโค้ดประมาณ 50 บรรทัดที่หลัก ๆ คืออธิบายให้เบราเซอร์ที่จะเอา service worker ของเราไปลงบนเครื่องผู้ใช้รู้ว่าเรามียุทธวิธีในการเซฟอะไรบ้าง แล้วจะทำอะไรบ้างเวลาแอพ “อัพเดต” ยกตัวอย่าง 20% ของโค้ดที่ตัด ๆ มาจากของจริง ของแบบนี้อ่านคู่มือนาน แต่พอทำเป็นจริง ๆ แล้วเขียนน้อยมาก ๆ

const CACHE = 'pboribal-v1.03';
// things to cache
const PRECACHE = ['/', '/index.html', '/media/me.webp', '/media/me2.webp'];
...
const shouldCache = (e) =>
  (e.request.url.startsWith(self.location.origin)
   && !e.request.url.includes('blog')
   && !e.request.url.includes('apps'))
  || e.request.url.endsWith('.woff')
  || e.request.url.includes('jsdelivr')
  || e.request.url.includes('unpkg');
addEventListener('fetch', e =>
  shouldCache(e) ? e.respondWith(cachedResource(e.request)) : fetch(e.request));

ซึ่งทั้งหมดนี้ก็แทบจะเป็นการแปลมาจากภาษาไทย/อังกฤษ เลยว่า "ให้เซฟไว้ไม่ต้องโหลดใหม่ถ้ามาจากเว็บตัวเองแต่ไม่ใช่บล็อกหรือแอพ นอกจากนั้นถ้าเอา .woff (ฟอนต์) หรือไฟล์จากเว็บ jsdelivr/unpkg (เครื่องมือที่เอามาใช้เขียนเว็บ) ก็ให้เซฟเก็บไว้ไม่ต้องโหลดใหม่" โค้ดก็ไม่ได้ยาวไปกว่าที่เขียนอธิบายเลยจริงไหม?

ทั้งนี้เราก็ยังไม่ได้ใช้ push notification เพราะไม่รู้จะใส่ไปทำอะไร แต่ปริมาณในการทำก็ถือว่าเท่า ๆ กันเพราะใน service worker มันมีตัวที่เรียกว่า pushManager ซึ่งเป็นตัวจัดการ เรื่อง subscription เหมือนเวลากดกระดิ่งเฟซบุ๊คอะไรงี้แล้วเวลาเกิดเหตุการณ์ที่น่าสนใจขึ้นก็จะสร้าง Notification เด้งขึ้นมาเป็นข้อความ + รูปภาพให้คนอย่างเรา ๆ เห็นนั่นเอง

สรุป

แค่นี้แหละ Progressive Web App (PWA) เลยเป็น web standard ที่ทำให้คนที่ทำเว็บเป็นก็เหมือนทำ mobile app / desktop app เป็นไปด้วย

เพราะงั้นสิ่งที่เหลือก็คือไปหัดเรื่อง responsive design หรือก็คือจะสไตล์เว็บยังไงให้มันดูต่างกันแล้วแต่ขนาดจอนั่นเอง (ซึ่งเป็นเทคนิค mobile web ทั่ว ๆ ไปที่ไม่เกี่ยวกับ PWA แต่อย่างใด)

อื่นๆ

ตรงนี้แปะท้ายมาเพราะไม่เกี่ยวกับ PWA แต่เป็นอะไรหลาย ๆ อย่างที่สรุปมาได้หลังจากนั่งประเมินเครื่องมือใหม่ ๆ ว่าจริง ๆ แล้วมีอะไรใหม่ขนาดไหน

Tooling/Framework

ไม่ต้องบอกทุกคนก็คงรู้อยู่แล้วว่า หาข้อมูลบนเน็ตมันง่ายมากกก (แต่หาให้มีคุณภาพน่ะคนละเรื่อง อาจจะไว้เขียนเรื่องนี้ครั้งต่อไป) พอลองหาดูว่าเดี๋ยวนี้คนใช้อะไรกันก็มียักษ์ใหญ่โผล่ขึ้นมาสี่ตัว

  1. React - โดย Facebook
  2. Angular - โดย Google
  3. Vue
  4. Svelte

มี honorary mention อีกนิดหน่อย

  1. MithrilJS
  2. lit-html

ซึ่งเป็น Open Source หมายความว่าคนทั่ว ๆ ไปก็สามารถเอาไปใช้ได้เช่นกัน! เพราะงั้นแทนที่จะมานั่งสร้างใหม่ทั้งหมด คนก็เลยมีของฟรีเป็นต้นทุนให้เลือกใช้เป็นฐาน เพราะงั้นถ้าใครสนใจเขียนเว็บเป็นงานหลักก็ไปดู ๆ ในสี่ห้าหกอันนี้ได้จะได้ตรงตาม demand นะ

แต่ถ้าดูลึก ๆ แล้วเนื่องจากว่ามีคนทำ front end เยอะเหลือเกิน เครื่องมือพวกนี้ดูจะเปลี่ยนแปลงบ่อย ความนิยมก็เปลี่ยนบ่อยแทบจะทุกเดือนทุกปี บ้าไปแล้ว! คือแทนที่จะมานั่งอ่าน Web Standard ให้ตัวเองมีมาตรฐานที่แท้จริง ดันกลายเป็นว่าต้องมาเรียนวิธีทำสิ่งนึงห้าหกแบบเพราะแต่ละเครื่องมือมีวิธีที่ต่างกัน :(

ส่วนตัวเลือก Mithril ไปเพราะดูไม่คุกคามเรา ไม่ต้องเททิ้งของเก่าหรือมาตรฐานสากลที่รู้มาแล้วแล้วเรียนวิธีใหม่เพื่อให้ได้ผลลัพธ์/ประสิทธิภาพเท่าเดิมเป๊ะ ๆ ตัวอื่นจะค่อนข้างมีความคุกคาม อยากสร้าง standard เป็นของตัวเอง มีความเป็นลัทธิมากกว่าเป็นเครื่องมือ ถ้าอยากหางานทางทำเว็บก็คงไปใช้แหละนะ แต่เนื่องจากไม่ได้จะไปทางนั้น หรือถ้าไปก็คือทำเองไม่ได้หาคนจ้าง ก็เลยบอกตัวเองว่า หนีไปปปปป

Standards

แม้ทาง IT จะมีตัวเลือกเครื่องมือให้ใช้มากมาย แต่แหล่งที่จะนำไปสู่ความเทพได้อย่างแท้จริงนั้นคือการทำตาม Standards :) ซึ่งตอนนี้แหล่งข้อมูลยอดเยี่ยมตกเป็นของ
MDN (Mozilla Develper Network) Web Docs
ถ้าใครไม่สันทัดการอ่าน manual ก็คงแนะนำให้หา framework ใช้นั่นแหละเป็น safe choice แต่ถึงใช้หรือไม่ใช้ อันนี้ก็เป็นแหล่งทีดีสุด ๆ ซึ่งหากใครคุ้น ๆ ชื่อเว็บ ก็เพราะ Mozilla ทำ Mozilla Firefox นั่นเอง

- END -