วิธีสร้าง PWA หลายรายการโดยใช้ชื่อโดเมนเดียวกันเพื่อให้ผู้ใช้ทราบว่าแอปเหล่านั้นเป็นขององค์กรหรือบริการเดียวกัน
ในบล็อกโพสต์ Progressive Web App ในเว็บไซต์แบบหลายต้นทาง เดเมียนได้กล่าวถึงความท้าทายที่เว็บไซต์ซึ่งสร้างขึ้นในหลายต้นทางต้องเผชิญเมื่อพยายามสร้าง Progressive Web App เดียวที่ครอบคลุมทั้งหมด
ตัวอย่างของโครงสร้างเว็บไซต์ประเภทนี้คือเว็บไซต์อีคอมเมิร์ซที่มีลักษณะดังนี้
- หน้าแรกอยู่ที่
https://www.example.com
- หน้าหมวดหมู่โฮสต์อยู่ที่
https://category.example.com
- หน้ารายละเอียดผลิตภัณฑ์ที่
https://product.example.com
ดังที่ได้กล่าวไว้ในบทความ นโยบายต้นทางเดียวกัน กำหนดข้อจำกัดหลายประการ ซึ่งป้องกันการแชร์ Service Worker, แคช และสิทธิ์ในต้นทางต่างๆ ด้วยเหตุนี้ เราจึงขอแนะนำเป็นอย่างยิ่ง ให้หลีกเลี่ยงการกำหนดค่าประเภทนี้ และสำหรับผู้ที่มีเว็บไซต์ ที่สร้างในลักษณะนี้อยู่แล้ว ให้พิจารณาย้ายข้อมูลไปยังสถาปัตยกรรมเว็บไซต์แบบต้นทางเดียว เมื่อใดก็ตามที่เป็นไปได้

ในโพสต์นี้ เราจะมาดูกรณีตรงกันข้ามกัน นั่นคือแทนที่จะเป็น PWA เดียว ในต้นทางต่างๆ เราจะวิเคราะห์กรณีของบริษัทที่ต้องการ ให้บริการ PWA หลายรายการ โดยใช้ชื่อโดเมนเดียวกัน และทำให้ ผู้ใช้ทราบว่า PWA เหล่านี้เป็นขององค์กรหรือบริการเดียวกัน
คุณอาจสังเกตเห็นว่าเราใช้คำที่แตกต่างกันแต่มีความเกี่ยวข้องกัน เช่น โดเมนและต้นทาง ก่อนดำเนินการต่อ เรามาทบทวนแนวคิดเหล่านี้กัน
คำศัพท์ทางเทคนิค
- โดเมน: ลำดับป้ายกำกับใดก็ได้ตามที่กำหนดไว้ในระบบชื่อโดเมน (DNS)
เช่น
com
และexample.com
คือโดเมน - ชื่อโฮสต์: รายการ DNS ที่แปลงเป็นที่อยู่ IP อย่างน้อย 1 รายการ ตัวอย่างเช่น
www.example.com
จะเป็นชื่อโฮสต์example.com
อาจเป็นชื่อโฮสต์หากมีที่อยู่ IP และcom
จะไม่สามารถแก้ไขเป็นที่อยู่ IP ได้ จึงไม่สามารถเป็นชื่อโฮสต์ได้ - ต้นทาง: ชุดค่าผสมของรูปแบบ ชื่อโฮสต์ และพอร์ต (ไม่บังคับ) เช่น
https://www.example.com:443
เป็นต้นทาง
นโยบายต้นทางเดียวกัน กำหนดข้อจำกัดเกี่ยวกับต้นทางตามชื่อของนโยบาย ดังนั้นเราจะใช้คำนี้เป็นส่วนใหญ่ตลอดทั้งบทความ อย่างไรก็ตาม เราจะใช้ "โดเมน" หรือ "โดเมนย่อย" เป็นครั้งคราวเพื่ออธิบายเทคนิคที่ใช้ในการสร้าง "ต้นทาง" ที่แตกต่างกัน
กรณีที่ต้องมี PWA หลายรายการที่เกี่ยวข้อง
ในบางกรณี คุณอาจต้องการสร้างแอปอิสระ แต่ยังคงระบุว่าแอปเหล่านั้น เป็นขององค์กรหรือ "แบรนด์" เดียวกัน การใช้ชื่อ โดเมนเดียวกันซ้ำเป็นวิธีที่ดีในการสร้างความสัมพันธ์ดังกล่าว เช่น
- เว็บไซต์อีคอมเมิร์ซต้องการสร้างประสบการณ์การใช้งานแบบสแตนด์อโลนเพื่อให้ผู้ขาย จัดการสินค้าคงคลังได้ ในขณะเดียวกันก็ต้องทำให้ผู้ขายเข้าใจว่าประสบการณ์การใช้งานนี้เป็นส่วนหนึ่งของ เว็บไซต์หลักที่ผู้ใช้ซื้อผลิตภัณฑ์
- เว็บไซต์ข่าวสารกีฬาต้องการสร้างแอปเฉพาะสำหรับมหกรรมกีฬาที่สำคัญ เพื่อให้ผู้ใช้รับสถิติเกี่ยวกับการแข่งขันที่ชื่นชอบผ่าน การแจ้งเตือน และติดตั้งเป็น Progressive Web App พร้อมทั้งตรวจสอบว่า ผู้ใช้ทราบว่าเป็นแอปที่สร้างโดยบริษัทข่าว
- บริษัทต้องการสร้างแอปแชท อีเมล และปฏิทินแยกกัน และต้องการให้แอปเหล่านี้ ทำงานเป็นแอปแต่ละแอปที่เชื่อมโยงกับชื่อของบริษัท

