การสร้าง Progressive Web App หลายรายการในโดเมนเดียวกัน

วิธีสร้าง PWA หลายรายการโดยใช้ชื่อโดเมนเดียวกันเพื่อให้ผู้ใช้ทราบว่า PWA เหล่านั้นมาจากองค์กรหรือบริการเดียวกัน

Chase Phillips
Matt Giuca
Matt Giuca

ในบล็อกโพสต์เกี่ยวกับ Progressive Web App ในเว็บไซต์หลายแหล่งที่มา Demian ได้พูดถึงความท้าทายที่เว็บไซต์ที่สร้างในแหล่งที่มาหลายแห่งพบเมื่อพยายามสร้าง Progressive Web App รายการเดียวที่รวมเว็บไซต์ทั้งหมดไว้

ตัวอย่างโครงสร้างเว็บไซต์ประเภทนี้คือเว็บไซต์อีคอมเมิร์ซที่มีลักษณะดังนี้

  • หน้าแรกอยู่ที่ https://www.example.com
  • หน้าหมวดหมู่โฮสต์อยู่ที่ https://category.example.com
  • หน้ารายละเอียดผลิตภัณฑ์ที่ https://product.example.com

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

แผนภาพแสดงเว็บไซต์ที่แบ่งออกเป็นหลายต้นทางและแสดงให้เห็นว่าเราไม่แนะนําให้ใช้เทคนิคนี้เมื่อสร้าง PWA
หลีกเลี่ยงการใช้ต้นทางที่แตกต่างกันสำหรับส่วนต่างๆ ของเว็บไซต์เดียวกันเมื่อพยายามสร้าง Progressive Web App แบบรวม

ในโพสต์นี้ เราจะดูกรณีที่ตรงข้ามกันแทน นั่นคือ เราจะวิเคราะห์กรณีของบริษัทที่ต้องการให้บริการ PWA หลายรายการ โดยใช้ประโยชน์จากชื่อโดเมนเดียวกัน และทำให้ผู้ใช้ทราบว่า PWA เหล่านั้นเป็นขององค์กรหรือบริการเดียวกัน

คุณอาจสังเกตเห็นว่าเราใช้คําที่ต่างกันแต่มีความเกี่ยวข้องกัน เช่น โดเมนและต้นทาง ก่อนดำเนินการต่อ เรามาทบทวนแนวคิดเหล่านี้กัน

คําศัพท์ทางเทคนิค

  • โดเมน: ลําดับป้ายกํากับตามที่ระบุไว้ในระบบชื่อโดเมน (DNS) เช่น com และ example.com คือโดเมน
  • ชื่อโฮสต์: รายการ DNS ที่แปลเป็นที่อยู่ IP อย่างน้อย 1 รายการ ตัวอย่างเช่น www.example.com จะเป็นชื่อโฮสต์, example.com อาจเป็นชื่อโฮสต์ได้หากมีที่อยู่ IP และ com จะแก้ไขเป็นที่อยู่ IP ไม่ได้ จึงจะเป็นชื่อโฮสต์ไม่ได้
  • ต้นทาง: ชุดค่าผสมของรูปแบบ ชื่อโฮสต์ และพอร์ต (ไม่บังคับ) เช่น https://www.example.com:443 เป็นต้นทาง

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

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

  • เว็บไซต์อีคอมเมิร์ซต้องการสร้างประสบการณ์การใช้งานแบบสแตนด์อโลนเพื่อให้ผู้ขายจัดการสินค้าคงคลังได้ ในขณะเดียวกันก็ช่วยให้ผู้ขายเข้าใจว่าเว็บไซต์ดังกล่าวเป็นส่วนหนึ่งของเว็บไซต์หลักที่ผู้ใช้ซื้อผลิตภัณฑ์
  • เว็บไซต์ข่าวกีฬาต้องการสร้างแอปเฉพาะสำหรับการแข่งขันกีฬาที่สำคัญ เพื่อให้ผู้ใช้ได้รับสถิติเกี่ยวกับการแข่งขันที่ชื่นชอบผ่านการแจ้งเตือน และติดตั้งแอปเป็น Progressive Web App ในขณะเดียวกันก็ทำให้ผู้ใช้ทราบว่าแอปดังกล่าวเป็นแอปที่บริษัทข่าวสร้างขึ้น
  • บริษัทต้องการสร้างแอปแชท อีเมล และปฏิทินแยกกันและต้องการให้แอปดังกล่าวทำงานเป็นแอปเดี่ยวๆ ที่เชื่อมโยงกับชื่อบริษัท
