ดูว่าตัวสแกนการโหลดล่วงหน้าของเบราว์เซอร์คืออะไร ช่วยเพิ่มประสิทธิภาพได้อย่างไร และคุณจะหลีกเลี่ยงปัญหานี้ได้อย่างไร
แง่มุมหนึ่งที่ถูกมองข้ามในการเพิ่มความเร็วหน้าเว็บคือการทำความเข้าใจบางอย่างเกี่ยวกับภายในเบราว์เซอร์ เบราว์เซอร์ทำการเพิ่มประสิทธิภาพบางอย่างเพื่อปรับปรุงประสิทธิภาพในแบบที่เราที่นักพัฒนาซอฟต์แวร์ทำไม่ได้ แต่ตราบใดที่การเพิ่มประสิทธิภาพเหล่านั้นไม่ขัดขวางการเพิ่มประสิทธิภาพนั้นโดยไม่ได้ตั้งใจ
การเพิ่มประสิทธิภาพเบราว์เซอร์ภายในเครื่องหนึ่งที่ต้องทำความเข้าใจก็คือตัวสแกนการโหลดล่วงหน้าของเบราว์เซอร์ โพสต์นี้จะอธิบายวิธีการทำงานของเครื่องสแกนการโหลดล่วงหน้า และที่สำคัญกว่านั้นคือวิธีที่คุณสามารถหลีกเลี่ยงที่จะทำงานผิดพลาดได้
เครื่องสแกนการโหลดล่วงหน้าคืออะไร
ทุกเบราว์เซอร์มีโปรแกรมแยกวิเคราะห์ HTML หลักที่แปลงข้อมูลมาร์กอัปดิบและประมวลผลให้เป็นโมเดลออบเจ็กต์ ปัญหาทั้งหมดนี้จะเกิดขึ้นต่อไปจนกว่าโปรแกรมแยกวิเคราะห์จะหยุดชั่วคราวเมื่อพบทรัพยากรที่บล็อก เช่น สไตล์ชีตที่โหลดโดยมีองค์ประกอบ <link>
หรือสคริปต์ที่โหลดด้วยเอลิเมนต์ <script>
โดยไม่มีแอตทริบิวต์ async
หรือ defer
ในกรณีของไฟล์ CSS ทั้งการแยกวิเคราะห์และการแสดงผลจะถูกบล็อกเพื่อป้องกันไม่ให้เนื้อหาที่ไม่มีการจัดรูปแบบ (FOUC) สว่างวาบขึ้นมา ซึ่งก็คือการดูหน้าเว็บเวอร์ชันที่ไม่มีการจัดรูปแบบได้เป็นเวลาสั้นๆ ก่อนที่รูปแบบจะถูกนำมาใช้
นอกจากนี้ เบราว์เซอร์ยังบล็อกการแยกวิเคราะห์และการแสดงผลของหน้าเมื่อพบองค์ประกอบ <script>
ที่ไม่มีแอตทริบิวต์ defer
หรือ async
กรณีนี้เกิดจากการที่เบราว์เซอร์ไม่ทราบอย่างแน่ชัดว่าสคริปต์ใดๆ จะแก้ไข DOM ขณะที่โปรแกรมแยกวิเคราะห์ HTML หลักยังคงทำงานอยู่หรือไม่ นี่คือเหตุผลทั่วไปในการโหลด JavaScript ที่ส่วนท้ายของเอกสารเพื่อให้ผลของการแยกวิเคราะห์และการแสดงผลที่ถูกบล็อกกลายเป็นส่วนเพิ่ม
นี่เป็นเหตุผลที่ดีว่าเหตุใดเบราว์เซอร์ควรบล็อกทั้งการแยกวิเคราะห์และการแสดงผล อย่างไรก็ตาม การดำเนินการในขั้นตอนสำคัญทั้ง 2 อย่างนี้ไม่เป็นที่ต้องการ เนื่องจากไม่อาจฉุดไม่อยู่ได้ เนื่องจากอาจทำให้ค้นพบแหล่งข้อมูลสำคัญอื่นๆ ล่าช้าออกไป โชคดีที่เบราว์เซอร์จะพยายามอย่างสุดความสามารถเพื่อลดปัญหาเหล่านี้ด้วยการใช้โปรแกรมแยกวิเคราะห์ 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
การโหลดแบบ Lazy Loading ด้วย JavaScript
การโหลดแบบ Lazy Loading เป็นวิธีที่ดีในการอนุรักษ์ข้อมูล ซึ่งมักใช้กับรูปภาพ อย่างไรก็ตาม บางครั้งการโหลดแบบ Lazy Loading อาจมีผลกับรูปภาพที่ "ครึ่งหน้าบน" อย่างไม่ถูกต้อง
ซึ่งจะทำให้เกิดปัญหาที่อาจเกิดขึ้นกับการค้นพบทรัพยากรในกรณีที่เป็นกังวลเรื่องเครื่องสแกนการโหลดล่วงหน้า และอาจทำให้ต้องใช้เวลาโดยไม่จำเป็นในการค้นหาการอ้างอิงไปยังรูปภาพ ดาวน์โหลด ถอดรหัส และนำเสนอรูปภาพดังกล่าว ลองดูมาร์กอัปรูปภาพนี้เป็นตัวอย่าง
<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">
การใช้คำนำหน้า data-
เป็นรูปแบบที่พบได้ทั่วไปใน Lazy Loader ที่ทำงานด้วยระบบ JavaScript เมื่อเลื่อนรูปภาพลงในวิวพอร์ต ตัวโหลดแบบ Lazy Loading จะตัดคำนำหน้า data-
ซึ่งหมายความว่าในตัวอย่างก่อนหน้านี้ data-src
จะกลายเป็น src
การอัปเดตนี้จะแจ้งให้เบราว์เซอร์ดึงข้อมูลทรัพยากร
รูปแบบนี้จะไม่เป็นปัญหาจนกว่าจะนำไปใช้กับรูปภาพที่อยู่ในวิวพอร์ตในระหว่างการเริ่มต้นใช้งาน เนื่องจากเครื่องสแกนการโหลดล่วงหน้าไม่อ่านแอตทริบิวต์ data-src
ในลักษณะเดียวกับแอตทริบิวต์ src
(หรือ srcset
) ระบบจึงไม่พบการอ้างอิงรูปภาพก่อนหน้านี้ ที่แย่ไปกว่านั้น รูปภาพยังโหลดล่าช้าตั้งแต่หลังจากที่โปรแกรมโหลด JavaScript โหลด คอมไพล์ และเรียกใช้ด้วย
ทั้งนี้ขึ้นอยู่กับขนาดของรูปภาพซึ่งอาจขึ้นอยู่กับขนาดของวิวพอร์ต และอาจเป็นองค์ประกอบที่ต้องการสำหรับ 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 ของหน้าเว็บเป็นองค์ประกอบที่มีพร็อพเพอร์ตี้ CSS background-image
ต่อไปนี้คือสิ่งที่จะเกิดขึ้นเมื่อทรัพยากรโหลดขึ้น
ในกรณีนี้ เครื่องสแกนการโหลดล่วงหน้าไม่ได้ทำงานอย่างเต็มที่เนื่องจากไม่เกี่ยวข้อง อย่างไรก็ตาม หากตัวเลือก LCP ในหน้าเว็บมาจากพร็อพเพอร์ตี้ CSS background-image
คุณก็จะต้องโหลดรูปภาพดังกล่าวล่วงหน้าดังนี้
<!-- 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 โดยเฉพาะทรัพยากรที่เข้ารหัสฐาน 64 เราไม่แนะนำให้ทำเช่นนี้ ยกเว้นสำหรับทรัพยากรที่มีขนาดเล็กมาก แทรกในบรรทัดให้น้อยที่สุดเท่าที่จะเป็นไปได้ เนื่องจากอินไลน์มากเกินไปก็เล่นกับไฟ
การแสดงผลมาร์กอัปด้วย JavaScript ฝั่งไคลเอ็นต์
ดังนั้นจึงไม่ต้องสงสัยเลยว่า JavaScript ส่งผลต่อความเร็วหน้าเว็บอย่างแน่นอน นักพัฒนาแอปไม่เพียงแค่พึ่งพาเครื่องมือนี้ในการนำเสนอการโต้ตอบเท่านั้น แต่ยังมีแนวโน้มที่จะพึ่งพาเครื่องมือดังกล่าวเพื่อนำเสนอเนื้อหาด้วย ซึ่งอาจทำให้นักพัฒนาซอฟต์แวร์ได้รับประสบการณ์การใช้งานที่ดีขึ้นในบางด้าน แต่ประโยชน์สำหรับนักพัฒนาซอฟต์แวร์ก็ไม่ได้ก่อให้เกิดประโยชน์ต่อผู้ใช้เสมอไป
รูปแบบหนึ่งที่สามารถเอาชนะตัวสแกนการโหลดล่วงหน้าได้คือการแสดงผลมาร์กอัปด้วย JavaScript ฝั่งไคลเอ็นต์
เมื่อเพย์โหลดมาร์กอัปอยู่ในและแสดงผลทั้งหมดโดย JavaScript ในเบราว์เซอร์ เครื่องสแกนการโหลดล่วงหน้าจะมองไม่เห็นทรัพยากรใดๆ ในมาร์กอัปนั้น วิธีนี้ทำให้การค้นหาทรัพยากรที่สำคัญล่าช้า ซึ่งจะส่งผลต่อ LCP อย่างแน่นอน ในกรณีของตัวอย่างเหล่านี้ คำขอรูปภาพ LCP มีความล่าช้าอย่างมาก เมื่อเทียบกับประสบการณ์การแสดงผลที่เทียบเท่าโดยเซิร์ฟเวอร์ซึ่งไม่ต้องใช้ JavaScript
บทความนี้อาจเปลี่ยนไปเล็กน้อย แต่ผลของการแสดงผลมาร์กอัปในไคลเอ็นต์นั้นมากกว่าที่เอาชนะตัวสแกนการโหลดล่วงหน้า ประการแรก การนำ JavaScript ไปใช้เพื่อขับเคลื่อนประสบการณ์ที่ไม่ต้องอาศัยเวลาประมวลผลที่ไม่จำเป็นซึ่งอาจส่งผลกระทบต่อการโต้ตอบกับ Next Paint (INP) การแสดงมาร์กอัปจํานวนมากในไคลเอ็นต์มีแนวโน้มที่จะสร้างงานที่ใช้เวลานาน เมื่อเทียบกับมาร์กอัปที่เซิร์ฟเวอร์ส่งในจำนวนที่เท่ากัน สาเหตุนอกเหนือจากการประมวลผลพิเศษที่ JavaScript ใช้แล้ว คือเบราว์เซอร์สตรีมมาร์กอัปจากเซิร์ฟเวอร์และแยกการแสดงผลในลักษณะที่มีแนวโน้มที่จะจำกัดงานที่ใช้เวลานาน ในทางกลับกัน มาร์กอัปที่แสดงผลโดยไคลเอ็นต์จะมีการจัดการเป็นงานเดี่ยวแบบโมโนลิธ ซึ่งอาจส่งผลต่อ INP ของหน้าเว็บ
การชดเชยในสถานการณ์นี้จะขึ้นอยู่กับคำตอบสำหรับคำถามนี้: มีสาเหตุใดหรือไม่ที่เซิร์ฟเวอร์ไม่สามารถให้มาร์กอัปของหน้าเว็บของคุณ แทนที่จะแสดงผลในไคลเอ็นต์ หากคำตอบคือ "ไม่" ควรพิจารณาการแสดงผลฝั่งเซิร์ฟเวอร์ (SSR) หรือมาร์กอัปที่สร้างขึ้นแบบคงที่หากทำได้ เนื่องจากจะช่วยให้เครื่องสแกนการโหลดล่วงหน้าค้นพบและดึงทรัพยากรที่สำคัญล่วงหน้าได้ตามความเหมาะสม
หากหน้าเว็บต้องการให้ JavaScript แนบฟังก์ชันการทำงานกับบางส่วนของมาร์กอัปหน้าเว็บ คุณก็ยังดำเนินการดังกล่าวได้โดยใช้ SSR ไม่ว่าจะด้วย vanilla JavaScript หรือ hydration เพื่อให้ได้ประโยชน์สูงสุดจากทั้ง 2 องค์ประกอบ
ช่วยให้เครื่องสแกนการโหลดล่วงหน้าช่วยคุณ
ตัวสแกนการโหลดล่วงหน้าเป็นการเพิ่มประสิทธิภาพเบราว์เซอร์ที่มีประสิทธิภาพสูง ซึ่งช่วยให้หน้าเว็บโหลดได้เร็วขึ้นในช่วงเริ่มต้น การหลีกเลี่ยงรูปแบบที่ทำลายความสามารถในการค้นพบทรัพยากรสำคัญล่วงหน้าไม่เพียงแค่ทำให้การพัฒนาง่ายขึ้นสำหรับคุณ แต่ยังเป็นการสร้างประสบการณ์ของผู้ใช้ที่ดียิ่งขึ้นซึ่งจะให้ผลลัพธ์ที่ดีกว่าในเมตริกจำนวนมาก ซึ่งรวมถึง Web Vitals บางอย่างด้วย
กล่าวโดยสรุปคือ คุณต้องนำสิ่งต่อไปนี้ออกจากโพสต์นี้
- ตัวสแกนการโหลดล่วงหน้าของเบราว์เซอร์เป็นโปรแกรมแยกวิเคราะห์ HTML รองที่สแกนก่อนโปรแกรมหลัก หากโปรแกรมถูกบล็อกไม่ให้ค้นพบทรัพยากรที่สามารถดึงข้อมูลได้เร็วกว่าตามโอกาส
- ตัวสแกนการโหลดล่วงหน้าจะไม่พบทรัพยากรที่ไม่ได้อยู่ในมาร์กอัปซึ่งเซิร์ฟเวอร์ในคำขอการนำทางเริ่มต้น วิธีที่เครื่องสแกนการโหลดล่วงหน้าอาจเอาชนะได้มีดังนี้ (แต่ไม่จำกัดเพียง)
- การแทรกทรัพยากรลงใน DOM ด้วย JavaScript ไม่ว่าจะเป็นสคริปต์ รูปภาพ สไตล์ชีต หรืออะไรก็ตามที่ควรปรับปรุงในเพย์โหลดมาร์กอัปเริ่มต้นจากเซิร์ฟเวอร์
- การโหลดรูปภาพครึ่งหน้าบนหรือ iframe แบบ Lazy Loading ด้วยโซลูชัน JavaScript
- แสดงผลมาร์กอัปบนไคลเอ็นต์ที่อาจมีการอ้างอิงทรัพยากรย่อยของเอกสารโดยใช้ JavaScript
- ตัวสแกนการโหลดล่วงหน้าจะสแกนเฉพาะ HTML เท่านั้น แต่จะไม่ตรวจสอบเนื้อหาของทรัพยากรอื่นๆ โดยเฉพาะ CSS ที่อาจมีการอ้างอิงถึงเนื้อหาที่สำคัญ รวมถึงตัวเลือก LCP
หากคุณไม่สามารถหลีกเลี่ยงรูปแบบที่ส่งผลเสียต่อความสามารถของเครื่องสแกนการโหลดล่วงหน้าเพื่อเร่งประสิทธิภาพการโหลดได้ ไม่ว่าจะด้วยเหตุใด โปรดอ่านคำแนะนำเกี่ยวกับแหล่งข้อมูล rel=preload
หากคุณใช้ rel=preload
ให้ทดสอบในเครื่องมือห้องทดลองเพื่อให้แน่ใจว่าเครื่องมือจะให้ผลตามที่คุณต้องการ สุดท้ายนี้ อย่าโหลดทรัพยากรล่วงหน้ามากเกินไป เพราะเมื่อคุณจัดลำดับความสำคัญทุกอย่างจะไม่มีอะไรเกิดขึ้น
แหล่งข้อมูล
- "สคริปต์แบบโหลดพร้อมกันได้" ที่มีการแทรกสคริปต์ถือว่าเป็นอันตราย
- วิธีที่ตัวโหลดล่วงหน้าของเบราว์เซอร์ทำให้หน้าเว็บโหลดเร็วขึ้น
- โหลดเนื้อหาที่สำคัญล่วงหน้าเพื่อปรับปรุงความเร็วในการโหลด
- สร้างการเชื่อมต่อเครือข่ายตั้งแต่เนิ่นๆ เพื่อเพิ่มความเร็วหน้าเว็บที่รับรู้
- การเพิ่มประสิทธิภาพ Largest Contentful Paint
รูปภาพหลักจาก Unsplash โดย Mohammad Rahmani