การใช้ต้นทางแยกกัน
แนวทางที่แนะนําในกรณีเช่นนี้คือให้แต่ละแอปที่แตกต่างกันในเชิงแนวคิด ทํางานในต้นทางของตัวเอง
หากต้องการใช้ชื่อโดเมนเดียวกันในทุกเว็บไซต์ คุณสามารถทำได้โดย
ใช้โดเมนย่อย ตัวอย่างเช่น บริษัทที่ให้บริการแอปหรือ
บริการอินเทอร์เน็ตหลายอย่างสามารถโฮสต์แอปอีเมลที่ https://mail.example.com
และแอปปฏิทินที่
https://calendar.example.com
ขณะเดียวกันก็ให้บริการหลักของ
ธุรกิจที่ https://www.example.com
อีกตัวอย่างหนึ่งคือเว็บไซต์กีฬาที่
ต้องการสร้างแอปอิสระที่ทุ่มเทให้กับ
การแข่งขันกีฬาที่สำคัญอย่างสมบูรณ์ เช่น การแข่งขันฟุตบอลชิงแชมป์ที่ https://footballcup.example.com
ซึ่ง
ผู้ใช้สามารถติดตั้งและใช้งานแยกจากเว็บไซต์กีฬาหลักที่โฮสต์อยู่ที่
https://www.example.com
แนวทางนี้อาจเป็นประโยชน์สำหรับแพลตฟอร์มที่
อนุญาตให้ลูกค้าสร้างแอปอิสระของตนเองภายใต้แบรนด์ของบริษัทด้วย
เช่น แอปที่ช่วยให้ผู้ขายสร้าง PWA ของตนเองได้ที่
https://merchant1.example.com
, https://merchant2.example.com
ฯลฯ
การใช้ต้นทางที่แตกต่างกันช่วยให้มั่นใจได้ว่าแอปจะแยกกัน ซึ่งหมายความว่า แต่ละแอปจะจัดการฟีเจอร์ต่างๆ ของเบราว์เซอร์ได้อย่างอิสระ ซึ่งรวมถึง
- ความสามารถในการติดตั้ง: แอปแต่ละแอปมีไฟล์ Manifest ของตัวเองและมอบประสบการณ์การติดตั้งของตัวเอง
- พื้นที่เก็บข้อมูล: แอปแต่ละแอปจะมีแคช พื้นที่เก็บข้อมูลในเครื่อง และพื้นที่เก็บข้อมูลในเครื่องของอุปกรณ์ทุกรูปแบบโดยไม่ต้องแชร์กับแอปอื่นๆ
- Service Worker: แอปแต่ละแอปจะมี Service Worker ของตัวเองสำหรับขอบเขตที่ลงทะเบียน ไว้
- สิทธิ์: สิทธิ์ยังกำหนดขอบเขตตามต้นทางด้วย ด้วยเหตุนี้ ผู้ใช้จึง ทราบได้อย่างชัดเจนว่าตนให้สิทธิ์แก่บริการใด และ ระบบจะระบุแหล่งที่มาของฟีเจอร์ต่างๆ เช่น การแจ้งเตือน ให้กับแต่ละแอปอย่างถูกต้อง
การสร้างระดับการแยกดังกล่าวเป็นสิ่งที่พึงประสงค์มากที่สุดในกรณีการใช้งาน PWA หลายรายการที่ทำงานแยกกัน ดังนั้นเราขอแนะนำแนวทางนี้เป็นอย่างยิ่ง
หากแอปในโดเมนย่อยต้องการแชร์ข้อมูลในเครื่องกับแอปอื่นๆ ก็ยังทำได้ผ่านคุกกี้ หรือในกรณีที่ซับซ้อนมากขึ้นก็อาจพิจารณาซิงค์ที่เก็บข้อมูลผ่านเซิร์ฟเวอร์

