การแสดงผล HTML และการโต้ตอบฝั่งไคลเอ็นต์

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

การแยกวิเคราะห์และการแสดงผล HTML เป็นสิ่งที่เบราว์เซอร์ทำได้ดีมากโดยค่าเริ่มต้นสำหรับเว็บไซต์ที่ใช้ตรรกะการนำทางในตัวของเบราว์เซอร์ ซึ่งบางครั้งเรียกว่า "การโหลดหน้าเว็บแบบดั้งเดิม" หรือ "การนำทางแบบฮาร์ด" บางครั้งเว็บไซต์ลักษณะนี้เรียกว่าแอปพลิเคชันแบบหลายหน้า (MPA)

อย่างไรก็ตาม นักพัฒนาแอปอาจหลีกเลี่ยงค่าเริ่มต้นของเบราว์เซอร์เพื่อให้เหมาะกับความต้องการของแอปพลิเคชันได้ ซึ่งเป็นกรณีที่เกิดขึ้นกับเว็บไซต์ที่ใช้รูปแบบแอปพลิเคชันหน้าเว็บเดียว (SPA) ซึ่งสร้างส่วนขนาดใหญ่ของ HTML/DOM ในฝั่งไคลเอ็นต์ด้วย JavaScript แบบไดนามิก การแสดงผลฝั่งไคลเอ็นต์คือชื่อของรูปแบบการออกแบบนี้ และอาจส่งผลต่อ Interaction to Next Paint (INP) ของเว็บไซต์หากมีงานที่เกี่ยวข้องมากเกินไป

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

วิธีที่เบราว์เซอร์แสดงผล HTML ที่เซิร์ฟเวอร์ให้มา

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

  1. เบราว์เซอร์จะส่งคำขอไปยังส่วนต่างๆ สำหรับ URL ที่ระบุ
  2. เซิร์ฟเวอร์จะตอบสนองด้วย HTML เป็นกลุ่มๆ

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

ภาพหน้าจอของการแยกวิเคราะห์ HTML ที่เซิร์ฟเวอร์ส่งมาซึ่งแสดงในแผงประสิทธิภาพของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome เมื่อสตรีม HTML เข้ามา ระบบจะประมวลผลข้อมูลเป็นกลุ่มๆ ในงานที่สั้นลงหลายงาน และการแสดงผลจะเพิ่มขึ้นทีละน้อย
การแยกวิเคราะห์และการแสดงผล HTML ที่เซิร์ฟเวอร์จัดเตรียมไว้ตามที่แสดงในแผงประสิทธิภาพของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome งานที่เกี่ยวข้องกับการแยกวิเคราะห์ 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 วิธีดังนี้

  1. พร็อพเพอร์ตี้ innerHTML ช่วยให้คุณตั้งค่าเนื้อหาในองค์ประกอบที่มีอยู่ผ่านสตริง ซึ่งเบราว์เซอร์จะแยกวิเคราะห์เป็น DOM
  2. เมธอด document.createElement ช่วยให้คุณสร้างองค์ประกอบใหม่เพื่อเพิ่มลงใน DOM ได้โดยไม่ต้องใช้การแยกวิเคราะห์ HTML ของเบราว์เซอร์
  3. เมธอด document.write ช่วยให้คุณเขียน HTML ลงในเอกสารได้ (และเบราว์เซอร์จะแยกวิเคราะห์ HTML ดังกล่าว เช่นเดียวกับในแนวทางที่ 1) อย่างไรก็ตาม เนื่องจากเหตุผลหลายประการ เราจึงไม่แนะนำให้ใช้ document.write
ภาพหน้าจอของการแยกวิเคราะห์ HTML ที่แสดงผลผ่าน JavaScript ซึ่งแสดงในแผงประสิทธิภาพของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome การทำงานจะเกิดขึ้นในงานเดียวที่ใช้เวลานานซึ่งบล็อกเทรดหลัก
การแยกวิเคราะห์และการแสดงผล HTML ผ่าน JavaScript ในไคลเอ็นต์ตามที่แสดงในแผงประสิทธิภาพของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome งานที่เกี่ยวข้องกับการแยกวิเคราะห์และการแสดงผลไม่ได้แบ่งออกเป็นส่วนๆ ส่งผลให้เกิดงานที่ใช้เวลานานซึ่งบล็อกเทรดหลัก

ผลที่ตามมาของการสร้าง HTML/DOM ผ่าน JavaScript ฝั่งไคลเอ็นต์อาจมีนัยสำคัญ ดังนี้

  • งาน JavaScript ในไคลเอ็นต์จะไม่ถูกแบ่งเป็นส่วนๆ โดยอัตโนมัติ ซึ่งต่างจาก HTML ที่เซิร์ฟเวอร์สตรีมเพื่อตอบสนองต่อคำขอการนำทาง ซึ่งอาจส่งผลให้เกิดงานที่ใช้เวลานานซึ่งบล็อกเทรดหลัก ซึ่งหมายความว่า INP ของหน้าเว็บอาจได้รับผลกระทบในทางลบหากคุณสร้าง HTML/DOM มากเกินไปในแต่ละครั้งในฝั่งไคลเอ็นต์
  • หากมีการสร้าง HTML ในไคลเอ็นต์ระหว่างการเริ่มต้นระบบ ทรัพยากรที่อ้างอิงภายใน HTML นั้นจะไม่ถูกค้นพบโดยเครื่องมือสแกนการโหลดล่วงหน้าของเบราว์เซอร์ ซึ่งจะส่งผลเสียต่อ Largest Contentful Paint (LCP) ของหน้าเว็บอย่างแน่นอน แม้ว่าปัญหานี้จะไม่ใช่ปัญหาด้านประสิทธิภาพรันไทม์ (แต่เป็นปัญหาความล่าช้าของเครือข่ายในการดึงข้อมูลทรัพยากรที่สำคัญ) คุณคงไม่ต้องการให้ LCP ของเว็บไซต์ได้รับผลกระทบจากการหลีกเลี่ยงการเพิ่มประสิทธิภาพเบราว์เซอร์ขั้นพื้นฐานนี้