หลีกเลี่ยงการใช้ต้นทางที่แตกต่างกันสำหรับส่วนต่างๆ ของเว็บไซต์เดียวกันเมื่อพยายามสร้าง Progressive Web App แบบรวม
บริษัทที่เป็นเจ้าของ example.com ต้องการให้บริการแอปหรือ PWA อิสระ 3 แอปโดยใช้ชื่อโดเมนเดียวกันเพื่อสร้างความสัมพันธ์ระหว่างแอปหรือ PWA เหล่านั้น

การใช้ต้นทางแยกต่างหาก

แนวทางที่แนะนําในกรณีเช่นนี้คือให้แต่ละแอปที่แตกต่างกันในเชิงแนวคิดเผยแพร่อยู่ในแหล่งที่มาของตนเอง

หากต้องการใช้ชื่อโดเมนเดียวกันในโดเมนย่อยทั้งหมด ให้ใช้โดเมนย่อย ตัวอย่างเช่น บริษัทที่ให้บริการแอปหรือบริการอินเทอร์เน็ตหลายรายการสามารถโฮสต์แอปอีเมลที่ 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 อิสระหลายรายการ ดังนั้นเราขอแนะนำแนวทางนี้อย่างยิ่ง

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

ALT_TEXT_HERE
การสร้าง PWA ที่แตกต่างกันในต้นทางที่แตกต่างกันโดยใช้โดเมนย่อยเป็นแนวทางปฏิบัติแนะนำ

ใช้ต้นทางเดียวกัน

แนวทางที่ 2 คือการสร้าง PWA ที่แตกต่างกันในต้นทางเดียวกัน ซึ่งรวมถึงกรณีต่อไปนี้

เส้นทางที่ไม่ทับซ้อนกัน

PWA หรือ "เว็บแอป" แนวความคิดหลายรายการที่โฮสต์ในต้นทางเดียวกันโดยมีเส้นทางที่ไม่ทับซ้อนกัน เช่น

  • https://example.com/app1/
  • https://example.com/app2/

เส้นทางที่ซ้อนทับ/ซ้อนกัน

PWA หลายรายการในต้นทางเดียวกัน โดยที่ขอบเขตของรายการหนึ่งฝังอยู่ภายในอีกรายการหนึ่ง

  • https://example.com/ ("แอปภายนอก")
  • https://example.com/app/ ("แอปภายใน")

API ของ Service Worker และรูปแบบไฟล์ Manifest ช่วยให้คุณทําอย่างใดอย่างหนึ่งข้างต้นได้โดยใช้การกําหนดขอบเขตระดับเส้นทาง อย่างไรก็ตาม ไม่ว่าในกรณีใดก็ตาม การใช้ต้นทางเดียวกันจะทำให้เกิดปัญหาและข้อจํากัดมากมาย ซึ่งเกิดจากข้อเท็จจริงที่ว่าเบราว์เซอร์จะไม่ถือว่าแอปเหล่านี้เป็น "แอป" ที่แยกกัน ดังนั้นเราไม่แนะนําให้ใช้แนวทางนี้

ALT_TEXT_HERE
เราไม่แนะนำให้ใช้เส้นทาง (ทับซ้อนกันหรือไม่) เพื่อให้บริการ PWA อิสระ 2 รายการ ("app1" "app2") ภายใต้ต้นทางเดียวกัน

ในส่วนถัดไป เราจะวิเคราะห์ปัญหาเหล่านี้โดยละเอียดมากขึ้น รวมถึงสิ่งที่ทําได้หากใช้ต้นทางแยกกันไม่ได้

ปัญหาของ 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