เราควรนำตรรกะและการแสดงภาพไปใช้ที่ใดในแอปพลิเคชันของเรา เราควรใช้การแสดงผลฝั่งเซิร์ฟเวอร์หรือไม่ แล้ว Rehydration ล่ะ มาหาคำตอบกัน
ในฐานะนักพัฒนาซอฟต์แวร์ เรามักต้องเผชิญกับการตัดสินใจที่ส่งผลต่อสถาปัตยกรรมทั้งหมดของแอปพลิเคชัน การตัดสินใจสำคัญอย่างหนึ่งที่นักพัฒนาเว็บต้องทำคือการนำตรรกะและการแสดงภาพไปใช้ในแอปพลิเคชันของตน เรื่องนี้อาจเป็นเรื่องยากเนื่องจากมีการสร้างเว็บไซต์หลายวิธี
ความเข้าใจของเราเกี่ยวกับส่วนนี้นั้นเกิดขึ้นจากการทำงานใน Chrome ที่เราได้พูดคุยกับเว็บไซต์ขนาดใหญ่ในช่วง 2-3 ปีที่ผ่านมา พูดกว้างๆ ก็คือ เราขอแนะนำให้นักพัฒนาซอฟต์แวร์พิจารณาใช้การแสดงผลฝั่งเซิร์ฟเวอร์หรือแบบภาพนิ่งมากกว่าการเปลี่ยนแนวทางเนื้อหาอย่างเต็มรูปแบบ
เพื่อให้เข้าใจมากขึ้นเกี่ยวกับสถาปัตยกรรมที่เราจะเลือกใช้เมื่อตัดสินใจเช่นนี้ เราจำเป็นต้องเข้าใจอย่างถ่องแท้ต่อแนวทางแต่ละวิธีและคำศัพท์ที่สอดคล้องในการใช้เมื่อพูดถึงแนวทางเหล่านั้น ความแตกต่างระหว่างแนวทางเหล่านี้ช่วยให้เห็นภาพข้อดีและข้อเสียของการแสดงผลบนเว็บผ่านมุมมองด้านประสิทธิภาพ
คำศัพท์
การแสดงภาพ
- การแสดงผลฝั่งเซิร์ฟเวอร์ (SSR): แสดงผลฝั่งไคลเอ็นต์หรือ Universal App เป็น HTML บนเซิร์ฟเวอร์
- การแสดงผลฝั่งไคลเอ็นต์ (CSR): แสดงผลแอปในเบราว์เซอร์ผ่าน JavaScript เพื่อแก้ไข DOM
- การดึงน้ำใหม่: มีการ "เพิ่ม" มุมมอง JavaScript ในไคลเอ็นต์จนทำให้ใช้โครงสร้างและข้อมูล DOM ของ HTML ที่แสดงผลโดยเซิร์ฟเวอร์ซ้ำ
- การแสดงผลล่วงหน้า: การเรียกใช้แอปพลิเคชันฝั่งไคลเอ็นต์ในเวลาบิลด์เพื่อบันทึกสถานะเริ่มต้นเป็น HTML แบบคงที่
ประสิทธิภาพ
- Time to First Byte (TTFB): หมายถึงช่วงเวลาระหว่างการคลิกลิงก์และส่วนแรกของเนื้อหา
- First Contentful Paint (FCP): เวลาที่แสดงเนื้อหาที่ขอ (เช่น เนื้อความบทความ)
- การโต้ตอบกับ Next Paint (INP) เป็นเมตริกตัวแทนที่ประเมินว่าหน้าเว็บตอบสนองต่อข้อมูลจากผู้ใช้เร็วสม่ำเสมอหรือไม่
- เวลาในการบล็อกทั้งหมด (TBT): เมตริกพร็อกซีสำหรับ INP ซึ่งจะคำนวณระยะเวลาที่เทรดหลักถูกบล็อกระหว่างการโหลดหน้าเว็บ
การแสดงผลฝั่งเซิร์ฟเวอร์
การแสดงผลฝั่งเซิร์ฟเวอร์จะสร้าง HTML แบบเต็มสำหรับหน้าเว็บบนเซิร์ฟเวอร์เพื่อตอบสนองต่อการนำทาง วิธีนี้จะช่วยให้ไคลเอ็นต์ไม่ต้องรับและคัดลอกเทมเพลตเมื่อมีการดึงข้อมูลอีก เนื่องจากมีการจัดการก่อนที่เบราว์เซอร์จะได้รับการตอบสนอง
การแสดงผลฝั่งเซิร์ฟเวอร์มักให้ FCP ที่รวดเร็ว การเรียกใช้ตรรกะของหน้าเว็บและการแสดงผลบนเซิร์ฟเวอร์จะช่วยให้หลีกเลี่ยงการส่ง JavaScript จำนวนมากไปยังไคลเอ็นต์ได้ วิธีนี้ช่วยลด TBT ของหน้าเว็บ ซึ่งอาจทำให้ INP ต่ำลงด้วย เนื่องจากเทรดหลักไม่ได้ถูกบล็อกบ่อยเท่าระหว่างการโหลดหน้าเว็บ เมื่อเทรดหลักถูกบล็อกบ่อยน้อยลง การโต้ตอบของผู้ใช้จะยิ่งมีโอกาสทำงานเร็วขึ้น ซึ่งเหมาะสมแล้ว เนื่องจากในการแสดงผลฝั่งเซิร์ฟเวอร์ คุณเพียงแค่ส่งข้อความและลิงก์ไปที่เบราว์เซอร์ของผู้ใช้ วิธีนี้ได้ผลดีสำหรับเงื่อนไขของอุปกรณ์และเครือข่ายที่หลากหลาย และทำให้เกิดการเพิ่มประสิทธิภาพเบราว์เซอร์ที่น่าสนใจ เช่น การแยกวิเคราะห์เอกสารสตรีมมิง