การใช้ต้นทางเดียวกัน
แนวทางที่ 2 คือการสร้าง PWA ที่แตกต่างกันในต้นทางเดียวกัน ซึ่งรวมถึงสถานการณ์ต่อไปนี้
เส้นทางที่ไม่ทับซ้อนกัน
PWA หรือ "เว็บแอป" เชิงแนวคิดหลายรายการที่โฮสต์ในต้นทางเดียวกันโดยมี เส้นทางที่ไม่ทับซ้อนกัน เช่น
https://example.com/app1/
https://example.com/app2/
เส้นทางที่ซ้อนทับ/ซ้อนกัน
PWA หลายรายการในต้นทางเดียวกัน โดยมีขอบเขตหนึ่งซ้อนอยู่ภายในอีกขอบเขตหนึ่ง
https://example.com/
("แอปภายนอก")https://example.com/app/
("แอปภายใน")
API ของ Service Worker และรูปแบบไฟล์ Manifest ช่วยให้คุณทำอย่างใดอย่างหนึ่งข้างต้นได้ โดยใช้การกำหนดขอบเขตระดับเส้นทาง อย่างไรก็ตาม ในทั้ง 2 กรณี การใช้ต้นทางเดียวกันจะทำให้เกิดปัญหาและข้อจำกัดมากมาย ซึ่งมีสาเหตุมาจากข้อเท็จจริงที่ว่าเบราว์เซอร์จะไม่ถือว่าสิ่งเหล่านี้เป็น "แอป" ที่แตกต่างกันอย่างแท้จริง ดังนั้นเราจึงไม่แนะนำให้ใช้วิธีนี้

