การแสดงผล HTML ด้วย JavaScript แตกต่างจากการแสดงผล HTML ที่เซิร์ฟเวอร์ส่ง ซึ่งอาจส่งผลต่อประสิทธิภาพ ดูความแตกต่างในคู่มือนี้และสิ่งที่ทําได้เพื่อรักษาประสิทธิภาพการแสดงผลของเว็บไซต์ โดยเฉพาะในกรณีที่เกี่ยวข้องกับการโต้ตอบ
การสับเปลี่ยนและการแสดงผล HTML เป็นงานที่เบราว์เซอร์ทำได้ดีมากโดยค่าเริ่มต้นสําหรับเว็บไซต์ที่ใช้ตรรกะการนําทางในตัวของเบราว์เซอร์ ซึ่งบางครั้งเรียกว่า "การโหลดหน้าเว็บแบบดั้งเดิม" หรือ "การนําทางแบบฮาร์ด" บางครั้งเว็บไซต์ดังกล่าวเรียกว่าแอปพลิเคชันหลายหน้า (MPA)
อย่างไรก็ตาม นักพัฒนาแอปอาจหลีกเลี่ยงค่าเริ่มต้นของเบราว์เซอร์เพื่อให้เหมาะกับความต้องการในแอปพลิเคชันของตน กรณีนี้เกิดขึ้นกับเว็บไซต์ที่ใช้รูปแบบแอปพลิเคชันหน้าเว็บเดียว (SPA) ซึ่งสร้าง HTML/DOM ส่วนใหญ่ในไคลเอ็นต์แบบไดนามิกด้วย JavaScript การแสดงผลฝั่งไคลเอ็นต์เป็นชื่อของรูปแบบการออกแบบนี้ และอาจส่งผลต่อ Interaction to Next Paint (INP) ของเว็บไซต์หากมีการทำงานมากเกินไป
คู่มือนี้จะช่วยคุณพิจารณาความแตกต่างระหว่างการใช้ HTML ที่เซิร์ฟเวอร์ส่งไปยังเบราว์เซอร์กับการสร้าง HTML ในไคลเอ็นต์ด้วย JavaScript และผลกระทบที่อาจเกิดขึ้นเมื่อใช้ JavaScript ซึ่งอาจส่งผลให้เวลาในการตอบสนองของการโต้ตอบสูงในบางช่วงเวลา
วิธีที่เบราว์เซอร์แสดงผล HTML ที่เซิร์ฟเวอร์ให้
รูปแบบการนําทางที่ใช้ในการโหลดหน้าเว็บแบบดั้งเดิมเกี่ยวข้องกับการรับ HTML จากเซิร์ฟเวอร์ในการนําทางทุกครั้ง หากคุณป้อน URL ในแถบที่อยู่ของเบราว์เซอร์หรือคลิกลิงก์ใน MPA เหตุการณ์ต่อไปนี้จะเกิดขึ้น
- เบราว์เซอร์จะส่งคําขอไปยัง URL ที่ระบุ
- เซิร์ฟเวอร์จะตอบกลับด้วย HTML เป็นกลุ่ม
ขั้นตอนสุดท้ายของกระบวนการนี้สำคัญมาก นอกจากนี้ยังเป็นหนึ่งในการเพิ่มประสิทธิภาพพื้นฐานที่สุดในการแลกเปลี่ยนข้อมูลระหว่างเซิร์ฟเวอร์/เบราว์เซอร์ และเรียกว่าสตรีมมิง หากเซิร์ฟเวอร์เริ่มส่ง HTML ได้เร็วที่สุด และเบราว์เซอร์ไม่รอการตอบกลับทั้งหมด เบราว์เซอร์จะประมวลผล HTML เป็นกลุ่มๆ เมื่อได้รับ