เมื่อใช้การแสดงผลฝั่งเซิร์ฟเวอร์ ผู้ใช้จะมีโอกาสน้อยลงที่ต้องรอให้ JavaScript ที่เชื่อมโยงกับ CPU ทำงานก่อนที่จะใช้เว็บไซต์ของคุณ แม้จะหลีกเลี่ยง JS ของบุคคลที่สามไม่ได้ แต่การใช้การแสดงผลฝั่งเซิร์ฟเวอร์เพื่อลดค่าใช้จ่าย JavaScript ของบุคคลที่หนึ่งอาจช่วยเพิ่มงบประมาณสำหรับส่วนที่เหลือได้ อย่างไรก็ตาม อาจมีข้อดีและข้อเสียบางประการสำหรับวิธีนี้ คือ การสร้างหน้าเว็บบนเซิร์ฟเวอร์ต้องใช้เวลา ซึ่งอาจส่งผลให้ TTFB สูงขึ้น
การแสดงผลฝั่งเซิร์ฟเวอร์จะเพียงพอสำหรับแอปพลิเคชันของคุณหรือไม่ส่วนใหญ่ขึ้นอยู่กับประเภทของประสบการณ์ที่คุณกำลังสร้าง มีการอภิปรายมาอย่างยาวนานเกี่ยวกับแอปพลิเคชันที่ถูกต้องของการแสดงผลฝั่งเซิร์ฟเวอร์กับการแสดงผลฝั่งไคลเอ็นต์ แต่ควรระลึกไว้เสมอว่าคุณสามารถเลือกใช้การแสดงผลฝั่งเซิร์ฟเวอร์สำหรับบางหน้าเท่านั้น เว็บไซต์บางแห่งได้ใช้เทคนิคการแสดงผลแบบไฮบริดที่ประสบความสำเร็จ เซิร์ฟเวอร์ของ Netflix แสดงผลหน้า Landing Page ที่ค่อนข้างคงที่ ขณะที่ดึงข้อมูล JS ล่วงหน้าสำหรับหน้าที่มีการโต้ตอบจำนวนมาก ทำให้หน้าที่แสดงผลของไคลเอ็นต์ที่มีน้ำหนักมากกว่านี้มีโอกาสโหลดได้เร็วยิ่งขึ้น
เฟรมเวิร์ก ไลบรารี และสถาปัตยกรรมสมัยใหม่จำนวนมากทำให้สามารถแสดงแอปพลิเคชันเดียวกันทั้งบนไคลเอ็นต์และเซิร์ฟเวอร์ได้ คุณสามารถใช้เทคนิคเหล่านี้สำหรับการแสดงผลฝั่งเซิร์ฟเวอร์ แต่สิ่งสำคัญที่ควรทราบคือสถาปัตยกรรมที่การแสดงผลเกิดขึ้นทั้งในเซิร์ฟเวอร์และไคลเอ็นต์เป็นโซลูชันในกลุ่มของตนเอง ซึ่งมีคุณลักษณะด้านประสิทธิภาพและข้อดีข้อเสียที่แตกต่างกันมาก ผู้ใช้รีแอ็กสามารถใช้ Server DOM API หรือโซลูชันที่สร้างขึ้นด้านบน เช่น Next.js สำหรับการแสดงผลฝั่งเซิร์ฟเวอร์ ผู้ใช้ Vue สามารถดูคำแนะนำในการแสดงผลฝั่งเซิร์ฟเวอร์หรือ Nuxt ของ Vue ได้ 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 สำหรับหน้าที่แสดงผลล่วงหน้า อาจยังมีฟังก์ชันการทำงานพื้นฐานบางอย่าง เช่น ลิงก์ แต่ส่วนใหญ่แล้วจะเป็นหน้าที่ไม่มีการเคลื่อนไหว
การทดสอบที่มีประโยชน์อีกอย่างคือการใช้การควบคุมเครือข่ายใน Chrome DevTools และสังเกตจำนวน JavaScript ที่ดาวน์โหลดก่อนที่หน้าเว็บจะโต้ตอบได้ โดยทั่วไปการแสดงผลล่วงหน้าต้องใช้ JavaScript มากกว่าจึงจะโต้ตอบได้ และ JavaScript มักจะซับซ้อนกว่าวิธีการเพิ่มประสิทธิภาพแบบต่อเนื่องที่ใช้โดยการแสดงผลแบบคงที่
การแสดงผลฝั่งเซิร์ฟเวอร์เทียบกับการแสดงผลแบบคงที่
การแสดงผลฝั่งเซิร์ฟเวอร์ไม่ใช่ต้นทุนต่ำ การแสดงผลฝั่งเซิร์ฟเวอร์มักมาพร้อมกับต้นทุนการประมวลผลที่สูงขึ้น โซลูชันการแสดงผลฝั่งเซิร์ฟเวอร์จํานวนมากไม่ได้ล้างข้อมูลก่อน อาจทำให้ TTFB ล่าช้า หรือเพิ่มการส่งข้อมูลเป็น 2 เท่า (เช่น สถานะในบรรทัดซึ่ง JavaScript ใช้งานในไคลเอ็นต์) ใน React renderToString()
อาจทำงานช้าเนื่องจากเป็นซิงโครนัสและเทรดเดี่ยว DOM API ของเซิร์ฟเวอร์ React ใหม่ที่รองรับสตรีมมิง ซึ่งสามารถรับส่วนแรกของการตอบสนอง HTML ไปยังเบราว์เซอร์เร็วขึ้นขณะที่ส่วนที่เหลือของระบบยังคงสร้างอยู่บนเซิร์ฟเวอร์
การแสดงผลฝั่งเซิร์ฟเวอร์ "ถูกต้อง" อาจเกี่ยวข้องกับการค้นหาหรือสร้างโซลูชันสำหรับการแคชคอมโพเนนต์ การจัดการการใช้หน่วยความจำ การใช้เทคนิคการบันทึกข้อความ และข้อกังวลอื่นๆ โดยปกติแล้ว คุณจะประมวลผล/สร้างแอปพลิเคชันเดิมใหม่หลายครั้ง ทั้งบนไคลเอ็นต์และ 1 ครั้งบนเซิร์ฟเวอร์ การที่การแสดงผลฝั่งเซิร์ฟเวอร์สามารถทำให้บางสิ่งปรากฏขึ้นเร็วเกินไปไม่ได้หมายความว่าคุณมีงานต้องทำน้อยลง หากคุณมีงานสำหรับไคลเอ็นต์มากมายหลังจากการตอบสนอง HTML ที่เซิร์ฟเวอร์สร้างขึ้นมาถึงไคลเอ็นต์ เหตุการณ์เช่นนี้ยังคงสามารถส่งผลให้มี TBT และ INP ที่สูงขึ้นสำหรับเว็บไซต์ของคุณ
การแสดงผลฝั่งเซิร์ฟเวอร์จะสร้าง HTML ตามคำขอสำหรับแต่ละ URL แต่อาจช้ากว่าการแสดงเนื้อหาที่แสดงผลแบบคงที่เท่านั้น หากคุณลงรายละเอียดเพิ่มเติมไปได้ การแสดงผลฝั่งเซิร์ฟเวอร์และการแคช HTML อาจลดเวลาในการแสดงผลของเซิร์ฟเวอร์ได้อย่างมาก ข้อดีของการแสดงผลฝั่งเซิร์ฟเวอร์คือ ความสามารถในการดึงข้อมูล "สด" ได้มากขึ้นและตอบสนองต่อชุดคำขอที่สมบูรณ์มากกว่าที่เป็นไปได้ด้วยการแสดงผลแบบคงที่ หน้าที่ต้องการการปรับเปลี่ยนให้เหมาะกับแต่ละบุคคลเป็นตัวอย่างที่ชัดเจนของประเภทคำขอที่ทำงานได้ไม่ดีกับการแสดงผลแบบคงที่
การแสดงผลฝั่งเซิร์ฟเวอร์ยังนำเสนอการตัดสินใจที่น่าสนใจเมื่อสร้าง PWA อีกด้วย การใช้การแคช Service Worker แบบเต็มหน้าหรือเพียงการแสดงผลเนื้อหาแต่ละส่วนจากเซิร์ฟเวอร์
การแสดงผลฝั่งไคลเอ็นต์
การแสดงผลฝั่งไคลเอ็นต์หมายถึงการแสดงผลหน้าเว็บโดยตรงในเบราว์เซอร์ด้วย JavaScript ตรรกะ การดึงข้อมูล การกำหนดเทมเพลต และการกำหนดเส้นทางทั้งหมดจะได้รับการจัดการบนไคลเอ็นต์ ไม่ใช่เซิร์ฟเวอร์ ผลลัพธ์ที่มีประสิทธิภาพคือจะมีการส่งข้อมูลไปยังอุปกรณ์ของผู้ใช้จากเซิร์ฟเวอร์มากขึ้น และมาพร้อมข้อดีและข้อเสียของตัวเอง
การแสดงผลฝั่งไคลเอ็นต์อาจแสดงผลได้ยากและคงความเร็วไว้ได้ในอุปกรณ์เคลื่อนที่ หากทำงานไม่มากนัก การแสดงผลฝั่งไคลเอ็นต์จะมีประสิทธิภาพมากในการแสดงผลฝั่งเซิร์ฟเวอร์ รักษางบประมาณ JavaScript ที่มั่นคง และสร้างมูลค่าในการส่งข้อมูลให้น้อยที่สุดเท่าที่จะเป็นไปได้ สคริปต์และข้อมูลที่สำคัญจะส่งได้เร็วขึ้นโดยใช้ <link rel=preload>
ซึ่งจะช่วยให้โปรแกรมแยกวิเคราะห์ทำงานให้คุณได้เร็วขึ้น นอกจากนี้ รูปแบบอย่าง PRPL ก็ควรค่าต่อการประเมินเพื่อให้การนําทางครั้งแรกและต่อไปเรื่อยๆ รู้สึกได้ทันที

