วิธีสร้าง PWA หลายตัวโดยใช้ประโยชน์จากชื่อโดเมนเดียวกัน เพื่อแจ้งให้ผู้ใช้ทราบว่าตนเองเป็นขององค์กรหรือบริการเดียวกัน
ในบล็อกโพสต์เกี่ยวกับ Progressive Web App ในเว็บไซต์หลายแหล่งที่มา Demian ได้พูดถึงความท้าทายที่เว็บไซต์ที่สร้างในแหล่งที่มาหลายแห่งพบเมื่อพยายามสร้าง Progressive Web App รายการเดียวที่รวมเว็บไซต์ทั้งหมดไว้
ตัวอย่างโครงสร้างเว็บไซต์ประเภทนี้คือเว็บไซต์อีคอมเมิร์ซที่มีลักษณะดังนี้
- หน้าแรกอยู่ที่
https://www.example.com
- หน้าหมวดหมู่โฮสต์อยู่ที่
https://category.example.com
- หน้ารายละเอียดผลิตภัณฑ์ที่
https://product.example.com
ดังที่ได้กล่าวไว้ในบทความ นโยบายต้นทางเดียวกันจะกำหนดข้อจำกัดหลายประการ ซึ่งป้องกันการแชร์ Service Worker, แคช และสิทธิ์ระหว่างต้นทาง ด้วยเหตุนี้ เราขอแนะนําอย่างยิ่งให้หลีกเลี่ยงการกําหนดค่าประเภทนี้ และสำหรับผู้ที่มีเว็บไซต์ที่สร้างด้วยวิธีนี้แล้ว ให้พิจารณาย้ายข้อมูลไปยังสถาปัตยกรรมเว็บไซต์ต้นทางเดียวเมื่อเป็นไปได้
ในโพสต์นี้ เราจะดูกรณีที่ตรงข้ามกันแทน นั่นคือ เราจะวิเคราะห์กรณีของบริษัทที่ต้องการให้บริการ 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 ของตัวเองสำหรับขอบเขตที่ลงทะเบียนไว้
- สิทธิ์: สิทธิ์ยังมีขอบเขตตามต้นทางด้วย ด้วยเหตุนี้ ผู้ใช้จึงทราบได้อย่างชัดเจนว่ากำลังให้สิทธิ์บริการใดอยู่ และฟีเจอร์ต่างๆ เช่น การแจ้งเตือนจะระบุแหล่งที่มาของแอปแต่ละแอปอย่างเหมาะสม
การสร้างการแยกระดับดังกล่าวเป็นสิ่งที่ต้องการมากที่สุดใน Use Case ของ PWA อิสระหลายรายการ ดังนั้นเราขอแนะนำแนวทางนี้อย่างยิ่ง
หากแอปในโดเมนย่อยต้องการแชร์ข้อมูลในเครื่องระหว่างกัน ก็จะยังคงแชร์ผ่านคุกกี้ได้อยู่ หรือในกรณีที่เป็นสถานการณ์ขั้นสูง ก็ลองซิงค์ข้อมูลพื้นที่เก็บข้อมูลผ่านเซิร์ฟเวอร์ได้
ใช้ต้นทางเดียวกัน
แนวทางที่ 2 คือการสร้าง PWA ที่แตกต่างกันในต้นทางเดียวกัน ซึ่งรวมถึงสถานการณ์ต่อไปนี้
เส้นทางที่ไม่ซ้อนทับกัน
PWA หรือ "เว็บแอป" แนวความคิดหลายรายการที่โฮสต์ในต้นทางเดียวกันโดยมีเส้นทางที่ไม่ทับซ้อนกัน เช่น
https://example.com/app1/
https://example.com/app2/
เส้นทางซ้อน/ซ้อนกัน
PWA หลายรายการในต้นทางเดียวกัน โดยที่ขอบเขตของรายการหนึ่งฝังอยู่ภายในอีกรายการหนึ่ง
https://example.com/
("แอปภายนอก")https://example.com/app/
("แอปภายใน")
API ของ Service Worker และรูปแบบไฟล์ Manifest ช่วยให้คุณทําอย่างใดอย่างหนึ่งข้างต้นได้โดยใช้การกําหนดขอบเขตระดับเส้นทาง อย่างไรก็ตาม ไม่ว่าในกรณีใดก็ตาม การใช้ต้นทางเดียวกันจะก่อให้เกิดปัญหาและข้อจํากัดมากมาย ซึ่งเกิดจากข้อเท็จจริงที่ว่าเบราว์เซอร์จะไม่ถือว่าแอปเหล่านี้เป็น "แอป" ที่แยกกัน ดังนั้นเราไม่แนะนําให้ใช้แนวทางนี้
ในส่วนถัดไป เราจะวิเคราะห์ปัญหาเหล่านี้โดยละเอียดมากขึ้น รวมถึงสิ่งที่ทําได้หากใช้ต้นทางแยกกันไม่ได้
ความท้าทายสำหรับ PWA ที่มีต้นทางเดียวกันหลายรายการ
ปัญหาที่พบได้ทั่วไปซึ่งเกิดขึ้นกับทั้ง 2 แนวทางแบบแหล่งที่มาเดียวกันมีดังนี้
- พื้นที่เก็บข้อมูล: แอปต่างๆ จะแชร์คุกกี้ พื้นที่เก็บข้อมูลในเครื่อง และพื้นที่เก็บข้อมูลในเครื่องทุกรูปแบบ ด้วยเหตุนี้ หากผู้ใช้ตัดสินใจล้างข้อมูลในตัวเครื่องของแอปหนึ่ง จะเป็นการลบข้อมูลทั้งหมดจากต้นทาง ซึ่งจะไม่มีวิธีทำได้ในแอปเดียว โปรดทราบว่า Chrome และเบราว์เซอร์อื่นๆ จะแจ้งให้ผู้ใช้ล้างข้อมูลในเครื่องเมื่อถอนการติดตั้งแอปใดแอปหนึ่ง ซึ่งจะส่งผลกับข้อมูลของแอปอื่นๆ ในต้นทางนั้นด้วย ปัญหาอีกอย่างคือแอปจะต้องแชร์โควต้าพื้นที่เก็บข้อมูลด้วย ซึ่งหมายความว่าหากแอปใดแอปหนึ่งใช้พื้นที่มากเกินไป แอปอีกแอปจะได้รับผลกระทบเชิงลบ
- สิทธิ์: สิทธิ์ของเบราว์เซอร์จะเชื่อมโยงกับต้นทาง ซึ่งหมายความว่าหากผู้ใช้ให้สิทธ์กับแอปหนึ่ง สิทธิ์ดังกล่าวจะมีผลกับทุกแอปในต้นทางนั้นพร้อมกัน นี่อาจฟังดูเข้าท่าดี (ไม่ต้องขอสิทธิ์หลายครั้ง) แต่อย่าลืมว่าหากผู้ใช้บล็อกสิทธิ์ของแอปนั้น ก็จะทำให้ผู้ใช้รายอื่นไม่สามารถขอสิทธิ์นั้นหรือใช้ฟีเจอร์นั้นได้ โปรดทราบว่าแม้ว่าจะต้องให้สิทธิ์เบราว์เซอร์เพียงครั้งเดียวต่อการให้สิทธิ์ต้นทาง แต่สิทธิ์ระดับระบบจะต้องให้สิทธิ์เพียงครั้งเดียวต่อแอป ไม่ว่าแอปหลายแอปจะชี้ไปยังต้นทางเดียวกันหรือไม่ก็ตาม
- การตั้งค่าผู้ใช้: การตั้งค่าจะตั้งค่าตามต้นทางด้วย ตัวอย่างเช่น หากแอป 2 แอปมีขนาดตัวอักษรต่างกัน และผู้ใช้ต้องการปรับการซูมแอปเพียงแอปเดียวเพื่อชดเชย
ปัญหาเหล่านี้ทำให้การส่งเสริมแนวทางนี้เป็นเรื่องยาก อย่างไรก็ตาม หากใช้ต้นทางแยกต่างหากไม่ได้ (เช่น ซับโดเมน) ตามที่อธิบายไว้ในส่วนการใช้ต้นทางแยกต่างหาก จากตัวเลือกต้นทางเดียวกัน 2 รายการที่เรานำเสนอ เราขอแนะนําอย่างยิ่งให้ใช้เส้นทางที่ไม่ทับซ้อนกันแทนเส้นทางที่ทับซ้อนกัน/ซ้อนกัน
ดังที่ได้กล่าวไปแล้ว ปัญหาที่กล่าวถึงในส่วนนี้เกิดขึ้นได้กับทั้ง 2 วิธีข้างต้น ในส่วนถัดไป เราจะเจาะลึกรายละเอียด ว่าเหตุใดการใช้เส้นทางที่ทับซ้อนกัน/ซ้อนกันจึงเป็นกลยุทธ์ที่แนะนำน้อยที่สุด
ปัญหาเพิ่มเติมสำหรับเส้นทางที่ซ้อนทับ/ซ้อนกัน
ปัญหาเพิ่มเติมเกี่ยวกับแนวทางเส้นทางที่ซ้อนทับ/ฝัง (โดยที่ https://example.com/
เป็นแอปด้านนอกและ https://example.com/app/
เป็นแอปด้านใน) คือ URL ทั้งหมดในแอปด้านในจะถือว่าเป็นส่วนหนึ่งของทั้งแอปด้านนอกและแอปด้านใน
ในทางปฏิบัติ ปัญหาที่อาจเกิดขึ้นมีดังนี้
- โปรโมชันการติดตั้ง: หากผู้ใช้เข้าชมแอปด้านใน (เช่น ในเว็บเบราว์เซอร์) เมื่อติดตั้งแอปด้านนอกในอุปกรณ์ของผู้ใช้แล้ว เบราว์เซอร์จะไม่แสดงแบนเนอร์โปรโมชันการติดตั้ง และเหตุการณ์ BeforeInstallPrompt จะไม่ทริกเกอร์ สาเหตุคือเบราว์เซอร์จะตรวจสอบว่าหน้าปัจจุบันเป็นของแอปที่ติดตั้งไว้แล้วหรือไม่ และสรุปว่าใช่ วิธีแก้ปัญหานี้คือให้ติดตั้งแอปภายในด้วยตนเอง (ผ่านตัวเลือกเมนู "สร้างทางลัด" ของเบราว์เซอร์) หรือติดตั้งแอปภายในก่อนแอปภายนอก
- การแจ้งเตือนและ Badging API: หากติดตั้งแอปด้านนอกแล้ว แต่ไม่ได้ติดตั้งแอปด้านใน การแจ้งเตือนและป้ายที่มาจากแอปด้านในจะได้รับการระบุแหล่งที่มาเป็นแอปด้านนอกอย่างไม่ถูกต้อง (ซึ่งเป็นขอบเขตที่ใกล้ที่สุดของแอปที่ติดตั้ง) ฟีเจอร์นี้จะทำงานอย่างถูกต้องในกรณีที่ติดตั้งทั้ง 2 แอปในอุปกรณ์ของผู้ใช้
- การบันทึกลิงก์: แอปภายนอกอาจบันทึก URL ที่เป็นของแอปภายใน ซึ่งเป็นไปได้อย่างยิ่งหากติดตั้งแอปด้านนอกแล้วแต่ไม่มีแอปภายใน ในทํานองเดียวกัน ลิงก์ภายในแอปภายนอกที่ลิงก์ไปยังแอปภายในจะไม่บันทึกลิงก์ไปยังแอปภายใน เนื่องจากระบบจะถือว่าลิงก์ดังกล่าวอยู่ภายในขอบเขตของแอปภายนอก นอกจากนี้ ใน ChromeOS และ Android หากแอปเหล่านี้เพิ่มลงใน Play Store (เป็นกิจกรรมบนเว็บที่เชื่อถือได้) แอปภายนอกจะบันทึกลิงก์ทั้งหมด แม้ว่าจะติดตั้งแอปภายในแล้ว แต่ระบบปฏิบัติการจะยังคงให้ตัวเลือกแก่ผู้ใช้ในการเปิดแอปภายในในแอปภายนอก
บทสรุป
ในบทความนี้เราพูดถึงวิธีต่างๆ ที่นักพัฒนาแอปสามารถสร้าง 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