หนึ่งในการตัดสินใจหลักที่นักพัฒนาเว็บต้องทำคือการเลือกตำแหน่งที่จะใช้ตรรกะและการเรนเดอร์ในแอปพลิเคชัน ซึ่งอาจเป็นเรื่องยากเนื่องจากการสร้างเว็บไซต์มีหลายวิธี
ความเข้าใจของเราเกี่ยวกับพื้นที่นี้มาจากการทำงานใน Chrome กับเว็บไซต์ขนาดใหญ่ในช่วงไม่กี่ปีที่ผ่านมา โดยทั่วไปแล้ว เราขอแนะนําให้นักพัฒนาซอฟต์แวร์พิจารณาใช้การแสดงผลฝั่งเซิร์ฟเวอร์หรือการแสดงผลแบบคงที่แทนการใช้แนวทางการ Hydration ทั้งหมด
เราต้องเข้าใจแนวทางแต่ละข้อและคำศัพท์ที่สอดคล้องกันเพื่อใช้พูดถึงสถาปัตยกรรมที่เราเลือกเมื่อตัดสินใจเช่นนี้ เพื่อให้เข้าใจสถาปัตยกรรมที่เราเลือกเมื่อตัดสินใจเช่นนี้ได้ดียิ่งขึ้น ความแตกต่างระหว่างวิธีการแสดงผลช่วยแสดงให้เห็นถึงข้อดีข้อเสียของการแสดงผลบนเว็บจากมุมมองของประสิทธิภาพหน้าเว็บ
คำศัพท์
ก่อนอื่น เราจะอธิบายคำศัพท์บางส่วนที่จะใช้
การแสดงผล
- การแสดงผลฝั่งเซิร์ฟเวอร์ (SSR)
- การแสดงผลแอปบนเซิร์ฟเวอร์เพื่อส่ง HTML ไปยังไคลเอ็นต์แทน JavaScript
- การแสดงผลฝั่งไคลเอ็นต์ (CSR)
- การแสดงผลแอปในเบราว์เซอร์โดยใช้ JavaScript เพื่อแก้ไข DOM
- การดื่มน้ำ
- "การบูต" มุมมอง JavaScript ในไคลเอ็นต์เพื่อให้ใช้แผนผัง DOM และข้อมูล HTML ที่แสดงผลจากเซิร์ฟเวอร์ซ้ำได้
- การแสดงผลล่วงหน้า
- การเรียกใช้แอปพลิเคชันฝั่งไคลเอ็นต์ ณ เวลาที่สร้างเพื่อบันทึกสถานะเริ่มต้นเป็น HTML คงที่
ประสิทธิภาพ
- เวลาที่ได้รับข้อมูลไบต์แรก (TTFB)
- เวลาที่ผ่านไประหว่างการคลิกลิงก์กับการโหลดไบต์แรกของเนื้อหาในหน้าใหม่
- First Contentful Paint (FCP)
- เวลาที่เนื้อหาที่ขอ (เนื้อหาบทความ ฯลฯ) ปรากฏขึ้น
- Interaction to Next Paint (INP)
- เมตริกตัวแทนที่ประเมินว่าหน้าเว็บตอบสนองต่ออินพุตของผู้ใช้อย่างรวดเร็วอย่างสม่ำเสมอหรือไม่
- เวลาการบล็อกทั้งหมด (TBT)
- เมตริกพร็อกซีสําหรับ INP ที่คํานวณระยะเวลาที่เทรดหลักถูกบล็อกระหว่างการโหลดหน้าเว็บ
การแสดงผลฝั่งเซิร์ฟเวอร์
การแสดงผลฝั่งเซิร์ฟเวอร์จะสร้าง HTML แบบเต็มสําหรับหน้าในเซิร์ฟเวอร์เพื่อตอบสนองต่อการนําทาง วิธีนี้จะช่วยหลีกเลี่ยงการส่งข้อมูลไปมาเพิ่มเติมสำหรับการดึงข้อมูลและการสร้างเทมเพลตในไคลเอ็นต์ เนื่องจากโปรแกรมแสดงผลจะจัดการข้อมูลเหล่านั้นก่อนที่เบราว์เซอร์จะได้รับคำตอบ
โดยทั่วไปแล้ว การแสดงผลฝั่งเซิร์ฟเวอร์จะให้ FCP ที่รวดเร็ว การแสดงผลและตรรกะของหน้าเว็บบนเซิร์ฟเวอร์ช่วยให้คุณไม่ต้องส่ง JavaScript จำนวนมากไปยังไคลเอ็นต์ ซึ่งจะช่วยลด TBT ของหน้าเว็บ ซึ่งอาจส่งผลให้ INP ลดลงด้วย เนื่องจากเธรดหลักไม่ได้รับการบล็อกบ่อยนักในระหว่างการโหลดหน้าเว็บ เมื่อการบล็อกเธรดหลักเกิดขึ้นน้อยลง การโต้ตอบของผู้ใช้ก็มีโอกาสที่จะทำงานได้เร็วขึ้น ซึ่งก็สมเหตุสมผล เนื่องจากเมื่อใช้การแสดงผลฝั่งเซิร์ฟเวอร์ คุณกําลังส่งข้อความและลิงก์ไปยังเบราว์เซอร์ของผู้ใช้ แนวทางนี้ใช้ได้กับอุปกรณ์และเครือข่ายในสภาพต่างๆ และเปิดโอกาสให้เพิ่มประสิทธิภาพเบราว์เซอร์ที่น่าสนใจ เช่น การสตรีมการแยกวิเคราะห์เอกสาร
เมื่อใช้การแสดงผลฝั่งเซิร์ฟเวอร์ ผู้ใช้จะมีโอกาสรอให้ JavaScript ที่ผูกอยู่กับ CPU ทำงานก่อนจึงจะใช้เว็บไซต์ได้น้อยลง แม้ว่าคุณจะหลีกเลี่ยงJS ของบุคคลที่สามไม่ได้ แต่การใช้การแสดงผลฝั่งเซิร์ฟเวอร์เพื่อลดต้นทุน JavaScript ของบุคคลที่หนึ่งก็จะช่วยให้คุณมีงบประมาณเหลือมากขึ้น อย่างไรก็ตาม แนวทางนี้มีข้อเสียอย่างหนึ่งคือการสร้างหน้าเว็บในเซิร์ฟเวอร์ต้องใช้เวลา ซึ่งอาจทำให้ TTFB ของหน้าเว็บเพิ่มขึ้น
การแสดงผลฝั่งเซิร์ฟเวอร์เพียงพอสำหรับแอปพลิเคชันหรือไม่นั้นขึ้นอยู่กับประเภทประสบการณ์ที่คุณกำลังสร้าง มีการถกเถียงกันมานานเกี่ยวกับการใช้งานที่ถูกต้องของการแสดงผลฝั่งเซิร์ฟเวอร์เทียบกับการแสดงผลฝั่งไคลเอ็นต์ แต่คุณเลือกที่จะใช้การแสดงผลฝั่งเซิร์ฟเวอร์กับบางหน้าและไม่ใช้กับหน้าอื่นๆ ได้ทุกเมื่อ เว็บไซต์บางแห่งใช้เทคนิคการแสดงผลแบบผสมผสานได้อย่างประสบความสำเร็จ ตัวอย่างเช่น Netflix แสดงผลหน้า Landing Page แบบคงที่โดยเซิร์ฟเวอร์ ขณะที่prefetching JS สําหรับหน้าเว็บที่มีการโต้ตอบมาก ซึ่งช่วยให้หน้าเว็บที่แสดงผลโดยไคลเอ็นต์ซึ่งมีขนาดใหญ่เหล่านี้มีโอกาสโหลดได้เร็วขึ้น
เฟรมเวิร์ก ไลบรารี และสถาปัตยกรรมสมัยใหม่จำนวนมากช่วยให้คุณแสดงผลแอปพลิเคชันเดียวกันได้ทั้งในไคลเอ็นต์และเซิร์ฟเวอร์ คุณใช้เทคนิคเหล่านี้สำหรับการเรนเดอร์ฝั่งเซิร์ฟเวอร์ได้ อย่างไรก็ตาม สถาปัตยกรรมที่มีการเรนเดอร์ทั้งบนเซิร์ฟเวอร์และบนไคลเอ็นต์เป็นโซลูชันระดับชั้นของตนเองที่มีลักษณะและข้อเสียด้านประสิทธิภาพแตกต่างกันมาก ผู้ใช้ React สามารถใช้ DOM API ฝั่งเซิร์ฟเวอร์หรือโซลูชันที่สร้างขึ้นจาก DOM API ฝั่งเซิร์ฟเวอร์ เช่น Next.js สำหรับการเรนเดอร์ฝั่งเซิร์ฟเวอร์ ผู้ใช้ Vue ใช้คู่มือการแสดงผลฝั่งเซิร์ฟเวอร์ของ Vue หรือ Nuxt ได้ Angular มี Universal อย่างไรก็ตาม โซลูชันยอดนิยมส่วนใหญ่ใช้การเติมน้ำในรูปแบบใดรูปแบบหนึ่ง ดังนั้นโปรดคำนึงถึงแนวทางที่เครื่องมือของคุณใช้
การแสดงผลแบบคงที่
การแสดงผลแบบคงที่เกิดขึ้นเมื่อสร้าง แนวทางนี้ช่วยให้ FCP รวดเร็ว รวมถึง TBT และ INP ลดลง ตราบใดที่คุณจํากัดจํานวน JS ฝั่งไคลเอ็นต์ในหน้าเว็บ การแสดงผลนี้ยังช่วยให้ TTFB รวดเร็วอย่างสม่ำเสมออีกด้วย ซึ่งแตกต่างจากการแสดงผลฝั่งเซิร์ฟเวอร์ เนื่องจากไม่ต้องสร้าง HTML ของหน้าเว็บแบบไดนามิกในเซิร์ฟเวอร์ โดยทั่วไปแล้ว การแสดงผลแบบคงที่หมายถึงการสร้างไฟล์ HTML แยกต่างหากสำหรับแต่ละ URL ล่วงหน้า เมื่อสร้างการตอบกลับ HTML ล่วงหน้า คุณจะติดตั้งใช้งานการแสดงผลแบบคงที่ใน CDN หลายรายการเพื่อใช้ประโยชน์จากการแคชที่ขอบได้
โซลูชันสำหรับการเรนเดอร์แบบคงที่มีหลายรูปแบบและหลายขนาด เครื่องมืออย่าง Gatsby ออกแบบมาเพื่อให้นักพัฒนาแอปรู้สึกว่าแอปพลิเคชันของตนได้รับการแสดงผลแบบไดนามิก ไม่ใช่สร้างขึ้นในขั้นตอนการสร้าง เครื่องมือสร้างเว็บไซต์แบบคงที่ เช่น 11ty, Jekyll และ Metalsmith ใช้ประโยชน์จากลักษณะแบบคงที่ของเว็บไซต์ ซึ่งให้แนวทางที่ขับเคลื่อนโดยเทมเพลตมากกว่า
ข้อเสียอย่างหนึ่งของการเรนเดอร์แบบคงที่คือต้องสร้างไฟล์ HTML แต่ละไฟล์สําหรับ URL ที่เป็นไปได้ทุกรายการ ซึ่งอาจเป็นเรื่องยากหรือเป็นไปไม่ได้เมื่อคุณไม่สามารถคาดเดา URL ล่วงหน้า หรือสำหรับเว็บไซต์ที่มีหน้าเว็บที่ไม่ซ้ำกันจํานวนมาก
ผู้ใช้ React อาจคุ้นเคยกับ Gatsby, การส่งออกแบบคงที่ของ Next.js หรือ Navi ซึ่งทั้งหมดนี้ช่วยให้สร้างหน้าเว็บจากคอมโพเนนต์ได้อย่างสะดวก อย่างไรก็ตาม การแสดงผลแบบคงที่และการแสดงผลล่วงหน้าจะทํางานแตกต่างกัน หน้าเว็บที่แสดงผลแบบคงที่เป็นแบบอินเทอร์แอกทีฟโดยที่ไม่ต้องเรียกใช้ JavaScript ฝั่งไคลเอ็นต์มากนัก ส่วนการแสดงผลล่วงหน้าจะปรับปรุง FCP ของแอปพลิเคชันหน้าเว็บเดียวที่ต้องบูตในไคลเอ็นต์เพื่อให้หน้าเว็บเป็นแบบอินเทอร์แอกทีฟอย่างแท้จริง
หากไม่แน่ใจว่าโซลูชันหนึ่งๆ เป็นการเรนเดอร์แบบคงที่หรือการเรนเดอร์ล่วงหน้าหรือไม่ ให้ลองปิดใช้ JavaScript และโหลดหน้าที่ต้องการทดสอบ สำหรับหน้าที่แสดงผลแบบคงที่ ฟีเจอร์แบบอินเทอร์แอกทีฟส่วนใหญ่จะยังคงใช้งานได้โดยไม่ต้องใช้ JavaScript หน้าเว็บที่แสดงผลล่วงหน้าอาจยังคงมีฟีเจอร์พื้นฐานบางอย่าง เช่น ลิงก์ที่ปิดใช้ JavaScript แต่หน้าเว็บส่วนใหญ่จะใช้งานไม่ได้
การทดสอบที่มีประโยชน์อีกอย่างหนึ่งคือการใช้การจำกัดแบนด์วิดท์เครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome และดูปริมาณการดาวน์โหลด JavaScript ก่อนที่หน้าเว็บจะโต้ตอบได้ โดยทั่วไปแล้ว การแสดงผลล่วงหน้าต้องใช้ JavaScript มากกว่าเพื่อให้เป็นแบบอินเทอร์แอกทีฟ และ JavaScript นั้นมักจะซับซ้อนกว่าแนวทางการเพิ่มประสิทธิภาพแบบเป็นขั้นเป็นตอนที่ใช้ในการแสดงผลแบบคงที่
การแสดงผลฝั่งเซิร์ฟเวอร์กับการแสดงผลแบบคงที่
การแสดงผลฝั่งเซิร์ฟเวอร์ไม่ใช่โซลูชันที่ดีที่สุดสำหรับทุกสิ่ง เนื่องจากลักษณะแบบไดนามิกอาจมีค่าใช้จ่ายส่วนเกินในการประมวลผลที่สำคัญ โซลูชันการแสดงผลฝั่งเซิร์ฟเวอร์จํานวนมากจะไม่ล้างข้อมูลก่อนเวลาอันควร ชะลอ TTFB หรือส่งข้อมูลเป็น 2 เท่า (เช่น สถานะที่ฝังอยู่ซึ่ง JavaScript ใช้ในไคลเอ็นต์) ใน React
renderToString()
อาจทำงานช้าเนื่องจากเป็นแบบเรียลไทม์และใช้เธรดเดียว
DOM API ของเซิร์ฟเวอร์ React เวอร์ชันใหม่รองรับการสตรีม ซึ่งสามารถส่งส่วนแรกของการตอบกลับ HTML ไปยังเบราว์เซอร์ได้เร็วขึ้นขณะที่ส่วนที่เหลือยังสร้างขึ้นบนเซิร์ฟเวอร์
การแสดงผลฝั่งเซิร์ฟเวอร์ที่ "ถูกต้อง" อาจเกี่ยวข้องกับการค้นหาหรือสร้างโซลูชันสำหรับการแคชคอมโพเนนต์ การจัดการการใช้หน่วยความจำ การใช้เทคนิคการจํา และข้อกังวลอื่นๆ คุณมักจะประมวลผลหรือสร้างแอปเดียวกันซ้ำ 2 ครั้ง โดยประมวลผลครั้งหนึ่งในไคลเอ็นต์และอีกครั้งในเซิร์ฟเวอร์ การแสดงผลฝั่งเซิร์ฟเวอร์ที่แสดงเนื้อหาเร็วขึ้นไม่ได้หมายความว่าคุณจะต้องทํางานน้อยลง หากมีงานจํานวนมากในไคลเอ็นต์หลังจากที่การตอบกลับ HTML ที่เซิร์ฟเวอร์สร้างขึ้นมาถึงไคลเอ็นต์ การแสดงผลฝั่งเซิร์ฟเวอร์อาจทําให้ TBT และ INP ของเว็บไซต์สูงขึ้น
การแสดงผลฝั่งเซิร์ฟเวอร์จะสร้าง HTML ตามคําขอสําหรับ URL แต่ละรายการ แต่อาจช้ากว่าการแสดงเนื้อหาที่แสดงผลแบบคงที่ หากทําได้ การเรนเดอร์ฝั่งเซิร์ฟเวอร์ร่วมกับการแคช HTML จะช่วยลดเวลาในการเรนเดอร์ของเซิร์ฟเวอร์ได้อย่างมาก ข้อดีของการแสดงผลฝั่งเซิร์ฟเวอร์คือการดึงข้อมูล "สด" มากขึ้นและตอบสนองต่อชุดคําขอที่สมบูรณ์กว่าการแสดงผลแบบคงที่ หน้าเว็บที่ต้องปรับเปลี่ยนในแบบของคุณเป็นตัวอย่างที่ชัดเจนของคำขอประเภทหนึ่งที่ทำงานร่วมกับการแสดงผลแบบคงที่ไม่ดี
การแสดงผลฝั่งเซิร์ฟเวอร์ยังอาจทำให้เกิดการตัดสินใจที่น่าสนใจเมื่อสร้าง PWA ด้วย เช่น การใช้แคชService Worker หน้าเว็บทั้งหน้าหรือเพียงแค่แสดงผลเนื้อหาแต่ละรายการบนเซิร์ฟเวอร์จะดีกว่ากัน
การแสดงผลฝั่งไคลเอ็นต์
การแสดงผลฝั่งไคลเอ็นต์หมายถึงการแสดงผลหน้าเว็บในเบราว์เซอร์โดยตรงด้วย JavaScript ระบบจะจัดการตรรกะ การดึงข้อมูล เทมเพลต และการกำหนดเส้นทางทั้งหมดในไคลเอ็นต์แทนที่จะเป็นเซิร์ฟเวอร์ ผลลัพธ์ที่มีประสิทธิภาพคือมีการส่งข้อมูลจำนวนมากขึ้นจากเซิร์ฟเวอร์ไปยังอุปกรณ์ของผู้ใช้ ซึ่งมีข้อเสียอยู่ด้วย
การแสดงผลฝั่งไคลเอ็นต์อาจทําให้อุปกรณ์เคลื่อนที่ทำงานช้าลง
เพียงทํางานเล็กน้อยเพื่อรักษางบประมาณ JavaScript ให้พอเพียงและแสดงผลลัพธ์ในการติดต่อแบบไปกลับให้น้อยที่สุด คุณก็สามารถทำให้การแสดงผลฝั่งไคลเอ็นต์ทํางานได้เกือบเทียบเท่าการแสดงผลฝั่งเซิร์ฟเวอร์ คุณสามารถทำให้โปรแกรมแยกวิเคราะห์ทำงานได้เร็วขึ้นโดยส่งสคริปต์และข้อมูลที่สำคัญโดยใช้ <link rel=preload>
เราขอแนะนำให้พิจารณาใช้รูปแบบอย่าง PRPL เพื่อให้การไปยังส่วนต่างๆ ครั้งแรกและครั้งต่อๆ ไปเป็นไปอย่างรวดเร็ว
ข้อเสียหลักของการแสดงผลฝั่งไคลเอ็นต์คือจํานวน JavaScript ที่จําเป็นมีแนวโน้มที่จะเพิ่มขึ้นเมื่อแอปพลิเคชันเติบโตขึ้น ซึ่งอาจส่งผลต่อ INP ของหน้าเว็บ ปัญหานี้ยิ่งทวีความยากขึ้นเมื่อมีการเพิ่มไลบรารี JavaScript, โพลีฟีล และโค้ดของบุคคลที่สามใหม่ ซึ่งแย่งชิงกำลังประมวลผลและต้องได้รับการประมวลผลบ่อยครั้งก่อนที่เนื้อหาของหน้าเว็บจะแสดงผลได้
ประสบการณ์การใช้งานที่ใช้การแสดงผลฝั่งไคลเอ็นต์และอาศัยกลุ่ม JavaScript ขนาดใหญ่ควรพิจารณาการแยกโค้ดอย่างละเอียดเพื่อลด TBT และ INP ระหว่างการโหลดหน้าเว็บ รวมถึงการโหลด JavaScript แบบ Lazy เพื่อแสดงเฉพาะสิ่งที่ผู้ใช้ต้องการเมื่อจำเป็น สำหรับประสบการณ์ที่มีการโต้ตอบน้อยหรือไม่มีเลย การแสดงผลฝั่งเซิร์ฟเวอร์อาจเป็นโซลูชันที่ปรับขนาดได้มากกว่าสำหรับปัญหาเหล่านี้
สําหรับผู้ที่สร้างแอปพลิเคชันหน้าเว็บเดียว การระบุส่วนสําคัญของอินเทอร์เฟซผู้ใช้ที่หน้าเว็บส่วนใหญ่ใช้ร่วมกันจะช่วยให้คุณใช้เทคนิคการแคชเชลล์แอปพลิเคชันได้ เมื่อใช้ร่วมกับ Service Worker เทคนิคนี้จะช่วยปรับปรุงประสิทธิภาพที่รับรู้ได้อย่างมากเมื่อเข้าชมซ้ำ เนื่องจากหน้าเว็บจะโหลด HTML ของเชลล์แอปพลิเคชันและทรัพยากรที่เกี่ยวข้องจาก CacheStorage
ได้อย่างรวดเร็ว
การทำให้ชื้นใหม่จะรวมการแสดงผลฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์เข้าด้วยกัน
การคืนค่าเป็นแนวทางที่พยายามลดความเสียเปรียบระหว่างการแสดงผลฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ด้วยการทำทั้ง 2 อย่าง คําขอการนําทาง เช่น การโหลดหน้าเว็บทั้งหมดหรือการโหลดซ้ำจะจัดการโดยเซิร์ฟเวอร์ที่แสดงผลแอปพลิเคชันเป็น HTML จากนั้นจะฝัง JavaScript และข้อมูลที่ใช้สําหรับการแสดงผลลงในเอกสารที่ได้ เมื่อทําอย่างระมัดระวัง การดำเนินการนี้จะทําให้ได้ FCP ที่รวดเร็วเหมือนการแสดงผลฝั่งเซิร์ฟเวอร์ จากนั้นจะ "เพิ่มประสิทธิภาพ" โดยการแสดงผลอีกครั้งในไคลเอ็นต์ นี่เป็นวิธีแก้ปัญหาที่มีประสิทธิภาพ แต่อาจมีข้อเสียด้านประสิทธิภาพอย่างมาก
ข้อเสียหลักของการแสดงผลฝั่งเซิร์ฟเวอร์ที่มีการให้น้ำใหม่คืออาจส่งผลเสียอย่างมากต่อ TBT และ INP แม้ว่าจะปรับปรุง FCP ได้ก็ตาม หน้าเว็บที่แสดงผลฝั่งเซิร์ฟเวอร์อาจดูเหมือนโหลดและโต้ตอบได้ แต่ไม่สามารถตอบสนองต่ออินพุตได้จนกว่าสคริปต์ฝั่งไคลเอ็นต์สำหรับคอมโพเนนต์จะทำงานและแนบตัวจัดการเหตุการณ์แล้ว บนอุปกรณ์เคลื่อนที่ การดำเนินการนี้อาจใช้เวลาหลายนาที ซึ่งทำให้ผู้ใช้สับสนและหงุดหงิด
ปัญหาการเติมน้ำ: แอปเดียวในราคา 2 แอป
เพื่อให้ JavaScript ฝั่งไคลเอ็นต์ "ดําเนินการต่อ" จากจุดที่เซิร์ฟเวอร์หยุดไว้ได้อย่างถูกต้องโดยไม่ต้องขอข้อมูลทั้งหมดที่เซิร์ฟเวอร์ใช้แสดงผล HTML อีกครั้ง โซลูชันการแสดงผลฝั่งเซิร์ฟเวอร์ส่วนใหญ่จะจัดรูปแบบการตอบกลับจากข้อมูล Dependency ของ UI เป็นแท็กสคริปต์ในเอกสาร เนื่องจากมีการทำซ้ำ HTML จำนวนมาก การทำให้ชุ่มชื้นอีกครั้งอาจทำให้เกิดปัญหามากกว่าแค่การโต้ตอบที่ล่าช้า
เซิร์ฟเวอร์จะแสดงคำอธิบาย UI ของแอปพลิเคชันเพื่อตอบสนองต่อคำขอการนําทาง แต่ก็จะแสดงข้อมูลต้นทางที่ใช้เขียน UI นั้นด้วย รวมถึงสําเนาที่สมบูรณ์ของการใช้งาน UI ซึ่งจะเริ่มต้นขึ้นในไคลเอ็นต์ UI จะไม่เป็นแบบอินเทอร์แอกทีฟจนกว่า bundle.js
จะโหลดและดำเนินการเสร็จสิ้น
เมตริกประสิทธิภาพที่รวบรวมจากเว็บไซต์จริงโดยใช้การแสดงผลและการคืนค่าฝั่งเซิร์ฟเวอร์บ่งชี้ว่าการแสดงผลและคืนค่าฝั่งเซิร์ฟเวอร์ไม่ใช่ตัวเลือกที่ดีที่สุด เหตุผลที่สําคัญที่สุดคือผลกระทบต่อประสบการณ์ของผู้ใช้ เมื่อหน้าเว็บดูพร้อมใช้งานแต่ฟีเจอร์แบบอินเทอร์แอกทีฟไม่ทํางาน
แต่การแสดงผลฝั่งเซิร์ฟเวอร์ที่มีการเติมน้ำอาจช่วยได้ ในระยะสั้น การใช้การแสดงผลฝั่งเซิร์ฟเวอร์กับเนื้อหาที่แคชได้สูงเท่านั้นที่สามารถลด TTFB ซึ่งจะให้ผลลัพธ์คล้ายกับการแสดงผลล่วงหน้า การเติมน้ำทีละน้อย ทีละน้อยๆ หรือบางส่วนอาจเป็นกุญแจสำคัญที่จะทำให้เทคนิคนี้ใช้งานได้จริงมากขึ้นในอนาคต
สตรีมการแสดงผลฝั่งเซิร์ฟเวอร์และเพิ่มน้ำอย่างต่อเนื่อง
การแสดงผลฝั่งเซิร์ฟเวอร์ได้รับการพัฒนาหลายอย่างในช่วง 2-3 ปีที่ผ่านมา
การแสดงผลฝั่งเซิร์ฟเวอร์แบบสตรีมช่วยให้คุณส่ง HTML เป็นกลุ่มๆ ที่เบราว์เซอร์แสดงผลได้ทีละส่วนเมื่อได้รับ วิธีนี้จะช่วยให้ผู้ใช้เห็นมาร์กอัปได้เร็วขึ้น ซึ่งจะเพิ่มความเร็ว FCP ใน React สตรีมแบบอะซิงโครนัสใน renderToPipeableStream()
เมื่อเทียบกับแบบซิงโครนัสใน renderToString()
หมายความว่าระบบจัดการแรงดันย้อนกลับได้ดี
การทำให้ชื้นแบบเป็นขั้นเป็นตอนก็เป็นสิ่งที่ควรพิจารณาด้วย และ React ก็ได้นำมาใช้แล้ว แนวทางนี้จะทำให้แต่ละส่วนของแอปพลิเคชันที่แสดงผลจากเซิร์ฟเวอร์ "บูต" ขึ้นเมื่อเวลาผ่านไป แทนที่จะใช้แนวทางทั่วไปในปัจจุบันซึ่งเริ่มต้นแอปพลิเคชันทั้งหมดพร้อมกัน ซึ่งจะช่วยลดความจําเป็นในการใช้ JavaScript ในการทําให้หน้าเว็บมีการโต้ตอบ เนื่องจากช่วยให้คุณเลื่อนการอัปเกรดฝั่งไคลเอ็นต์ของส่วนที่มีลําดับความสําคัญต่ำของหน้าเว็บเพื่อไม่ให้บล็อกเธรดหลักได้ ซึ่งจะช่วยให้การโต้ตอบของผู้ใช้เกิดขึ้นเร็วขึ้นหลังจากที่ผู้ใช้เริ่มการโต้ตอบ
การทำให้ข้อมูลชุ่มชื้นแบบเป็นขั้นๆ ยังช่วยคุณหลีกเลี่ยงข้อผิดพลาดที่พบบ่อยที่สุดอย่างหนึ่งในการทำให้ข้อมูลการเรนเดอร์ฝั่งเซิร์ฟเวอร์ชุ่มชื้นได้อีกด้วย ซึ่งก็คือการทำลายต้นไม้ DOM ที่แสดงผลจากเซิร์ฟเวอร์แล้วสร้างใหม่ทันที ซึ่งมักเกิดขึ้นเนื่องจากการแสดงผลฝั่งไคลเอ็นต์แบบซิงค์ครั้งแรกต้องใช้ข้อมูลที่ยังไม่พร้อมใช้งาน ซึ่งมักเป็นPromise
ที่ยังไม่ได้รับการแก้ไข
การคืนความชุ่มชื้นบางส่วน
พบว่าการคืนความชุ่มชื้นบางส่วนใช้งานยาก แนวทางนี้เป็นส่วนขยายของการทำให้ข้อมูลชุ่มชื้นแบบเป็นขั้นเป็นตอนซึ่งจะวิเคราะห์ชิ้นส่วนต่างๆ ของหน้าเว็บ (คอมโพเนนต์ มุมมอง หรือต้นไม้) และระบุชิ้นส่วนที่มีการโต้ตอบน้อยหรือไม่มีการโต้ตอบ สําหรับแต่ละส่วนที่เป็นแบบคงที่ส่วนใหญ่ ระบบจะเปลี่ยนโค้ด JavaScript ที่เกี่ยวข้องเป็นการอ้างอิงแบบคงที่และฟีเจอร์ตกแต่ง ซึ่งจะลดร่องรอยฝั่งไคลเอ็นต์ให้เหลือเกือบเป็น 0
วิธีการให้น้ำบางส่วนก็มีปัญหาและข้อจำกัดของตัวเอง ซึ่งทำให้เกิดปัญหาที่น่าสนใจบางอย่างสำหรับการแคช และการนำทางฝั่งไคลเอ็นต์หมายความว่าเราไม่สามารถถือว่า HTML ที่เซิร์ฟเวอร์แสดงผลสำหรับส่วนที่ไม่มีการเปลี่ยนแปลงของแอปพลิเคชันพร้อมใช้งานโดยไม่ต้องโหลดหน้าเว็บอย่างเต็มรูปแบบ
การแสดงผลแบบ 3 รูป
หากService Worker เป็นตัวเลือกสำหรับคุณ ให้พิจารณาการแสดงผลแบบ 3 รูปแบบ ซึ่งเป็นเทคนิคที่ช่วยให้คุณใช้การแสดงผลฝั่งเซิร์ฟเวอร์แบบสตรีมมิงสำหรับการนําทางครั้งแรกหรือที่ไม่ใช่ JS จากนั้นให้ Service Worker แสดงผล HTML สำหรับการนําทางหลังจากติดตั้งแล้ว ซึ่งจะช่วยให้คอมโพเนนต์และเทมเพลตที่แคชไว้เป็นปัจจุบันอยู่เสมอ และเปิดใช้การนําทางสไตล์ SPA เพื่อนําเสนอผลลัพธ์ของมุมมองใหม่ในเซสชันเดียวกัน วิธีการนี้ได้ผลดีที่สุดเมื่อคุณแชร์โค้ดเทมเพลตและการกำหนดเส้นทางเดียวกันระหว่างเซิร์ฟเวอร์ หน้าไคลเอ็นต์ และ Service Worker
ข้อควรพิจารณาเกี่ยวกับ SEO
เมื่อเลือกกลยุทธ์การแสดงผลเว็บ ทีมมักจะพิจารณาผลกระทบของ SEO การแสดงผลฝั่งเซิร์ฟเวอร์เป็นตัวเลือกยอดนิยมในการมอบประสบการณ์ที่ "ดูสมบูรณ์" ซึ่ง Crawler สามารถตีความได้ Crawler เข้าใจ JavaScript แต่มักจะมีข้อจำกัดในการแสดงผล การแสดงผลฝั่งไคลเอ็นต์อาจใช้งานได้ แต่มักต้องมีการทดสอบและค่าใช้จ่ายเพิ่มเติม เมื่อเร็วๆ นี้ การแสดงผลแบบไดนามิกก็กลายเป็นตัวเลือกที่ควรพิจารณาด้วยหากสถาปัตยกรรมของคุณใช้ JavaScript ฝั่งไคลเอ็นต์อย่างหนัก
หากมีข้อสงสัย เครื่องมือทดสอบความเหมาะกับอุปกรณ์เคลื่อนที่เป็นวิธีที่ดีในการทดสอบว่าแนวทางที่คุณเลือกทํางานตามที่คาดหวังหรือไม่ โดยจะแสดงตัวอย่างภาพว่าหน้าเว็บปรากฏต่อ Crawler ของ Google อย่างไร เนื้อหา HTML ที่ซีเรียลไลซ์ซึ่งพบหลังจากเรียกใช้ JavaScript และข้อผิดพลาดที่พบระหว่างการแสดงผล
บทสรุป
เมื่อตัดสินใจเลือกวิธีการแสดงผล ให้วัดและทําความเข้าใจปัญหาคอขวด พิจารณาว่าการแสดงผลแบบคงที่หรือการแสดงผลฝั่งเซิร์ฟเวอร์ช่วยแก้ปัญหาได้หรือไม่ คุณส่ง HTML ส่วนใหญ่ที่มี JavaScript เพียงเล็กน้อยเพื่อให้ได้รับประสบการณ์แบบอินเทอร์แอกทีฟได้ อินโฟกราฟิกแสดงสเปกตรัมเซิร์ฟเวอร์ไคลเอ็นต์ที่มีประโยชน์มีดังนี้
เครดิต
ขอขอบคุณทุกคนสำหรับรีวิวและแรงบันดาลใจ
Jeffrey Posnick, Houssein Djirdeh, Shubhie Panicker, Chris Harrelson และ Sebastian Markbåge