ข้อเสียหลักของการแสดงผลฝั่งไคลเอ็นต์คือปริมาณ JavaScript ที่ต้องใช้มีแนวโน้มที่จะเพิ่มขึ้นเมื่อแอปพลิเคชันเติบโตขึ้น ซึ่งอาจส่งผลเสียต่อ INP ของหน้าเว็บ ซึ่งจะทำได้ยากขึ้นมากกับการเพิ่มไลบรารี JavaScript, โพลีฟิลล์ และโค้ดของบุคคลที่สามใหม่ๆ ที่แย่งชิงประสิทธิภาพในการประมวลผล และมักจะต้องประมวลผลเนื้อหาของหน้าเว็บก่อน
ประสบการณ์ที่ใช้การแสดงผลฝั่งไคลเอ็นต์ที่อาศัยแพ็กเกจ JavaScript ขนาดใหญ่ควรพิจารณาการแยกโค้ดอย่างเข้มงวดเพื่อลด TBT และ INP ระหว่างการโหลดหน้าเว็บ และอย่าลืมโหลด JavaScript แบบ Lazy Loading "แสดงเฉพาะสิ่งที่คุณต้องการในเวลาที่ต้องการ" เท่านั้น สำหรับประสบการณ์ที่มีการโต้ตอบเพียงเล็กน้อยหรือไม่มีเลย การแสดงผลฝั่งเซิร์ฟเวอร์อาจเป็นโซลูชันที่รองรับการปรับขนาดเพื่อแก้ไขปัญหาเหล่านี้
สำหรับผู้ที่สร้างแอปพลิเคชันหน้าเว็บเดียว การระบุส่วนหลักของอินเทอร์เฟซผู้ใช้ที่แชร์โดยหน้าเว็บส่วนใหญ่หมายความว่าคุณสามารถใช้เทคนิคการแคช Application Shell ได้ เมื่อใช้ร่วมกับโปรแกรมทำงานของบริการ วิธีนี้ช่วยปรับปรุงประสิทธิภาพที่รับรู้ได้อย่างมากเมื่อเข้าชมซ้ำๆ เนื่องจาก HTML ของ Application Shell และการอ้างอิงของแอปพลิเคชันนี้สามารถโหลดจาก CacheStorage
ได้อย่างรวดเร็ว
การรวมการแสดงผลฝั่งเซิร์ฟเวอร์กับการแสดงผลฝั่งไคลเอ็นต์ผ่านการเติมข้อมูล
วิธีนี้พยายามปรับสมดุลระหว่างการแสดงผลฝั่งไคลเอ็นต์กับการแสดงผลฝั่งเซิร์ฟเวอร์ให้ราบรื่นยิ่งขึ้นด้วยการดำเนินการทั้ง 2 อย่าง คำขอการนำทาง เช่น การโหลดหน้าเว็บแบบเต็มหรือการโหลดใหม่ จะได้รับการจัดการโดยเซิร์ฟเวอร์ที่แสดงผลแอปพลิเคชันเป็น HTML จากนั้น JavaScript และข้อมูลที่ใช้สำหรับการแสดงผลจะฝังลงในเอกสารผลลัพธ์ หากทำออกมาอย่างระมัดระวัง วิธีนี้จะได้ FCP ที่รวดเร็วเช่นเดียวกับการแสดงผลฝั่งเซิร์ฟเวอร์ จากนั้น "หยิบ" โดยการแสดงผลอีกครั้งบนไคลเอ็นต์ด้วยเทคนิคที่เรียกว่า (เพิ่ม)ความชุ่มชื้น นี่เป็นโซลูชันที่มีประสิทธิภาพ แต่ก็อาจมีข้อเสียด้านประสิทธิภาพหลายประการ
ข้อเสียหลักของการแสดงผลฝั่งเซิร์ฟเวอร์ที่มีการดึงเนื้อหาคืออาจส่งผลเสียอย่างมากต่อ TBT และ INP แม้ว่าจะเป็นการปรับปรุง FCP ก็ตาม หน้าที่แสดงผลฝั่งเซิร์ฟเวอร์อาจดูเหมือนโหลดและมีการโต้ตอบแบบหลอกลวง แต่จริงๆ แล้วไม่สามารถตอบสนองต่ออินพุตได้จนกว่าจะมีการเรียกใช้สคริปต์ฝั่งไคลเอ็นต์สำหรับคอมโพเนนต์และแนบตัวแฮนเดิลเหตุการณ์แล้ว การดำเนินการนี้อาจใช้เวลาไม่กี่วินาทีหรือแม้กระทั่งนาทีบนอุปกรณ์เคลื่อนที่
โดยคุณอาจเคยเจอกับปัญหานี้มาสักพักหนึ่งแล้วหลังจากที่ดูเหมือนว่าหน้าเว็บโหลดขึ้นมา การคลิกหรือการแตะ ทำให้ไม่มีอะไรเกิดขึ้น กรณีนี้ทำให้เกิดความหงุดหงิดอย่างรวดเร็ว เนื่องจากผู้ใช้สงสัยว่าทำไมไม่มีอะไรเกิดขึ้นเมื่อพยายามโต้ตอบกับหน้าเว็บ
ปัญหาการขาดน้ำ: แอปเดียวแต่จ่ายราคาสองเท่า
ปัญหาการขาดน้ำมักแย่กว่าการโต้ตอบล่าช้าเนื่องจาก JavaScript เพื่อให้ JavaScript ฝั่งไคลเอ็นต์สามารถ "เลือก" จากที่เซิร์ฟเวอร์ค้างไว้ได้อย่างถูกต้องโดยไม่ต้องขอข้อมูลทั้งหมดที่เซิร์ฟเวอร์ใช้ในการแสดงผล HTML ของตน โซลูชันการแสดงผลฝั่งเซิร์ฟเวอร์ที่ใช้อยู่ในปัจจุบันมักจะจัดลำดับการตอบสนองจากทรัพยากร Dependency ของ UI ลงในเอกสารเป็นแท็กสคริปต์ เอกสาร HTML ที่ได้มีการทำซ้ำในระดับสูง:

