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