เช่นเดียวกับสิ่งต่างๆ ส่วนใหญ่ที่เกิดขึ้นในเบราว์เซอร์ การจัดรูปแบบ HTML จะเกิดขึ้นภายในงาน เมื่อสตรีม HTML จากเซิร์ฟเวอร์ไปยังเบราว์เซอร์ เบราว์เซอร์จะเพิ่มประสิทธิภาพการแยกวิเคราะห์ HTML นั้นด้วยการแยกวิเคราะห์ทีละส่วนเมื่อข้อมูลแต่ละส่วนในสตรีมมาถึง ผลที่ตามมาคือเบราว์เซอร์จะสละสิทธิ์ให้กับเทรดหลักเป็นระยะๆ หลังจากประมวลผลแต่ละกลุ่ม ซึ่งจะช่วยหลีกเลี่ยงงานที่ใช้เวลานาน ซึ่งหมายความว่างานอื่นๆ อาจเกิดขึ้นขณะที่ระบบกำลังแยกวิเคราะห์ HTML ซึ่งรวมถึงงานแสดงผลที่เพิ่มขึ้นซึ่งจําเป็นต่อการแสดงหน้าเว็บต่อผู้ใช้ ตลอดจนการประมวลผลการโต้ตอบของผู้ใช้ที่อาจเกิดขึ้นในช่วงเริ่มต้นที่สำคัญของหน้า แนวทางนี้จะช่วยให้หน้าเว็บได้คะแนน Interaction to Next Paint (INP) ดีขึ้น
สรุปคือ เมื่อสตรีม HTML จากเซิร์ฟเวอร์ คุณจะได้รับการจัดรูปแบบและการแยกวิเคราะห์ HTML ที่เพิ่มขึ้น รวมถึงการส่งผ่านไปยังเธรดหลักโดยอัตโนมัติโดยไม่มีค่าใช้จ่าย ซึ่งคุณจะไม่พบในการแสดงผลฝั่งไคลเอ็นต์
วิธีที่เบราว์เซอร์แสดงผล HTML ที่ JavaScript ระบุ
แม้ว่าคำขอไปยังหน้าเว็บแต่ละรายการจะต้องให้ HTML บางส่วนจากเซิร์ฟเวอร์ แต่เว็บไซต์บางแห่งจะใช้รูปแบบ SPA แนวทางนี้มักจะเกี่ยวข้องกับเพย์โหลด HTML เริ่มต้นขั้นต่ำที่เซิร์ฟเวอร์เป็นผู้จัดหา แต่จากนั้นไคลเอ็นต์จะป้อนข้อมูลในบริเวณเนื้อหาหลักของหน้าเว็บด้วย HTML ที่ประกอบขึ้นจากข้อมูลที่ดึงมาจากเซิร์ฟเวอร์ การนำทางในภายหลัง ซึ่งในกรณีนี้บางครั้งเรียกว่า "การนำทางแบบซอฟต์" จะจัดการโดย JavaScript ทั้งหมดเพื่อป้อนข้อมูล HTML ใหม่ในหน้า
การแสดงผลฝั่งไคลเอ็นต์อาจเกิดขึ้นในเว็บไซต์ที่ไม่ใช่ SPA ในกรณีที่มีข้อจํากัดมากขึ้นด้วย ซึ่งมีการเพิ่ม HTML ไปยัง DOM แบบไดนามิกผ่าน JavaScript
การสร้าง HTML หรือการเพิ่มลงใน DOM ผ่าน JavaScript มีวิธีทั่วไปอยู่ 2-3 วิธีดังนี้
- พร็อพเพอร์ตี้
innerHTML
ช่วยให้คุณตั้งค่าเนื้อหาในองค์ประกอบที่มีอยู่ผ่านสตริง ซึ่งเบราว์เซอร์จะแยกวิเคราะห์เป็น DOM - เมธอด
document.createElement
ช่วยให้คุณสร้างองค์ประกอบใหม่เพื่อเพิ่มลงใน DOM ได้โดยไม่ต้องใช้การแยกวิเคราะห์ HTML ของเบราว์เซอร์ - เมธอด
document.write
ช่วยให้คุณเขียน HTML ลงในเอกสารได้ (และเบราว์เซอร์จะแยกวิเคราะห์ เช่นเดียวกับแนวทางที่ 1) อย่างไรก็ตาม เราไม่แนะนำให้ใช้document.write
เนื่องจากเหตุผลหลายประการ