ดังที่คุณเห็น เซิร์ฟเวอร์ส่งคืนคำอธิบาย UI ของแอปพลิเคชันเพื่อตอบสนองต่อคำขอการนำทาง แต่เซิร์ฟเวอร์ยังส่งคืนข้อมูลแหล่งที่มาที่ใช้เขียน UI นั้น และสำเนาทั้งหมดของการใช้งาน UI ซึ่งจะบูตขึ้นบนไคลเอ็นต์ UI นี้จะโต้ตอบได้หลังจากโหลดและดำเนินการ bundle.js
เสร็จแล้ว
เมตริกประสิทธิภาพที่รวบรวมจากเว็บไซต์จริงโดยใช้การแสดงผลฝั่งเซิร์ฟเวอร์และการดึงน้ำใหม่ชี้ให้เห็นว่าไม่ควรใช้งานเมตริกนี้ ท้ายที่สุดแล้ว เหตุผลก็มาจากประสบการณ์ของผู้ใช้ กล่าวคือ การปล่อยผู้ใช้ทิ้งไว้ใน "หุบเขาอันแปลกประหลาด" นั้นเป็นเรื่องที่ง่ายอย่างยิ่ง ซึ่งผู้ใช้จะรู้สึกว่าไม่มีการโต้ตอบแม้หน้าเว็บจะปรากฏขึ้นเพื่อพร้อมใช้งานก็ตาม