ในส่วนถัดไป เราจะวิเคราะห์ความท้าทายเหล่านี้โดยละเอียด รวมถึงสิ่งที่จะทำได้หากการใช้ต้นทางแยกกันไม่ใช่ตัวเลือก
ความท้าทายสำหรับ PWA หลายรายการที่มีต้นทางเดียวกัน
ปัญหาที่พบบ่อยในการใช้งานจริงของทั้ง 2 วิธีการแบบโดเมนเดียวกันมีดังนี้
- พื้นที่เก็บข้อมูล: คุกกี้, พื้นที่เก็บข้อมูลในเครื่อง และพื้นที่เก็บข้อมูลในเครื่องของอุปกรณ์ทุกรูปแบบจะ แชร์ระหว่างแอป ด้วยเหตุนี้ หากผู้ใช้ตัดสินใจที่จะล้างข้อมูลในเครื่อง สำหรับแอปหนึ่ง ระบบจะล้างข้อมูลทั้งหมดจากต้นทาง และไม่มีวิธี ดำเนินการนี้สำหรับแอปเดียว โปรดทราบว่า Chrome และเบราว์เซอร์อื่นๆ บางตัว จะแจ้งให้ผู้ใช้ล้างข้อมูลในเครื่องเมื่อถอนการติดตั้งแอปใดแอปหนึ่ง และการดำเนินการนี้จะมีผลกับข้อมูลของแอปอื่นๆ ในต้นทางด้วย อีกปัญหาหนึ่งคือแอปจะต้องแชร์โควต้า พื้นที่เก็บข้อมูลด้วย ซึ่งหมายความว่าหากแอปใดแอปหนึ่งใช้พื้นที่มากเกินไป อีกแอปหนึ่งจะได้รับผลกระทบในทางลบ
- สิทธิ์: สิทธิ์ของเบราว์เซอร์จะเชื่อมโยงกับต้นทาง ซึ่งหมายความว่าหากผู้ใช้ให้สิทธิ์แก่แอปหนึ่ง สิทธิ์นั้นจะมีผลกับแอปทั้งหมดในต้นทางนั้นพร้อมกัน ซึ่งอาจฟังดูเหมือนเป็นเรื่องดี (ไม่ต้องขอสิทธิ์หลายครั้ง) แต่โปรดทราบว่าหากผู้ใช้บล็อกสิทธิ์ของแอปหนึ่ง แอปอื่นๆ จะขอสิทธิ์นั้นหรือใช้ฟีเจอร์นั้นไม่ได้ โปรดทราบว่าแม้ว่าสิทธิ์ของเบราว์เซอร์จะได้รับเพียงครั้งเดียวต่อต้นทาง แต่สิทธิ์ระดับระบบจะต้องได้รับเพียงครั้งเดียวต่อแอป ไม่ว่าแอปหลายแอปจะชี้ไปยังต้นทางเดียวกันหรือไม่ก็ตาม
- การตั้งค่าผู้ใช้: การตั้งค่าจะกำหนดต่อต้นทางด้วย เช่น หากแอป 2 แอป มีขนาดแบบอักษรต่างกัน และผู้ใช้ต้องการปรับการซูมในแอปใดแอปหนึ่ง เพื่อชดเชยขนาดแบบอักษร ผู้ใช้จะทำไม่ได้หากไม่ใช้ การตั้งค่ากับแอปอื่นๆ ด้วย
ความท้าทายเหล่านี้ทำให้การสนับสนุนแนวทางนี้เป็นเรื่องยาก อย่างไรก็ตาม หากคุณใช้ต้นทางแยกต่างหากไม่ได้ (เช่น โดเมนย่อย) ตามที่อธิบายไว้ในส่วนการใช้ต้นทางแยกต่างหาก จากตัวเลือกต้นทางเดียวกัน 2 รายการที่เรานำเสนอ เราขอแนะนำอย่างยิ่งให้ใช้เส้นทางที่ไม่ทับซ้อนกันแทนเส้นทางที่ทับซ้อนกัน/ซ้อนกัน
ดังที่กล่าวไปแล้ว ความท้าทายที่กล่าวถึงในส่วนนี้เป็นความท้าทายที่พบได้ทั่วไปในทั้ง 2 วิธีการแบบ Same-Origin ในส่วนถัดไป เราจะเจาะลึกรายละเอียด ว่าเหตุใดการใช้เส้นทางที่ทับซ้อนกัน/ซ้อนกันจึงเป็นกลยุทธ์ที่แนะนําน้อยที่สุด
ความท้าทายเพิ่มเติมสำหรับเส้นทางที่ซ้อนทับ/ซ้อนกัน
ปัญหาเพิ่มเติมเกี่ยวกับแนวทางเส้นทางที่ซ้อนทับ/ซ้อนกัน (โดยที่
https://example.com/
คือแอปภายนอกและ https://example.com/app/
คือ
แอปภายใน) คือ URL ทั้งหมดในแอปภายในจะถือเป็น
ส่วนหนึ่งของทั้งแอปภายนอกและแอปภายใน
ในทางปฏิบัติ ปัญหานี้ทำให้เกิดปัญหาต่อไปนี้
- โปรโมชันการติดตั้ง: หากผู้ใช้เข้าชมแอปภายใน (เช่น ในเว็บเบราว์เซอร์) เมื่อติดตั้งแอปภายนอกไว้ในอุปกรณ์ของผู้ใช้แล้ว เบราว์เซอร์จะไม่แสดงแบนเนอร์โปรโมชันการติดตั้ง และจะไม่ทริกเกอร์เหตุการณ์ BeforeInstallPrompt เนื่องจากเบราว์เซอร์จะตรวจสอบว่าหน้าปัจจุบันเป็นของแอปที่ติดตั้งไว้แล้วหรือไม่ และจะสรุปว่าใช่ วิธีแก้ปัญหานี้คือการติดตั้งแอปด้านในด้วยตนเอง (ผ่านตัวเลือกเมนูเบราว์เซอร์ "สร้างทางลัด") หรือติดตั้งแอปด้านในก่อนแอปด้านนอก
- การแจ้งเตือน และ Badging API: หากติดตั้งแอปภายนอกแล้วแต่ไม่ได้ติดตั้งแอปภายใน ระบบจะระบุแหล่งที่มาของการแจ้งเตือนและป้ายที่มาจากแอปภายในอย่างไม่ถูกต้องว่าเป็นของแอปภายนอก (ซึ่งเป็นขอบเขตที่ใกล้ที่สุดของแอปที่ติดตั้ง) ฟีเจอร์นี้จะทำงานอย่างถูกต้องในกรณีที่ติดตั้งทั้ง 2 แอปในอุปกรณ์ของผู้ใช้
- การดักจับลิงก์: แอปภายนอกอาจดักจับ URL ที่เป็นของแอปภายใน ซึ่งมีแนวโน้มที่จะเกิดขึ้น โดยเฉพาะอย่างยิ่งหากมีการติดตั้งแอปภายนอกแต่ไม่ได้ติดตั้งแอปภายใน ในทำนองเดียวกัน ลิงก์ภายในแอปภายนอกที่ลิงก์ไปยังแอปภายในจะไม่ จับลิงก์ไปยังแอปภายใน เนื่องจากถือว่าอยู่ในขอบเขตของแอปภายนอก นอกจากนี้ ใน ChromeOS และ Android หากมีการเพิ่มแอปเหล่านี้ลงใน Play Store (เป็น Trusted Web Activities) แอปด้านนอกจะจับลิงก์ทั้งหมด แม้ว่าจะติดตั้งแอปด้านในแล้ว แต่ระบบปฏิบัติการจะยังคงให้ผู้ใช้เลือกเปิดแอปในแอปด้านนอก
บทสรุป
ในบทความนี้ เราได้ดูวิธีต่างๆ ที่นักพัฒนาแอปสามารถสร้าง Progressive Web App หลายรายการที่เกี่ยวข้องซึ่งกันและกันภายในโดเมนเดียวกัน
โดยสรุป เราขอแนะนำอย่างยิ่งให้ใช้ต้นทางอื่น (เช่น ใช้โดเมนย่อย) เพื่อโฮสต์ PWA ที่เป็นอิสระ การโฮสต์ในต้นทางเดียวกันทำให้เกิดความท้าทายมากมาย เนื่องจากเบราว์เซอร์จะไม่พิจารณาว่า แอปเหล่านี้เป็นแอปที่แตกต่างกันอย่างเต็มที่
- ต้นทางที่แยกกัน: แนะนำ
- เส้นทางเดียวกันที่ไม่ทับซ้อนกัน: ไม่แนะนำ
- ต้นทางเดียวกัน เส้นทางที่ซ้อนทับ/ซ้อนกัน: ไม่แนะนำอย่างยิ่ง
หากไม่สามารถใช้ต้นทางที่แตกต่างกันได้ เราขอแนะนำอย่างยิ่งให้ใช้เส้นทางที่ไม่ทับซ้อนกัน (เช่น https://example.com/app1/
และ https://example.com/app2/
) แทนการใช้เส้นทางที่ทับซ้อนกันหรือซ้อนกัน เช่น https://example.com/
(สำหรับแอปภายนอก) และ https://example.com/app/
(สำหรับแอปภายใน)
แหล่งข้อมูลเพิ่มเติม
ขอขอบคุณJoe Medley, Dominick Ng, Alan Cutter, Daniel Murphy, Penny McLachlan, Thomas Steiner และ Darwin Huang ที่ช่วยตรวจสอบด้านเทคนิคและให้คำแนะนำ
รูปภาพโดย Tim Mossholder ใน Unsplash