สิ่งที่คุณทำได้เกี่ยวกับผลกระทบด้านประสิทธิภาพของการแสดงผลฝั่งไคลเอ็นต์

หากเว็บไซต์ของคุณอาศัยการแสดงผลฝั่งไคลเอ็นต์เป็นอย่างมาก และคุณสังเกตเห็นค่า INP ที่ไม่ดีในข้อมูลภาคสนาม คุณอาจสงสัยว่าการแสดงผลฝั่งไคลเอ็นต์เกี่ยวข้องกับปัญหาหรือไม่ ตัวอย่างเช่น หากเว็บไซต์เป็น SPA ข้อมูลภาคสนามอาจแสดงการโต้ตอบที่รับผิดชอบงานการแสดงผลจำนวนมาก

ไม่ว่าสาเหตุจะเป็นอะไร ต่อไปนี้คือสาเหตุที่เป็นไปได้ซึ่งคุณสามารถตรวจสอบเพื่อช่วยให้ทุกอย่างกลับมาเป็นปกติ

ระบุ HTML จากเซิร์ฟเวอร์ให้มากที่สุดเท่าที่จะทำได้

ดังที่กล่าวไว้ก่อนหน้านี้ เบราว์เซอร์จะจัดการ HTML จากเซิร์ฟเวอร์ด้วยวิธีที่มีประสิทธิภาพสูงโดยค่าเริ่มต้น ซึ่งจะแยกการแยกวิเคราะห์และการแสดงผล HTML ในลักษณะที่หลีกเลี่ยงงานที่ใช้เวลานาน และเพิ่มประสิทธิภาพระยะเวลาทั้งหมดของเทรดหลัก ซึ่งจะส่งผลให้เวลาทั้งหมดในการบล็อก (TBT) ลดลง และ TBT มีความสัมพันธ์อย่างมากกับ INP

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

  • สำหรับ React คุณจะต้องใช้ Server DOM API เพื่อแสดงผล HTML บนเซิร์ฟเวอร์ แต่โปรดทราบว่าวิธีการแสดงผลฝั่งเซิร์ฟเวอร์แบบดั้งเดิมจะใช้แนวทางแบบซิงโครนัส ซึ่งอาจทำให้เวลาที่ได้รับข้อมูลไบต์แรก (TTFB) นานขึ้น รวมถึงเมตริกที่ตามมา เช่น First Contentful Paint (FCP) และ LCP หากเป็นไปได้ ให้ตรวจสอบว่าคุณใช้ API การสตรีมสำหรับ Node.js หรือรันไทม์ JavaScript อื่นๆ เพื่อให้เซิร์ฟเวอร์เริ่มสตรีม HTML ไปยังเบราว์เซอร์ได้โดยเร็วที่สุด Next.js ซึ่งเป็นเฟรมเวิร์กที่ใช้ React มีแนวทางปฏิบัติแนะนำมากมายโดยค่าเริ่มต้น นอกจากการแสดงผล HTML บนเซิร์ฟเวอร์โดยอัตโนมัติแล้ว ยังสามารถสร้าง HTML แบบคงที่สำหรับหน้าเว็บที่ไม่เปลี่ยนแปลงตามบริบทของผู้ใช้ (เช่น การตรวจสอบสิทธิ์) ได้ด้วย
  • Vue ยังทำการแสดงผลฝั่งไคลเอ็นต์โดยค่าเริ่มต้นด้วย อย่างไรก็ตาม Vue ยังสามารถแสดงผล HTML ของคอมโพเนนต์บนเซิร์ฟเวอร์ได้เช่นเดียวกับ React ใช้ประโยชน์จาก API ฝั่งเซิร์ฟเวอร์เหล่านี้เมื่อเป็นไปได้ หรือพิจารณาใช้นามธรรมระดับสูงขึ้นสำหรับโปรเจ็กต์ Vue เพื่อให้ใช้แนวทางปฏิบัติแนะนำได้ง่ายขึ้น
  • Svelte แสดงผล HTML บนเซิร์ฟเวอร์โดยค่าเริ่มต้น แม้ว่าโค้ดคอมโพเนนต์ของคุณจำเป็นต้องเข้าถึงเนมสเปซเฉพาะเบราว์เซอร์ (เช่น window) คุณอาจแสดงผล HTML ของคอมโพเนนต์นั้นบนเซิร์ฟเวอร์ไม่ได้ สำรวจแนวทางอื่นๆ ที่เป็นไปได้เพื่อไม่ให้เกิดการแสดงผลฝั่งไคลเอ็นต์โดยไม่จำเป็น SvelteKit ซึ่งเป็นเฟรมเวิร์กสำหรับ Svelte เช่นเดียวกับที่ 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 ที่คุณขอจากเซิร์ฟเวอร์ด้วย

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

บทสรุป

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

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

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