ดูว่าเครื่องมือสแกนการโหลดล่วงหน้าของเบราว์เซอร์คืออะไร ประโยชน์ต่อประสิทธิภาพ และวิธีหลีกเลี่ยง
สิ่งหนึ่งที่มักถูกมองข้ามเกี่ยวกับการเพิ่มประสิทธิภาพความเร็วหน้าเว็บคือการรู้จักข้อมูลภายในของเบราว์เซอร์ เบราว์เซอร์จะทำการปรับปรุงบางอย่างเพื่อเพิ่มประสิทธิภาพในลักษณะที่เราในฐานะนักพัฒนาแอปทำไม่ได้ แต่จะทำได้ก็ต่อเมื่อไม่มีการขัดขวางการปรับปรุงเหล่านั้นโดยไม่ตั้งใจ
การเพิ่มประสิทธิภาพเบราว์เซอร์ภายในอย่างหนึ่งที่คุณควรทราบคือเครื่องมือสแกนการโหลดล่วงหน้าของเบราว์เซอร์ โพสต์นี้จะอธิบายวิธีการทำงานของเครื่องมือสแกนเพื่อโหลดล่วงหน้า และที่สำคัญกว่านั้นคือวิธีหลีกเลี่ยงไม่ให้เครื่องมือทำงานขัดข้อง
เครื่องมือสแกนการโหลดล่วงหน้าคืออะไร
เบราว์เซอร์ทุกตัวมีโปรแกรมแยกวิเคราะห์ HTML หลักที่แยกคำมาร์กอัปดิบ และประมวลผลเป็นโมเดลออบเจ็กต์ การดำเนินการทั้งหมดนี้ดำเนินไปอย่างราบรื่นจนกว่าโปรแกรมแยกวิเคราะห์จะหยุดชั่วคราวเมื่อพบทรัพยากรที่บล็อก เช่น สไตล์ชีตที่โหลดด้วยองค์ประกอบ <link>
หรือสคริปต์ที่โหลดด้วยองค์ประกอบ <script>
ที่ไม่มีแอตทริบิวต์ async
หรือ defer
ในกรณีของไฟล์ CSS ระบบจะบล็อกการแสดงผลเพื่อป้องกันเนื้อหาที่ไม่มีการจัดรูปแบบ (FOUC) ซึ่งก็คือการที่ผู้ใช้เห็นหน้าเว็บเวอร์ชันที่ไม่มีการจัดรูปแบบเป็นระยะเวลาสั้นๆ ก่อนที่จะมีการใช้สไตล์กับหน้านั้น
นอกจากนี้เบราว์เซอร์ยังบล็อกการแยกวิเคราะห์และการแสดงผลหน้าเว็บเมื่อพบองค์ประกอบ <script>
ที่ไม่มีแอตทริบิวต์ defer
หรือ async
ด้วย
สาเหตุคือเบราว์เซอร์ไม่สามารถทราบได้อย่างแน่ชัดว่าสคริปต์ใดจะแก้ไข DOM ขณะเครื่องมือแยกวิเคราะห์ HTML หลักยังคงทํางานอยู่หรือไม่ ด้วยเหตุนี้ แนวทางปฏิบัติทั่วไปจึงเป็นการโหลด JavaScript ที่ส่วนท้ายของเอกสารเพื่อให้ผลของการแยกวิเคราะห์และการเรนเดอร์ที่ถูกบล็อกมีน้อยที่สุด
เหตุผลเหล่านี้เป็นเหตุผลที่เบราว์เซอร์ควรบล็อกทั้งการแยกวิเคราะห์และการเรนเดอร์ อย่างไรก็ตาม การบล็อกขั้นตอนสำคัญเหล่านี้ไม่เป็นสิ่งที่พึงประสงค์ เนื่องจากอาจทำให้การแสดงล่าช้าโดยการเลื่อนเวลาการค้นพบทรัพยากรสำคัญอื่นๆ แต่โชคดีที่เบราว์เซอร์พยายามอย่างเต็มที่เพื่อลดปัญหาเหล่านี้ด้วยเครื่องมือแยกวิเคราะห์ HTML รองที่เรียกว่าเครื่องมือสแกนการโหลดล่วงหน้า
บทบาทของสแกนเนอร์การโหลดล่วงหน้าคือการคาดเดา ซึ่งหมายความว่าจะตรวจสอบมาร์กอัปดิบเพื่อค้นหาทรัพยากรที่จะดึงข้อมูลเมื่อมีโอกาสก่อนที่โปรแกรมแยกวิเคราะห์ HTML หลักจะค้นพบ
วิธีดูว่าเครื่องมือสแกนเพื่อโหลดล่วงหน้าทำงานอยู่หรือไม่
เครื่องมือสแกนเพื่อโหลดล่วงหน้ามีอยู่เนื่องจากการแสดงผลและการแยกวิเคราะห์ถูกบล็อก หากไม่พบปัญหาด้านประสิทธิภาพ 2 ประการนี้ เครื่องมือสแกนเพื่อโหลดล่วงหน้าจะไม่ค่อยมีประโยชน์ ปัจจัยสําคัญในการระบุว่าหน้าเว็บได้รับประโยชน์จากเครื่องมือสแกนการโหลดล่วงหน้าหรือไม่นั้นขึ้นอยู่กับปรากฏการณ์การบล็อกเหล่านี้ โดยคุณสามารถเพิ่มการหน่วงเวลาเทียมสําหรับคําขอเพื่อดูว่าเครื่องมือสแกนการโหลดล่วงหน้าทํางานอยู่ที่ไหน
ยกตัวอย่างจากหน้านี้ซึ่งมีข้อความและรูปภาพพื้นฐานที่มีสไตล์ชีต เนื่องจากไฟล์ CSS บล็อกทั้งการแสดงผลและการแยกวิเคราะห์ คุณจึงต้องเพิ่มการหน่วงเวลา 2 วินาทีให้กับสไตล์ชีตผ่านบริการพร็อกซี ความล่าช้านี้ช่วยให้เห็นได้ง่ายขึ้นใน Waterfall ของเครือข่ายว่าเครื่องมือสแกนเพื่อโหลดล่วงหน้าทํางานอยู่
ดังที่คุณเห็นในการแสดงภาพ Waterfall ตัวสแกนการโหลดล่วงหน้าจะพบองค์ประกอบ <img>
แม้ว่าระบบจะบล็อกการแสดงผลและการแยกวิเคราะห์เอกสาร หากไม่มีการเพิ่มประสิทธิภาพนี้ เบราว์เซอร์จะดึงข้อมูลตามโอกาสไม่ได้ในช่วงที่บล็อกอยู่ และคำขอทรัพยากรเพิ่มเติมจะส่งต่อกันแทนที่จะส่งพร้อมกัน
หลังจากดูตัวอย่างสมมติกันไปแล้ว เรามาดูรูปแบบในชีวิตจริงที่อาจหลบเลี่ยงการสแกนการโหลดล่วงหน้าได้ และวิธีแก้ไขกัน
สคริปต์ async
ที่แทรก
สมมติว่าคุณมี HTML ใน <head>
ที่มี JavaScript ในบรรทัด เช่น
<script>
const scriptEl = document.createElement('script');
scriptEl.src = '/yall.min.js';
document.head.appendChild(scriptEl);
</script>
สคริปต์ที่แทรกจะเป็น async
โดยค่าเริ่มต้น ดังนั้นเมื่อแทรกสคริปต์นี้ ระบบจะทํางานเหมือนกับว่ามีการใช้แอตทริบิวต์ async
กับสคริปต์ ซึ่งหมายความว่าจะทํางานโดยเร็วที่สุดและจะไม่บล็อกการแสดงผล ฟังดูเหมาะเจาะดีใช่ไหม แต่หากคุณคิดว่า <script>
ในบรรทัดนี้อยู่หลังองค์ประกอบ <link>
ที่โหลดไฟล์ CSS ภายนอก คุณจะได้รับผลลัพธ์ที่ไม่เหมาะสม
มาดูรายละเอียดสิ่งที่เกิดขึ้นกัน
- เมื่อถึง 0 วินาที ระบบจะขอเอกสารหลัก
- เมื่อถึง 1.4 วินาที ไบต์แรกของคำขอการนําทางจะมาถึง
- เมื่อถึง 2.0 วินาที ระบบจะขอ CSS และรูปภาพ
- เนื่องจากโปรแกรมแยกวิเคราะห์ถูกบล็อกไม่ให้โหลดสไตล์ชีต และ JavaScript แบบอินไลน์ที่แทรกสคริปต์
async
มาหลังสไตล์ชีตนั้นที่ 2.6 วินาที ฟังก์ชันการทำงานที่สคริปต์ให้จึงใช้งานไม่ได้เร็วที่สุดเท่าที่ควร
ซึ่งไม่เหมาะที่สุดเนื่องจากคําขอสคริปต์จะเกิดขึ้นหลังจากที่ดาวน์โหลดสไตล์ชีตเสร็จแล้วเท่านั้น ซึ่งจะทำให้สคริปต์ทำงานล่าช้า ในทางตรงกันข้าม เครื่องมือสแกนเพื่อโหลดล่วงหน้าจะค้นพบองค์ประกอบ <img>
เนื่องจากค้นพบได้ในมาร์กอัปที่เซิร์ฟเวอร์ระบุ
จะเกิดอะไรขึ้นหากคุณใช้แท็ก <script>
ปกติที่มีแอตทริบิวต์ async
แทนที่จะแทรกสคริปต์ลงใน DOM
<script src="/yall.min.js" async></script>
ผลลัพธ์ที่ได้คือ
คุณอาจอยากแนะนำให้แก้ปัญหาเหล่านี้โดยใช้ rel=preload
วิธีนี้ได้ผลแน่นอน แต่อาจมีผลข้างเคียงบางอย่าง ท้ายที่สุดแล้ว เหตุใดจึงต้องใช้ rel=preload
เพื่อแก้ไขปัญหาที่หลีกเลี่ยงได้ด้วยการไม่แทรกองค์ประกอบ <script>
ลงใน DOM
การป้อนข้อมูลล่วงหน้า "แก้ไข" ปัญหานี้ แต่ทำให้เกิดปัญหาใหม่คือ สคริปต์ async
ในเดโม 2 รายการแรกแม้จะโหลดใน <head>
ก็ตาม แต่ระบบจะโหลดด้วยลําดับความสําคัญ "ต่ำ" ส่วนสไตล์ชีตจะโหลดด้วยลําดับความสําคัญ "สูงสุด" ในเดโมล่าสุดที่โหลดสคริปต์ async
ไว้ล่วงหน้า ไฟล์สไตล์จะยังคงโหลดโดยมีลําดับความสําคัญเป็น "สูงสุด" แต่ลําดับความสําคัญของสคริปต์ได้รับการเลื่อนเป็น "สูง"
เมื่อเพิ่มลําดับความสําคัญของทรัพยากร เบราว์เซอร์จะจัดสรรแบนด์วิดท์ให้ทรัพยากรนั้นมากขึ้น ซึ่งหมายความว่าแม้ว่าไฟล์สไตล์จะมีลําดับความสําคัญสูงสุด แต่การขึ้นลําดับความสําคัญของสคริปต์อาจทําให้เกิดการแย่งแบนด์วิดท์ ซึ่งอาจเป็นปัจจัยที่ทำให้เกิดการเชื่อมต่อที่ช้า หรือในกรณีที่ทรัพยากรมีขนาดใหญ่
คำตอบนั้นง่ายมาก หากต้องใช้สคริปต์ระหว่างการเริ่มต้น ให้หลีกเลี่ยงการสกัดการสแกนการโหลดล่วงหน้าโดยการแทรกสคริปต์ลงใน DOM ทดสอบตำแหน่งองค์ประกอบ <script>
และแอตทริบิวต์ต่างๆ เช่น defer
และ async
ตามที่จำเป็น
การโหลดเมื่อจำเป็นด้วย JavaScript
การโหลดแบบเลื่อนเวลาเป็นวิธีที่ยอดเยี่ยมในการประหยัดข้อมูล ซึ่งมักใช้กับรูปภาพ อย่างไรก็ตาม บางครั้งระบบอาจใช้การโหลดแบบเลื่อนลงอย่างไม่ถูกต้องกับรูปภาพที่ "อยู่เหนือส่วนที่มีการแบ่งหน้า"
ซึ่งอาจทำให้เกิดปัญหาเกี่ยวกับความสามารถในการค้นพบทรัพยากรในส่วนที่เกี่ยวข้องกับเครื่องมือสแกนเพื่อโหลดล่วงหน้า และอาจทำให้การค้นพบการอ้างอิงรูปภาพ การดาวน์โหลด การถอดรหัส และการแสดงรูปภาพล่าช้าโดยไม่จำเป็น มาดูตัวอย่างมาร์กอัปรูปภาพนี้กัน
<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">
การใช้คำนำหน้า data-
เป็นรูปแบบที่พบได้ทั่วไปในเครื่องมือโหลดแบบเลื่อนเวลา (Lazy Loader) ที่ทำงานด้วย JavaScript เมื่อเลื่อนรูปภาพไปยังวิวพอร์ต ตัวโหลดแบบเลื่อนดูทีละส่วนจะตัดคำนำหน้า data-
ออก ซึ่งหมายความว่าในตัวอย่างก่อนหน้านี้ data-src
จะกลายเป็น src
การอัปเดตนี้จะแจ้งให้เบราว์เซอร์ดึงข้อมูล
รูปแบบนี้จะไม่มีปัญหาจนกว่าจะใช้กับรูปภาพที่อยู่ในวิวพอร์ตระหว่างการเริ่มต้น เนื่องจากเครื่องมือสแกนการโหลดล่วงหน้าไม่ได้อ่านแอตทริบิวต์ data-src
ในลักษณะเดียวกับที่อ่านแอตทริบิวต์ src
(หรือ srcset
) ระบบจึงไม่พบการอ้างอิงรูปภาพก่อนหน้านี้ ที่แย่กว่านั้นคือรูปภาพจะโหลดล่าช้าจนกว่าจะหลัง JavaScript ของ Lazy Loader ดาวน์โหลด คอมไพล์ และดำเนินการ
รูปภาพอาจเป็นองค์ประกอบที่เป็นไปได้สำหรับ Largest Contentful Paint (LCP) ทั้งนี้ขึ้นอยู่กับขนาดของรูปภาพ ซึ่งอาจขึ้นอยู่กับขนาดของวิวพอร์ต เมื่อเครื่องมือสแกนการโหลดล่วงหน้าไม่สามารถคาดเดาและดึงข้อมูลทรัพยากรรูปภาพล่วงหน้าได้ ซึ่งอาจเกิดขึ้นเมื่อสไตล์ชีตของหน้าเว็บบล็อกการแสดงผล LCP จะได้รับผลกระทบ
วิธีแก้ปัญหาคือเปลี่ยนมาร์กอัปรูปภาพ โดยทำดังนี้
<img src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">
รูปแบบนี้เป็นรูปแบบที่ดีที่สุดสำหรับรูปภาพที่อยู่ในวิวพอร์ตระหว่างการเริ่มต้น เนื่องจากเครื่องมือสแกนเพื่อโหลดล่วงหน้าจะค้นพบและดึงข้อมูลทรัพยากรรูปภาพได้เร็วขึ้น
ผลลัพธ์ในตัวอย่างที่เข้าใจง่ายนี้คือ LCP ดีขึ้น 100 มิลลิวินาทีในการเชื่อมต่อที่ช้า การดำเนินการนี้อาจดูเหมือนไม่ใช่การปรับปรุงครั้งใหญ่ แต่จริงๆ แล้วเป็นเช่นนั้นเมื่อพิจารณาว่าโซลูชันนี้เป็นวิธีแก้ไขมาร์กอัปอย่างรวดเร็ว และหน้าเว็บส่วนใหญ่มีความซับซ้อนกว่าชุดตัวอย่างนี้ ซึ่งหมายความว่าผู้สมัคร LCP อาจต้องแย่งแบนด์วิดท์กับทรัพยากรอื่นๆ อีกมากมาย การเพิ่มประสิทธิภาพเช่นนี้จึงมีความสำคัญมากขึ้นเรื่อยๆ
รูปภาพพื้นหลัง CSS
โปรดทราบว่าเครื่องมือสแกนการโหลดล่วงหน้าของเบราว์เซอร์จะสแกนมาร์กอัป แต่จะไม่ได้สแกนทรัพยากรประเภทอื่นๆ เช่น CSS ซึ่งอาจเกี่ยวข้องกับการดึงข้อมูลรูปภาพที่อ้างอิงโดยพร็อพเพอร์ตี้ background-image
เช่นเดียวกับ HTML เบราว์เซอร์จะประมวลผล CSS เป็นโมเดลออบเจ็กต์ของตัวเอง ซึ่งเรียกว่า CSSOM หากพบทรัพยากรภายนอกขณะสร้าง CSSOM ระบบจะขอทรัพยากรเหล่านั้น ณ เวลาที่ค้นพบ ไม่ใช่โดยเครื่องมือสแกนเพื่อโหลดล่วงหน้า
สมมติว่า LCP Candidate ของหน้าเว็บคือองค์ประกอบที่มีพร็อพเพอร์ตี้ background-image
ของ CSS สิ่งที่จะเกิดขึ้นเมื่อโหลดทรัพยากรมีดังนี้
ในกรณีนี้ การสแกนเพื่อโหลดล่วงหน้าไม่ได้ถูกบล็อก แต่ไม่ได้มีส่วนเกี่ยวข้อง อย่างไรก็ตาม หาก LCP ที่เป็นไปได้ในหน้าเว็บมาจากพร็อพเพอร์ตี้ background-image
CSS คุณจะต้องโหลดรูปภาพนั้นล่วงหน้า โดยทำดังนี้
<!-- Make sure this is in the <head> below any
stylesheets, so as not to block them from loading -->
<link rel="preload" as="image" href="lcp-image.jpg">
คำแนะนำ rel=preload
นั้นเล็ก แต่ช่วยให้เบราว์เซอร์ค้นพบรูปภาพได้เร็วขึ้น
การใช้คำแนะนำ rel=preload
จะทำให้ระบบค้นพบ LCP ที่เป็นไปได้เร็วขึ้น ซึ่งจะช่วยลดเวลา LCP แม้ว่าคำแนะนำดังกล่าวจะช่วยแก้ไขปัญหานี้ได้ แต่ตัวเลือกที่ดีกว่าอาจเป็นการประเมินว่า LCP ของรูปภาพต้องต้องโหลดจาก CSS หรือไม่ การใช้แท็ก <img>
จะช่วยให้คุณควบคุมการโหลดรูปภาพที่เหมาะกับวิวพอร์ตได้มากขึ้น ในขณะเดียวกันก็อนุญาตให้เครื่องมือสแกนการโหลดล่วงหน้าค้นพบรูปภาพดังกล่าว
การแทรกทรัพยากรมากเกินไป
การแทรกในบรรทัดคือแนวทางปฏิบัติที่วางทรัพยากรภายใน HTML คุณสามารถแทรกสไตล์ชีตในองค์ประกอบ <style>
, สคริปต์ในองค์ประกอบ <script>
และทรัพยากรอื่นๆ เกือบทั้งหมดได้โดยใช้การเข้ารหัส Base64
การแทรกทรัพยากรในหน้าเว็บอาจเร็วกว่าการดาวน์โหลด เนื่องจากระบบจะไม่ส่งคําขอแยกต่างหากสําหรับทรัพยากร วิดีโอจะแสดงในเอกสารและโหลดทันที แต่มีข้อเสียที่สำคัญดังนี้
- หากคุณไม่ได้แคช HTML และไม่สามารถแคชได้หากการตอบกลับ HTML เป็นแบบไดนามิก ระบบจะไม่แคชทรัพยากรที่ฝังไว้ ซึ่งส่งผลต่อประสิทธิภาพเนื่องจากทรัพยากรที่ฝังไว้ใช้ซ้ำไม่ได้
- แม้ว่าคุณจะแคช HTML ได้ แต่ระบบจะไม่แชร์ทรัพยากรที่ฝังไว้ระหว่างเอกสาร ซึ่งจะลดประสิทธิภาพการแคชเมื่อเทียบกับไฟล์ภายนอกที่แคชและนํามาใช้ซ้ำได้ทั่วทั้งต้นทาง
- หากคุณใส่โค้ดในบรรทัดมากเกินไป จะทำให้การสแกนเพื่อโหลดล่วงหน้าค้นพบทรัพยากรในภายหลังของเอกสารล่าช้า เนื่องจากการดาวน์โหลดเนื้อหาเพิ่มเติมในบรรทัดนั้นใช้เวลานานกว่า
มาดูตัวอย่างจากหน้านี้ ในบางเงื่อนไข องค์ประกอบ LCP ที่เป็นไปได้คือรูปภาพที่อยู่ด้านบนของหน้า และ CSS อยู่ในไฟล์แยกต่างหากที่โหลดโดยองค์ประกอบ <link>
หน้าเว็บนี้ยังใช้แบบอักษรเว็บ 4 แบบซึ่งระบบขอเป็นไฟล์แยกต่างหากจากทรัพยากร CSS
จะเกิดอะไรขึ้นหาก CSS และแบบอักษรทั้งหมดอยู่ในบรรทัดเดียวกันเป็นทรัพยากร Base64
ผลกระทบของการฝังโค้ดส่งผลเสียต่อ LCP และประสิทธิภาพโดยรวมในตัวอย่างนี้ เวอร์ชันของหน้าเว็บที่ไม่ได้ฝังสิ่งใดเลยจะแสดงภาพ LCP ในประมาณ 3.5 วินาที หน้าเว็บที่แทรกทุกอย่างในบรรทัดเดียวกันไม่แสดงภาพ LCP จนกว่าจะผ่านไป 7 วินาที
ปัญหานี้เกิดจากหลายสาเหตุ ไม่ใช่แค่เครื่องมือสแกนการโหลดล่วงหน้า การวางแบบฝังฟอนต์ไม่ใช่กลยุทธ์ที่ดีเนื่องจาก base64 เป็นรูปแบบที่ไม่มีประสิทธิภาพสำหรับทรัพยากรไบนารี ปัจจัยอีกประการหนึ่งคือระบบจะไม่ดาวน์โหลดแหล่งข้อมูลแบบอักษรภายนอก เว้นแต่ CSSOM จะพิจารณาว่าจําเป็น เมื่อแทรกแบบฝังเป็น Base64 ระบบจะดาวน์โหลดแบบอักษรเหล่านั้นไม่ว่าจะจำเป็นสำหรับหน้าปัจจุบันหรือไม่ก็ตาม
การโหลดล่วงหน้าช่วยแก้ปัญหานี้ได้ไหม เอาสิ คุณอาจโหลดรูปภาพ LCP ล่วงหน้าและลดเวลา LCP ได้ แต่การเพิ่มทรัพยากรที่ฝังใน HTML ซึ่งอาจแคชไม่ได้จะส่งผลเสียต่อประสิทธิภาพอื่นๆ First Contentful Paint (FCP) ก็ได้รับผลกระทบจากรูปแบบนี้ด้วย ในเวอร์ชันของหน้าเว็บที่ไม่มีบรรทัดแรก FCP อยู่ที่ประมาณ 2.7 วินาที ในเวอร์ชันที่ฝังทุกอย่างไว้ FCP อยู่ที่ประมาณ 5.8 วินาที
โปรดระมัดระวังอย่างยิ่งเมื่อแทรกข้อมูลลงใน HTML โดยเฉพาะแหล่งข้อมูลที่เข้ารหัส Base64 โดยทั่วไปแล้วเราไม่แนะนำ ยกเว้นในกรณีที่มีทรัพยากรน้อยมาก ใช้การฝังในบรรทัดน้อยที่สุดเท่าที่จะเป็นไปได้ เนื่องจากการใช้การฝังในบรรทัดมากเกินไปเป็นการกระทำที่เสี่ยง
การแสดงผลมาร์กอัปด้วย JavaScript ฝั่งไคลเอ็นต์
JavaScript ส่งผลต่อความเร็วของหน้าเว็บอย่างแน่นอน นักพัฒนาแอปไม่เพียงใช้วิดีโอเพื่อมอบประสบการณ์การโต้ตอบเท่านั้น แต่ยังใช้เพื่อนำเสนอเนื้อหาด้วย ซึ่งทำให้นักพัฒนาแอปได้รับประสบการณ์การใช้งานที่ดีขึ้นในบางด้าน แต่ประโยชน์ของนักพัฒนาแอปไม่ได้แปลว่าจะเป็นประโยชน์ต่อผู้ใช้เสมอไป
รูปแบบหนึ่งที่อาจหลบเลี่ยงการสแกนการโหลดล่วงหน้าได้คือการแสดงผลมาร์กอัปด้วย JavaScript ฝั่งไคลเอ็นต์ ดังนี้
เมื่อมีการรวมและแสดงผลเพย์โหลดมาร์กอัปทั้งหมดโดย JavaScript ในเบราว์เซอร์ ทรัพยากรในมาร์กอัปนั้นจะมองไม่เห็นโดยตัวสแกนเนอร์การโหลดล่วงหน้า ซึ่งจะทำให้การค้นพบทรัพยากรสําคัญล่าช้า ซึ่งส่งผลต่อ LCP อย่างแน่นอน ในตัวอย่างนี้ คําขอรูปภาพ LCP จะล่าช้าอย่างมากเมื่อเทียบกับประสบการณ์การใช้งานที่แสดงผลจากเซิร์ฟเวอร์ที่เทียบเท่าซึ่งไม่จําเป็นต้องใช้ JavaScript
หัวข้อนี้อาจไม่ได้เกี่ยวข้องกับประเด็นหลักของบทความนี้มากนัก แต่ผลของการเรนเดอร์มาร์กอัปในไคลเอ็นต์นั้นส่งผลได้มากกว่าการเอาชนะเครื่องมือสแกนการโหลดล่วงหน้า ตัวอย่างเช่น การใช้ JavaScript เพื่อขับเคลื่อนประสบการณ์การใช้งานที่ไม่จําเป็นต้องใช้จะเพิ่มเวลาในการประมวลผลที่ไม่จําเป็น ซึ่งอาจส่งผลต่อ Interaction to Next Paint (INP) การแสดงผลมาร์กอัปจำนวนมากในไคลเอ็นต์มีแนวโน้มที่จะสร้างงานที่มีขนาดใหญ่มากกว่าเมื่อเทียบกับมาร์กอัปจำนวนเดียวกันที่เซิร์ฟเวอร์ส่ง สาเหตุที่ทำให้เกิดปัญหานี้ (นอกเหนือจากการประมวลผลเพิ่มเติมที่ JavaScript เกี่ยวข้อง) คือเบราว์เซอร์สตรีมมาร์กอัปจากเซิร์ฟเวอร์และแบ่งการแสดงผลออกเป็นส่วนๆ ในลักษณะที่มักจะจำกัดงานระยะยาว ในทางกลับกัน มาร์กอัปที่แสดงผลฝั่งไคลเอ็นต์จะได้รับการจัดการเป็นงานแบบโมโนลิธิคงานเดียว ซึ่งอาจส่งผลต่อ INP ของหน้า
วิธีแก้ไขสำหรับสถานการณ์นี้ขึ้นอยู่กับคำตอบของคำถามนี้ มีเหตุผลใดที่ทำให้เซิร์ฟเวอร์ไม่สามารถแสดงผลมาร์กอัปของหน้าเว็บแทนที่จะแสดงผลในไคลเอ็นต์ หากคำตอบคือ "ไม่" คุณควรพิจารณาใช้การแสดงผลฝั่งเซิร์ฟเวอร์ (SSR) หรือมาร์กอัปที่สร้างขึ้นแบบคงที่ หากเป็นไปได้ เนื่องจากจะช่วยให้เครื่องมือสแกนเพื่อโหลดล่วงหน้าค้นพบและดึงข้อมูลทรัพยากรสําคัญล่วงหน้าได้
หากหน้าเว็บต้องใช้ JavaScript เพื่อแนบฟังก์ชันการทำงานกับมาร์กอัปของหน้าเว็บบางส่วน คุณยังคงใช้ SSR ได้โดยใช้ JavaScript เวอร์ชันมาตรฐานหรือการไฮเดรตเพื่อใช้ทั้ง 2 รูปแบบร่วมกัน
ช่วยให้เครื่องมือสแกนแบบโหลดล่วงหน้าช่วยเหลือคุณได้
เครื่องมือสแกนเพื่อโหลดล่วงหน้าเป็นการเพิ่มประสิทธิภาพเบราว์เซอร์ที่มีประสิทธิภาพสูงซึ่งช่วยให้หน้าเว็บโหลดเร็วขึ้นในระหว่างการเริ่มต้น การหลีกเลี่ยงรูปแบบที่ขัดขวางความสามารถของเบราว์เซอร์ในการค้นพบทรัพยากรสําคัญล่วงหน้าไม่เพียงทําให้การพัฒนาง่ายขึ้นสําหรับคุณเท่านั้น แต่ยังสร้างประสบการณ์การใช้งานที่ดีขึ้นซึ่งจะให้ผลลัพธ์ที่ดีขึ้นในเมตริกต่างๆ รวมถึง Web Vitals บางรายการ
สรุปสิ่งที่คุณควรทราบจากโพสต์นี้
- ตัวสแกนการโหลดล่วงหน้าของเบราว์เซอร์คือโปรแกรมแยกวิเคราะห์ HTML รองที่จะสแกนก่อนโปรแกรมแยกวิเคราะห์หลัก หากถูกบล็อกเพื่อค้นหาทรัพยากรที่ดึงข้อมูลได้เร็วขึ้น
- เครื่องมือสแกนเพื่อโหลดล่วงหน้าจะตรวจไม่พบทรัพยากรที่ไม่ได้อยู่ในมาร์กอัปที่เซิร์ฟเวอร์ระบุในคำขอการนําทางครั้งแรก วิธีที่อาจหลบเลี่ยงการสแกนเพื่อโหลดล่วงหน้าได้ (แต่ไม่จํากัดเพียง) มีดังนี้
- การแทรกทรัพยากรลงใน DOM ด้วย JavaScript ไม่ว่าจะเป็นสคริปต์ รูปภาพ สไตล์ชีต หรือสิ่งอื่นๆ ที่ควรอยู่ในเพย์โหลดมาร์กอัปเริ่มต้นจากเซิร์ฟเวอร์
- การโหลดแบบ Lazy Loading สำหรับรูปภาพหรือ iframe ด้านบนส่วนแรกโดยใช้โซลูชัน JavaScript
- การแสดงผลมาร์กอัปในไคลเอ็นต์ที่อาจมีการอ้างอิงถึงทรัพยากรย่อยของเอกสารโดยใช้ JavaScript
- เครื่องมือสแกนการโหลดล่วงหน้าจะสแกนเฉพาะ HTML แต่จะไม่ได้ตรวจสอบเนื้อหาของทรัพยากรอื่นๆ โดยเฉพาะ CSS ที่อาจมีการอ้างอิงถึงชิ้นงานสำคัญ รวมถึง LCP ที่เป็นไปได้
หากไม่สามารถหลีกเลี่ยงรูปแบบที่ส่งผลเสียต่อความสามารถของสแกนเนอร์การโหลดล่วงหน้าในการเร่งประสิทธิภาพการโหลด ให้พิจารณาใช้คำแนะนำทรัพยากร rel=preload
หากคุณใช้ rel=preload
ให้ทดสอบในเครื่องมือห้องทดลองเพื่อให้แน่ใจว่าเครื่องมือให้ผลลัพธ์ที่ต้องการ สุดท้าย อย่าโหลดทรัพยากรล่วงหน้ามากเกินไป เนื่องจากเมื่อคุณจัดลําดับความสําคัญให้กับทุกอย่าง ทุกอย่างก็จะไม่มีความสําคัญ
แหล่งข้อมูล
- "สคริปต์แบบไม่พร้อมกัน" ที่มีการแทรกสคริปต์ถือว่าเป็นอันตราย
- วิธีที่โปรแกรมโหลดหน้าเว็บของเบราว์เซอร์ทำให้หน้าเว็บโหลดเร็วขึ้น
- โหลดชิ้นงานสําคัญล่วงหน้าเพื่อปรับปรุงความเร็วในการโหลด
- สร้างการเชื่อมต่อเครือข่ายตั้งแต่เนิ่นๆ เพื่อปรับปรุงความเร็วของหน้าเว็บที่ผู้ใช้รับรู้
- การเพิ่มประสิทธิภาพ Largest Contentful Paint
รูปภาพหลักจาก Unsplash โดย Mohammad Rahmani