วิธีสร้าง PWA หลายรายการโดยใช้ชื่อโดเมนเดียวกันเพื่อให้ผู้ใช้ทราบว่าเป็นองค์กรหรือบริการเดียวกัน
ในบล็อกโพสต์ของ Progressive Web App ในเว็บไซต์ที่มีหลายต้นทาง Demian พูดถึงความท้าทายที่เว็บไซต์ที่สร้างขึ้นจากต้นทางหลายแห่งต้องเผชิญเมื่อพยายามสร้าง Progressive Web App แอปเดียวที่ครอบคลุมทุกต้นทางนั้น
ตัวอย่างของสถาปัตยกรรมเว็บไซต์ประเภทนี้คือเว็บไซต์อีคอมเมิร์ซซึ่ง:
- หน้าแรกอยู่ที่
https://www.example.com
- หน้าหมวดหมู่โฮสต์อยู่ที่
https://category.example.com
- หน้ารายละเอียดผลิตภัณฑ์ที่
https://product.example.com
ตามที่ได้กล่าวไว้ในบทความนี้ นโยบายต้นทางเดียวกันกำหนดข้อจำกัดหลายอย่าง ซึ่งจะป้องกันการแชร์โปรแกรมทำงานของบริการ แคช และสิทธิ์ข้ามต้นทาง ด้วยเหตุนี้ เราจึงขอแนะนำอย่างยิ่งให้หลีกเลี่ยงการกำหนดค่าประเภทนี้ และสำหรับผู้ที่มีเว็บไซต์ที่สร้างขึ้นในลักษณะนี้อยู่แล้ว ให้พิจารณาย้ายข้อมูลไปยังสถาปัตยกรรมเว็บไซต์ต้นทางเดียวเมื่อเป็นไปได้
![แผนภาพที่แสดงเว็บไซต์ในต้นทางหลายแห่ง และแสดงให้เห็นว่าการสร้าง PWA ไม่แนะนำให้ใช้เทคนิคดังกล่าว](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/diagram-showing-site-div-64e98fc6031ee.png?authuser=5&hl=th)
ในโพสต์นี้ เราจะพิจารณากรณีตรงกันข้าม คือแทนที่จะวิเคราะห์ 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 ในขณะเดียวกันก็ต้องดูแลให้ผู้ใช้จดจำว่าเป็นแอปที่สร้างโดยบริษัทข่าว
- บริษัทแห่งหนึ่งต้องการสร้างแอปแชท อีเมล และปฏิทินแยกกัน และต้องการให้แอปทำงานเป็นคนละแอปกับชื่อบริษัท
![หลีกเลี่ยงการใช้ต้นทางที่ต่างกันสำหรับส่วนเว็บไซต์ของเว็บไซต์เดียวกันเมื่อพยายามสร้าง Progresive Web App แบบรวม](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/avoid-using-different-ori-d78df43acb88b.png?authuser=5&hl=th)
การใช้ต้นทางแยกกัน
แนวทางที่แนะนำในกรณีเช่นนี้คือการใช้กับแอปแต่ละแอปที่มีแนวคิดแตกต่างกันซึ่งมาจากต้นทางของตนเอง
หากต้องการใช้ชื่อโดเมนเดียวกันในทุกโดเมน ก็ทำได้โดยใช้โดเมนย่อย ตัวอย่างเช่น บริษัทที่ให้บริการแอปหรือบริการทางอินเทอร์เน็ตหลายแอปสามารถโฮสต์แอปอีเมลใน 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 อิสระหลายรายการ เราจึงขอแนะนำแนวทางนี้
หากแอปในโดเมนย่อยต้องการแชร์ข้อมูลในเครื่องให้แก่กันและกัน แอปก็จะยังคงทำได้ผ่านคุกกี้ หรือสำหรับสถานการณ์ขั้นสูงขึ้น แอปเหล่านั้นอาจพิจารณาซิงค์ข้อมูลพื้นที่เก็บข้อมูลผ่านเซิร์ฟเวอร์
![ALT_TEXT_HERE](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/alttexthere-699ea17734325.png?authuser=5&hl=th)
ใช้ต้นทางเดียวกัน
วิธีที่ 2 คือการสร้าง PWA ที่ต่างกันบนต้นทางเดียวกัน ซึ่งรวมถึงสถานการณ์ต่อไปนี้
เส้นทางที่ไม่ซ้อนทับกัน
PWA หลายรายการหรือ "เว็บแอป" เชิงแนวคิดที่ฝากไว้ในต้นทางเดียวกันโดยมีเส้นทางที่ไม่ซ้อนทับกัน เช่น
https://example.com/app1/
https://example.com/app2/
เส้นทางที่ทับซ้อนกัน/ซ้อนกัน
PWA หลายรายการบนต้นทางเดียวกัน โดยหนึ่งในขอบเขตนั้นฝังอยู่ในอีกจุดหนึ่ง ดังนี้
https://example.com/
("แอปภายนอก")https://example.com/app/
("แอปภายใน")
รูปแบบ Service Worker API และไฟล์ Manifest ช่วยให้คุณทำอย่างใดอย่างหนึ่งข้างต้นได้โดยใช้การกำหนดขอบเขตระดับเส้นทาง อย่างไรก็ตาม ในทั้ง 2 กรณี การใช้ต้นทางเดียวกันจะก่อให้เกิดปัญหาและข้อจำกัดต่างๆ มากมาย สาเหตุของปัญหานี้เกิดจากข้อเท็จจริงที่ว่าเบราว์เซอร์จะไม่ถือว่าแอปเหล่านี้เป็น "แอป" ที่แตกต่างกันโดยสิ้นเชิง เราจึงไม่แนะนำให้ใช้วิธีการนี้
![ALT_TEXT_HERE](https://web.developers.google.cn/static/articles/building-multiple-pwas-on-the-same-domain/image/alttexthere-67b559ff24375.png?authuser=5&hl=th)
ในส่วนถัดไป เราจะวิเคราะห์ความท้าทายเหล่านี้อย่างละเอียดมากขึ้น และสิ่งที่ทำได้หากไม่มีตัวเลือกให้ใช้ต้นทางแยกต่างหาก
ปัญหาสําหรับ PWA ที่มีต้นทางเดียวกันหลายรายการ
ปัญหาที่ใช้ได้จริงซึ่งพบได้บ่อยในแนวทางที่มีต้นทางเดียวกันทั้ง 2 แบบมีดังนี้
- พื้นที่เก็บข้อมูล: คุกกี้ พื้นที่เก็บข้อมูลในเครื่อง และพื้นที่เก็บข้อมูลในอุปกรณ์ทุกรูปแบบจะใช้ร่วมกันระหว่างแอปต่างๆ ด้วยเหตุผลดังกล่าว หากผู้ใช้ตัดสินใจที่จะล้างข้อมูลในเครื่องของแอปหนึ่ง จะเป็นการลบข้อมูลทั้งหมดจากต้นทาง ซึ่งคุณไม่สามารถทำได้ด้วยแอปเดียว โปรดทราบว่า Chrome และเบราว์เซอร์อื่นๆ บางเบราว์เซอร์จะแจ้งให้ผู้ใช้ล้างข้อมูลในเครื่องเมื่อถอนการติดตั้งแอปใดแอปหนึ่ง ซึ่งจะส่งผลต่อข้อมูลของแอปอื่นๆ ในต้นทางด้วย อีกปัญหาหนึ่งคือแอปจะต้องแชร์โควต้าพื้นที่เก็บข้อมูลของแอปด้วย ซึ่งหมายความว่าแอปใดแอปหนึ่งใช้พื้นที่มากเกินไป อีกแอปหนึ่งจะได้รับผลเสีย
- สิทธิ์: สิทธิ์ต่างๆ จะเชื่อมโยงกับต้นทาง ซึ่งหมายความว่าหากผู้ใช้ ให้สิทธิ์แก่แอปหนึ่ง สิทธิ์ดังกล่าวก็จะมีผลกับทุกแอปในต้นทางนั้นพร้อมกัน อาจฟังดูเข้าท่าดี (ไม่ต้องขอสิทธิ์หลายครั้ง) แต่โปรดทราบว่าหากผู้ใช้บล็อกสิทธิ์ของแอปหนึ่ง ก็จะเป็นการป้องกันไม่ให้แอปอื่นขอสิทธิ์นั้นหรือใช้ฟีเจอร์ดังกล่าว
- การตั้งค่าผู้ใช้: ระบบจะตั้งค่าตามต้นทางด้วย ตัวอย่างเช่น หากแอป 2 แอปมีขนาดแบบอักษรที่ต่างกัน และผู้ใช้ต้องการปรับการซูมเพียงแอปเดียวเพื่อชดเชย ก็ทำไม่ได้หากไม่ใช้การตั้งค่ากับแอปอื่นๆ ด้วยเช่นกัน
ความท้าทายเหล่านี้ทำให้การส่งเสริมแนวทางนี้เป็นเรื่องยาก อย่างไรก็ตาม หากคุณใช้ต้นทางแยกต่างหากไม่ได้ (เช่น โดเมนย่อย) ตามที่ได้อธิบายไว้ในส่วนการใช้ต้นทางแยกต่างหาก ขอแนะนำเป็นอย่างยิ่งให้ใช้ตัวเลือกต้นทาง 2 รายการที่เรานำเสนอ ขอแนะนำเป็นอย่างยิ่งให้ใช้เส้นทางที่ไม่ซ้อนทับกัน ซึ่งก็คือเส้นทางที่ทับซ้อนกัน/ซ้อนกัน
ดังที่กล่าวไปแล้ว ความท้าทายที่พูดถึงในส่วนนี้เป็นเรื่องที่พบได้บ่อยในแนวทางที่มีต้นทางเดียวกันทั้ง 2 แบบ ในส่วนถัดไป เราจะเจาะลึกรายละเอียดเกี่ยวกับ เหตุผลที่การใช้เส้นทางที่ทับซ้อนกัน/ซ้อนกันเป็นกลยุทธ์ที่แนะนำให้ใช้น้อยที่สุด
ภารกิจเพิ่มเติมสำหรับเส้นทางที่ทับซ้อนกัน/ซ้อนกัน
ปัญหาเพิ่มเติมเกี่ยวกับแนวทางเส้นทางที่ทับซ้อนกัน/ซ้อนกัน (โดยที่ https://example.com/
เป็นแอปภายนอกและ https://example.com/app/
เป็นแอปภายใน) ก็คือจริงๆ แล้ว URL ทั้งหมดในแอปภายในจะถือว่าเป็นส่วนหนึ่งของทั้งแอปภายนอกและแอปภายใน
ในทางปฏิบัติจะทำให้เกิดปัญหาต่อไปนี้
- โปรโมชันการติดตั้ง: หากผู้ใช้เข้าชมแอปภายใน (เช่น ในเว็บเบราว์เซอร์) เมื่อติดตั้งแอปภายนอกในอุปกรณ์ของผู้ใช้แล้ว เบราว์เซอร์จะไม่แสดงแบนเนอร์โปรโมตการติดตั้ง และระบบจะไม่ทริกเกอร์เหตุการณ์ beforeInstallPrompt เหตุผลคือเบราว์เซอร์จะตรวจสอบและดูว่าหน้าปัจจุบันเป็นของแอปที่ติดตั้งไว้แล้วหรือไม่ และจะสรุปว่าเป็นสิ่งนั้น วิธีแก้ปัญหาชั่วคราวคือการติดตั้งแอปภายในด้วยตนเอง (ผ่านตัวเลือกเมนูเบราว์เซอร์ "สร้างทางลัด") หรือติดตั้งแอปภายในก่อนแอปภายนอก
- การแจ้งเตือน และ 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