แต่ก็หวังว่าการแสดงผลฝั่งเซิร์ฟเวอร์จะพร้อมการรีไฮ ในระยะสั้น การใช้การแสดงผลฝั่งเซิร์ฟเวอร์สำหรับเนื้อหาที่สร้างแคชได้สูงเท่านั้นอาจทำให้ TTFB ลดลง ซึ่งทำให้ได้ผลลัพธ์ที่คล้ายกับการแสดงผลล่วงหน้า การเติมน้ำให้ทีละน้อย ค่อยๆ เพิ่ม หรือบางส่วนอาจเป็นกุญแจสำคัญในการทำให้เทคนิคนี้ใช้งานได้จริงมากขึ้นในอนาคต
การสตรีมการแสดงผลฝั่งเซิร์ฟเวอร์และการดึงน้ำแบบโพรเกรสซีฟ
การแสดงผลฝั่งเซิร์ฟเวอร์ได้มีการพัฒนาไปมากในช่วงไม่กี่ปีที่ผ่านมา
การแสดงผลฝั่งเซิร์ฟเวอร์แบบสตรีมมิงช่วยให้คุณส่ง HTML เป็นส่วนๆ ที่เบราว์เซอร์สามารถแสดงผลอย่างต่อเนื่องตามที่ได้รับ ซึ่งอาจส่งผลให้ FCP เร็วเนื่องจากมาร์กอัปจะมาถึงผู้ใช้เร็วขึ้น ใน React สตรีมแบบไม่พร้อมกันใน [renderToPipeableStream()
] เมื่อเทียบกับแบบซิงโครนัส renderToString()
หมายความว่าความดันย้อนกลับจะได้รับการจัดการอย่างดี
การคืนน้ำแบบโพรเกรสซีฟควรพิจารณาด้วยเช่นกัน รวมถึงสิ่งที่ React ลงจอด วิธีนี้ทำให้แต่ละแอปพลิเคชันที่แสดงผลบนเซิร์ฟเวอร์มีการ "บูต" เมื่อเวลาผ่านไป แทนที่จะเป็นวิธีการเริ่มต้นแอปพลิเคชันทั้งหมดพร้อมกันในปัจจุบันที่ใช้กันทั่วไป วิธีนี้จะช่วยลดปริมาณ JavaScript ที่ต้องใช้ในการทำให้หน้าเว็บโต้ตอบได้ เนื่องจากการอัปเกรดฝั่งไคลเอ็นต์ส่วนที่มีลำดับความสำคัญต่ำของหน้าเว็บอาจเลื่อนออกไปเพื่อป้องกันการบล็อกเทรดหลัก ซึ่งจะทำให้การโต้ตอบของผู้ใช้เกิดขึ้นเร็วขึ้นหลังจากที่ผู้ใช้เริ่มต้นการดำเนินการดังกล่าว
การฟื้นฟูแบบโพรเกรสซีฟยังช่วยหลีกเลี่ยงข้อผิดพลาดเกี่ยวกับการคืนข้อมูลการแสดงผลฝั่งเซิร์ฟเวอร์ที่พบได้บ่อยที่สุด ซึ่งโครงสร้าง DOM ที่แสดงผลโดยเซิร์ฟเวอร์ถูกทำลายแล้วสร้างขึ้นใหม่ทันที โดยส่วนใหญ่เป็นเพราะฝั่งไคลเอ็นต์แบบซิงโครนัสตอนแรกแสดงผลข้อมูลที่ยังไม่พร้อมใช้งาน ซึ่งอาจรอให้มีการแก้ไข Promise
เติมน้ำบางส่วน
การคืนน้ำบางส่วนพิสูจน์แล้วว่าทำได้ยาก วิธีนี้เป็นส่วนต่อของแนวคิดเรื่องการค่อยๆ เติมน้ำ (Progressive Rehydration) โดยเป็นการวิเคราะห์ชิ้นส่วนแต่ละชิ้น (ส่วนประกอบ/มุมมอง/ต้นไม้) ที่จะคืนน้ำให้มากขึ้นเรื่อยๆ และตรวจพบชิ้นส่วนที่มีปฏิกิริยาโต้ตอบเพียงเล็กน้อยหรือไม่พบปฏิกิริยาใดๆ สำหรับแต่ละส่วนส่วนใหญ่ที่คงที่เหล่านี้ โค้ด JavaScript ที่เกี่ยวข้องจะเปลี่ยนรูปแบบเป็นการอ้างอิงแบบเฉื่อยและฟังก์ชันการตกแต่ง ลดการใช้งานฝั่งไคลเอ็นต์ลงจนแทบเป็นศูนย์
แนวทางที่ให้น้ำบางส่วนมักจะมีปัญหาและอุปสรรคในตัวเอง การทำเช่นนี้ก่อให้เกิดความท้าทายที่น่าสนใจสำหรับการแคช และการนำทางฝั่งไคลเอ็นต์ทำให้เราไม่สามารถสรุปได้ว่า HTML ที่แสดงผลโดยเซิร์ฟเวอร์สำหรับส่วนเฉื่อยๆ ของแอปพลิเคชันนั้นจะพร้อมใช้งานได้หากไม่มีการโหลดหน้าเว็บแบบเต็ม
การแสดงภาพสามมิติ
หากโปรแกรมทำงานของบริการเป็นตัวเลือกสำหรับคุณ การแสดงภาพแบบ "trisomorphic" ก็อาจเป็นประโยชน์เช่นกัน ซึ่งเป็นเทคนิคที่คุณสามารถใช้การแสดงผลฝั่งเซิร์ฟเวอร์ของสตรีมมิงสำหรับการนำทางเริ่มต้น/ที่ไม่ใช่ JS จากนั้นให้ Service Worker ใช้การแสดงผล HTML สำหรับการนำทางหลังจากติดตั้งแล้ว ซึ่งจะช่วยให้คอมโพเนนต์และเทมเพลตที่แคชไว้เป็นปัจจุบันอยู่เสมอ และเปิดใช้การนำทางแบบ SPA เพื่อแสดงผลมุมมองใหม่ในเซสชันเดียวกัน วิธีนี้จะทำงานได้ดีที่สุดเมื่อคุณแชร์เทมเพลตและรหัสการกำหนดเส้นทางเดียวกันระหว่างเซิร์ฟเวอร์ หน้าไคลเอ็นต์ และ Service Worker