การสร้าง HTML/DOM ผ่าน JavaScript ฝั่งไคลเอ็นต์อาจส่งผลเสียอย่างมาก ดังนี้
- งาน JavaScript ในไคลเอ็นต์จะไม่แบ่งออกเป็นกลุ่มโดยอัตโนมัติ ซึ่งแตกต่างจาก HTML ที่เซิร์ฟเวอร์สตรีมเพื่อตอบสนองต่อคำขอไปยังส่วนต่างๆ ซึ่งอาจส่งผลให้เกิดงานที่มีขนาดใหญ่ซึ่งบล็อกเธรดหลัก ซึ่งหมายความว่า INP ของหน้าเว็บอาจได้รับผลกระทบในทางลบหากคุณสร้าง HTML/DOM มากเกินไปในครั้งเดียวบนไคลเอ็นต์
- หากมีการสร้าง HTML ในไคลเอ็นต์ระหว่างการเริ่มต้น เครื่องมือสแกนการโหลดล่วงหน้าของเบราว์เซอร์จะไม่ค้นพบทรัพยากรที่อ้างอิงภายใน การดำเนินการนี้จะส่งผลเสียต่อ Largest Contentful Paint (LCP) ของหน้าเว็บอย่างแน่นอน แม้ว่านี่จะไม่ใช่ปัญหาด้านประสิทธิภาพรันไทม์ (แต่เป็นปัญหาความล่าช้าของเครือข่ายในการดึงข้อมูลทรัพยากรสําคัญ) แต่คุณไม่ต้องการให้ LCP ของเว็บไซต์ได้รับผลกระทบจากการละเว้นการเพิ่มประสิทธิภาพเบราว์เซอร์ขั้นพื้นฐานนี้
สิ่งที่คุณทำได้เกี่ยวกับผลกระทบด้านประสิทธิภาพของการแสดงผลฝั่งไคลเอ็นต์
หากเว็บไซต์ของคุณใช้การแสดงผลฝั่งไคลเอ็นต์เป็นส่วนใหญ่และคุณสังเกตเห็นค่า INP ไม่ดีในข้อมูลภาคสนาม คุณอาจสงสัยว่าการแสดงผลฝั่งไคลเอ็นต์มีส่วนเกี่ยวข้องกับปัญหานี้หรือไม่ ตัวอย่างเช่น หากเว็บไซต์เป็น SPA ข้อมูลในช่องอาจแสดงการโต้ตอบที่ทำให้เกิดงานแสดงผลจำนวนมาก
ไม่ว่าสาเหตุจะเป็นอย่างไร ต่อไปนี้คือสาเหตุที่เป็นไปได้บางส่วนที่คุณตรวจสอบได้เพื่อช่วยให้ทุกอย่างกลับมาทำงานได้ตามปกติ
ระบุ HTML จากเซิร์ฟเวอร์ให้ได้มากที่สุด
ดังที่ได้กล่าวไปก่อนหน้านี้ เบราว์เซอร์จะจัดการ HTML จากเซิร์ฟเวอร์อย่างมีประสิทธิภาพสูงโดยค่าเริ่มต้น โดยจะแบ่งการแยกวิเคราะห์และการแสดงผล HTML ในลักษณะที่หลีกเลี่ยงงานที่มีระยะเวลานาน และเพิ่มประสิทธิภาพเวลาทั้งหมดในเทรดหลัก ซึ่งส่งผลให้เวลาในการบล็อกทั้งหมด (TBT) ลดลง และ TBT มีความสัมพันธ์อย่างมากกับ INP
คุณอาจใช้เฟรมเวิร์กส่วนหน้าเพื่อสร้างเว็บไซต์ ในกรณีนี้ คุณต้องตรวจสอบว่าคุณแสดงผล HTML ของคอมโพเนนต์บนเซิร์ฟเวอร์ ซึ่งจะจำกัดปริมาณการแสดงผลครั้งแรกฝั่งไคลเอ็นต์ที่เว็บไซต์ของคุณจําเป็นต้องใช้ และควรส่งผลให้ได้รับประสบการณ์การใช้งานที่ดีขึ้น
- สําหรับ React คุณควรใช้ Server DOM API เพื่อแสดงผล HTML ในเซิร์ฟเวอร์ แต่โปรดทราบว่าวิธีการแบบดั้งเดิมของการแสดงผลฝั่งเซิร์ฟเวอร์ใช้แนวทางแบบซิงค์ ซึ่งอาจทําให้ Time To First Byte (TTFB) นานขึ้น รวมถึงเมตริกที่ตามมา เช่น First Contentful Paint (FCP) และ LCP โปรดตรวจสอบว่าคุณใช้ Streaming API สำหรับ Node.js หรือ รันไทม์ JavaScript อื่นๆ หากเป็นไปได้ เพื่อให้เซิร์ฟเวอร์เริ่มสตรีม HTML ไปยังเบราว์เซอร์โดยเร็วที่สุด Next.js ซึ่งเป็นเฟรมเวิร์กที่ใช้ React มีแนวทางปฏิบัติแนะนำมากมายโดยค่าเริ่มต้น นอกจากการแสดงผล HTML ในเซิร์ฟเวอร์โดยอัตโนมัติแล้ว ยังสามารถสร้าง HTML แบบคงที่สำหรับหน้าเว็บที่ไม่เปลี่ยนแปลงตามบริบทของผู้ใช้ (เช่น การตรวจสอบสิทธิ์) ได้ด้วย
- นอกจากนี้ Vue ยังแสดงผลฝั่งไคลเอ็นต์โดยค่าเริ่มต้นด้วย อย่างไรก็ตาม Vue ยังสามารถแสดงผล HTML ของคอมโพเนนต์บนเซิร์ฟเวอร์ได้เช่นเดียวกับ React ใช้ประโยชน์จาก API ฝั่งเซิร์ฟเวอร์เหล่านี้เมื่อเป็นไปได้ หรือพิจารณาใช้การแยกระดับที่สูงขึ้นสำหรับโปรเจ็กต์ Vue เพื่อให้นำแนวทางปฏิบัติแนะนำไปใช้ได้ง่ายขึ้น
- Svelte จะแสดงผล HTML บนเซิร์ฟเวอร์โดยค่าเริ่มต้น แม้ว่าหากโค้ดคอมโพเนนต์ของคุณจำเป็นต้องเข้าถึงเนมสเปซเฉพาะเบราว์เซอร์ (เช่น
window
) คุณอาจแสดงผล HTML ของคอมโพเนนต์นั้นบนเซิร์ฟเวอร์ไม่ได้ ลองใช้แนวทางอื่นเมื่อเป็นไปได้เพื่อไม่ให้เกิดการเรนเดอร์ฝั่งไคลเอ็นต์ที่ไม่จำเป็น SvelteKit เปรียบเสมือน Next.js สำหรับ React ซึ่งฝังแนวทางปฏิบัติแนะนำจำนวนมากไว้ในโปรเจ็กต์ Svelte เพื่อช่วยให้คุณหลีกเลี่ยงข้อผิดพลาดที่อาจเกิดขึ้นในโปรเจ็กต์ที่ใช้ Svelte เพียงอย่างเดียว
จำกัดจำนวนโหนด DOM ที่สร้างขึ้นบนไคลเอ็นต์
เมื่อ DOM มีขนาดใหญ่ การประมวลผลที่จำเป็นในการแสดงผลมีแนวโน้มที่จะเพิ่มขึ้น ไม่ว่าเว็บไซต์ของคุณจะเป็น SPA ที่สมบูรณ์แบบ หรือจะแทรกโหนดใหม่ลงใน DOM ที่มีอยู่อันเป็นผลมาจากการโต้ตอบสําหรับ MPA ก็ตาม ให้พิจารณาเก็บ DOM เหล่านั้นให้เล็กที่สุดเท่าที่จะเป็นไปได้ วิธีนี้จะช่วยลดความซับซ้อนของงานที่ต้องทำในระหว่างการแสดงผลฝั่งไคลเอ็นต์เพื่อแสดง HTML ดังกล่าว ซึ่งหวังว่าจะช่วยรักษา INP ของเว็บไซต์ให้ต่ำลง
พิจารณาสถาปัตยกรรม Service Worker ของบริการสตรีมมิง
เทคนิคนี้เป็นเทคนิคขั้นสูงที่อาจใช้ไม่ได้กับทุกกรณีการใช้งาน แต่สามารถเปลี่ยน MPA ของคุณให้เป็นเว็บไซต์ที่ดูเหมือนจะโหลดทันทีเมื่อผู้ใช้ไปยังหน้าเว็บถัดไป คุณสามารถใช้ Service Worker เพื่อแคชส่วนแบบคงที่ของเว็บไซต์ใน CacheStorage
ล่วงหน้าขณะใช้ ReadableStream
API เพื่อดึงข้อมูล HTML ที่เหลือของหน้าเว็บจากเซิร์ฟเวอร์
เมื่อใช้เทคนิคนี้สําเร็จ คุณจะไม่ได้สร้าง HTML ในไคลเอ็นต์ แต่การโหลดเนื้อหาบางส่วนจากแคชในทันทีจะทําให้ผู้ใช้รู้สึกว่าเว็บไซต์โหลดเร็ว เว็บไซต์ที่ใช้แนวทางนี้ให้ความรู้สึกเกือบเหมือนกับ SPA แต่ไม่มีข้อเสียของการแสดงผลฝั่งไคลเอ็นต์ และยังลดปริมาณ HTML ที่คุณขอจากเซิร์ฟเวอร์ด้วย
กล่าวโดยย่อคือ สถาปัตยกรรมของเวิร์กเกอร์บริการสตรีมมิงไม่ได้แทนที่ตรรกะการนําทางในตัวของเบราว์เซอร์ แต่เพิ่มเข้าไป ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีดำเนินการนี้ด้วย Workbox ได้ที่แอปพลิเคชันหลายหน้าเร็วขึ้นด้วยสตรีม
บทสรุป
วิธีที่เว็บไซต์รับและแสดงผล HTML จะส่งผลต่อประสิทธิภาพ เมื่อคุณใช้เซิร์ฟเวอร์เพื่อส่ง HTML ทั้งหมด (หรือส่วนใหญ่) ที่จำเป็นต่อการทำงานของเว็บไซต์ คุณจะได้รับประโยชน์มากมายโดยไม่มีค่าใช้จ่าย เช่น การแยกวิเคราะห์และการแสดงผลที่เพิ่มขึ้น รวมถึงการมอบสิทธิ์แก่เธรดหลักโดยอัตโนมัติเพื่อหลีกเลี่ยงงานที่ใช้เวลานาน
การแสดงผล HTML ฝั่งไคลเอ็นต์อาจทำให้เกิดปัญหาด้านประสิทธิภาพหลายประการที่หลีกเลี่ยงได้ในกรณีส่วนใหญ่ อย่างไรก็ตาม ปัญหานี้อาจเกิดขึ้นได้บ้างเนื่องจากข้อกำหนดของแต่ละเว็บไซต์ หากต้องการลดงานที่อาจใช้เวลานานซึ่งอาจเกิดจากการแสดงผลเว็บไซต์ไคลเอ็นต์มากเกินไป ให้ตรวจสอบว่าคุณส่ง HTML ของเว็บไซต์จากเซิร์ฟเวอร์มากที่สุดเท่าที่จะทำได้ รักษาขนาด DOM ให้เล็กที่สุดเท่าที่จะเป็นไปได้สำหรับ HTML ที่ต้องแสดงผลบนไคลเอ็นต์ และพิจารณาใช้สถาปัตยกรรมอื่นเพื่อเพิ่มความเร็วในการนำส่ง HTML ไปยังไคลเอ็นต์ ในขณะเดียวกันก็ใช้ประโยชน์จากการแยกวิเคราะห์และการแสดงผลที่เพิ่มขึ้นซึ่งเบราว์เซอร์มีให้สำหรับ HTML ที่โหลดจากเซิร์ฟเวอร์
หากสามารถลดการแสดงผลฝั่งไคลเอ็นต์ของเว็บไซต์ให้น้อยที่สุดได้ ก็จะไม่เพียงปรับปรุง INP ของเว็บไซต์เท่านั้น แต่ยังปรับปรุงเมตริกอื่นๆ เช่น LCP, TBT และอาจรวมถึง TTFB ในบางกรณีด้วย
รูปภาพหลักจาก Unsplash โดย Maik Jonietz