ข้อควรพิจารณาเกี่ยวกับ SEO
ทีมต่างๆ มักคำนึงถึงผลลัพธ์ของ SEO เมื่อเลือกกลยุทธ์สำหรับการแสดงภาพในเว็บ การแสดงผลฝั่งเซิร์ฟเวอร์มักได้รับเลือกเพื่อมอบประสบการณ์ "รูปลักษณ์ที่สมบูรณ์" ซึ่งโปรแกรมรวบรวมข้อมูลสามารถตีความได้อย่างง่ายดาย โปรแกรมรวบรวมข้อมูลอาจเข้าใจ JavaScript แต่มักจะมีข้อจำกัดที่ควรทราบเกี่ยวกับวิธีแสดงผล การแสดงผลฝั่งไคลเอ็นต์อาจใช้งานได้ แต่มักจะไม่เป็นเช่นนั้นหากไม่มีการทดสอบเพิ่มเติมและลงลึกในรายละเอียด เมื่อไม่นานมานี้ การแสดงผลแบบไดนามิกได้กลายเป็นตัวเลือกที่ควรพิจารณาด้วยหากสถาปัตยกรรมของคุณอาศัย JavaScript ฝั่งไคลเอ็นต์อย่างมาก
หากไม่แน่ใจ เครื่องมือทดสอบความเหมาะกับอุปกรณ์เคลื่อนที่มีประโยชน์อย่างยิ่งในการทดสอบว่าแนวทางที่คุณเลือกนั้นสามารถทำสิ่งที่คุณต้องการได้ โดยจะแสดงให้เห็นภาพตัวอย่างของลักษณะที่หน้าเว็บปรากฏต่อโปรแกรมรวบรวมข้อมูลของ Google เนื้อหา HTML ตามลำดับที่พบ (หลังจากเรียกใช้ JavaScript) และข้อผิดพลาดใดๆ ที่พบระหว่างการแสดงผล

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

เครดิต
ขอขอบคุณทุกคนสำหรับรีวิวและแรงบันดาลใจ
Jeffrey Posnick, Houssein Djirdeh, Shubhie Panicker, Chris Harrelson และ Sebastian Markbåge