PageSpeed Insights
บทความนี้อธิบายว่าเบราว์เซอร์
คำตอบ สั้น ๆ
render-blocking resources คือไฟล์ที่เบราว์เซอร์ต้องดึงมา และบางครั้งต้องรันด้วย ก่อนจะวาดพิกเซลแรกของหน้าเว็บ ผู้ต้องสงสัยประจำคือ
- สไตล์ชีตในส่วน head ของหน้า เบราว์เซอร์จะไม่วาดอะไร จนกว่าจะได้ CSS ที่ต้องใช้
- สคริปต์ที่ไม่มี
deferหรือasyncมันหยุดไม่ให้เบราว์เซอร์อ่าน HTML ต่อ จนกว่าจะรันเสร็จ - เว็บฟอนต์ ไม่ได้บล็อกทั้งหน้า แต่ซ่อน
ข้อความ ได้
วิธีแก้คือ เลื่อนสคริปต์ที่
เบราว์เซอร์สร้าง หน้าเว็บอย่างไร และรอตรงไหน
CSS บล็อกการแสดงผลครั้งแรกโดยตั้งใจ
เบราว์เซอร์อ่าน HTML เพื่อ
ถ้าวาดเร็วกว่านั้น จะเห็นเนื้อหาที่ยังไม่มีสไตล์แวบขึ้นมา เบราว์เซอร์จึงรอสไตล์ชีตทุกไฟล์ใน head ที่ใช้กับ
สคริปต์แบบ synchronous หยุดการอ่านไปเลย
แท็ก <script src="…"> แบบดั้งเดิมที่ไม่มีแอตทริบิวต์ จะบล็อก parser เบราว์เซอร์หยุด
ยังมีการรอที่
ฟอนต์ถ่วงข้อความ ไม่ใช่ทั้งหน้า
เบราว์เซอร์จะขอไฟล์ฟอนต์ ก็ต่อเมื่อรู้ว่ามี
สิ่งที่ preload scanner มองไม่เห็น
เบราว์เซอร์บรรเทาปัญหานี้ด้วย preload scanner ซึ่งกวาดอ่าน HTML @import รูป
หาไฟล์ที่บล็อกการเรนเดอร์ บนเว็บไซต์ ของคุณ
PageSpeed Insights และ Lighthouse ตั้งแต่ Lighthouse 13 ไฟล์เหล่านี้อยู่ในหัวข้อ “Render-blocking requests” ส่วนรายงานรุ่นเก่าแสดงไว้ใต้ “กำจัดทรัพยากรที่บล็อกการแสดงผล” บทความ วิธีอ่านรายงาน PageSpeed Insights อธิบายว่าควรเชื่อตัวเลขเวลาที่ประหยัดได้แค่ไหน และทำไม “element render delay” ที่สูงใน
Chrome DevTools แผง Performance บันทึกการโหลด และแจ้งคำขอที่บล็อกการ
ตรวจผ่าน console ใน Chrome หรือ Edge performance.getEntriesByType('resource').filter(r => r.renderBlockingStatus === 'blocking') จะแสดงรายการไฟล์ที่ถูกนับว่าบล็อก ณ เวลาที่เขียน รองรับเฉพาะเบราว์เซอร์ที่
ทดสอบตอนออกจากระบบแล้ว เพราะเซสชัน WordPress ที่ล็อกอินอยู่ มักข้ามแคชของหน้า และโหลดไฟล์ของแถบ
แก้ JavaScript: defer, async หรือไม่ใช้ทั้งคู่
สคริปต์
| วิธีโหลด | บล็อกการอ่าน HTML ไหม? | รันเมื่อไร | รักษาลำดับไหม? | ใช้กับอะไร |
|---|---|---|---|---|
| ไม่มีแอตทริบิวต์ | ใช่ | ทันที ตรงตำแหน่งที่มันอยู่ | ใช่ | สคริปต์ส่วนน้อยที่ต้องรันก่อน |
defer |
ไม่ | หลังอ่าน HTML เสร็จ | ใช่ | สคริปต์ของคุณเอง |
async |
เฉพาะตอนที่รัน | ทันทีที่ดาวน์โหลดเสร็จ | ไม่ | สคริปต์อิสระ เช่น analytics |
type="module" |
ไม่ | เหมือน defer เว้นแต่จะใส่ async |
ใช่ | โค้ดสมัยใหม่ที่ bundle แล้ว |
ให้ defer ใน head เป็นค่าasync ไว้สำหรับสคริปต์ที่ไม่พึ่งอะไร และไม่มีอะไรพึ่งมัน โค้ดที่ถูก defer ยังรันบน main thread ซึ่งงานที่ยาว ๆ จะทำให้การแตะ
เมื่อการ defer สคริปต์ทำให้อะไรพัง
โค้ดบางส่วนพึ่งจังหวะเวลาแบบเดิม
- inline script ที่เรียกไลบรารี
jQuery(function () { … })แบบ inline จะรันทันที เมื่อ jQuery ถูก defer แล้ว console จะแจ้งjQuery is not definedการใส่deferให้ inline script ไม่มีผลอะไร - ลำดับ
ภายใต้ asyncสคริปต์ของปลั๊กอินที่รันก่อนไลบรารีจะมาถึง จะล้มเหลว เป็นบางครั้ง ซึ่งทำให้จำลองปัญหาซ้ำได้ยาก DOMContentLoadedในสคริปต์แบบ async สคริปต์แบบ async อาจรันหลังอีเวนต์นั้นเกิดไปแล้ว โค้ดที่รออีเวนต์นั้นจึงไม่เคยรันdocument.writeMDN ระบุว่าเบราว์เซอร์ไม่สนใจคำสั่ง นี้ ในสคริปต์แบบ defer และ async- สคริปต์ที่บล็อกโดยตั้งใจ เช่น ตัวจัดการความยินยอม (consent manager) โค้ดกันหน้า
กระพริบ สำหรับการทดสอบ A/B และสคริปต์จิ๋วที่ตั้งธีมสีก่อนวาดหน้า ให้สคริปต์เหล่านี้เล็ก อยู่ลำดับแรก และมีให้น้อยที่สุด
ตั้งแต่เวอร์ชัน 6.3 WordPress ให้ธีมและปลั๊กอินdefer หรือ async ได้ และจะกลับไปโหลดแบบปกติ ในกรณีที่การ defer จะทำลายลำดับการพึ่งพา วิธีนี้ปลอดภัยกว่าการใช้ปลั๊กอินบังคับ defer กับทุกไฟล์
ระวังการ “หน่วงไว้จนกว่าจะมีการโต้ตอบ”
ปลั๊กอินเพิ่มความเร็วบางตัว กักสคริปต์ไว้จนกว่า
แก้ CSS: critical CSS และ CSS ที่ไม่ได้ใช้
CSS บางส่วนต้องบล็อก จึงควรทำส่วนนั้นให้เล็ก
ฝัง critical CSS ไว้ในหน้า
critical CSS คือ CSS <style> ใน head เพื่อให้มาถึงพร้อม HTML
ข้อ
ถ้า CSS ทั้งหมดของ
โหลดส่วนที่เหลือแบบไม่บล็อก
rel="preload" หรือ media="print" แล้วเปิดใช้ด้วยตัวจัดการ onload และเพิ่ม <noscript> สำรองไว้ Content Security Policy ที่
สไตล์ชีตที่แอตทริบิวต์ media ไม่ตรงกับอุปกรณ์ ยังถูกดาวน์โหลดอยู่ด้วยลำดับความสำคัญที่ต่ำกว่า แต่ไม่บล็อกการmedia จึงเป็นวิธีที่ได้ผล และมีความเสี่ยงต่ำ และ@import ภายในสไตล์ชีต เพราะไฟล์ที่ถูก import จะเริ่มดาวน์โหลดไม่ได้ จนกว่าไฟล์ที่ import มันจะมาถึง
ลด CSS ที่ไม่ได้ใช้
ธีมและปลั๊กอินมักโหลดสไตล์ชีตทุกไฟล์ในทุกหน้า สไตล์ของ
- เลิกโหลดในที่ที่ไม่ต้องใช้ โหลดสไตล์ของปลั๊กอินและคอมโพเนนต์ เฉพาะในเทมเพลตที่ใช้มัน นี่คือวิธีแก้ที่ปลอดภัยที่สุด และมักได้ผลมากที่สุด
- ตัดออกด้วย
เครื่องมือ ฟีเจอร์ “ลบ CSS ที่ไม่ได้ใช้” แบบอัตโนมัติ จะลบ selector ที่หาไม่เจอในหน้า รวมถึงคลาสที่ JavaScript เพิ่มเข้ามาทีหลัง จึงต้องมีรายการยกเว้น (safelist) และทดสอบทุกสถานะ
โหลดเว็บฟอนต์ให้ดี
บทความ
- โหลดไฟล์ให้น้อยลง แต่ละตระกูล
น้ำหนัก และสไตล์ มักเป็นไฟล์แยกกัน variable font ไฟล์เดียวแทนหลายน้ำหนัก ได้ - โฮสต์ WOFF2 เองเมื่อทำได้ บริการฟอนต์ภายนอกมักเพิ่มสไตล์ชีตของ
ตัวเอง อีกไฟล์ นั่นคือคำขอที่บล็อกการเรนเดอร์ เพิ่มอีกหนึ่ง ไปยังอีกเซิร์ฟเวอร์ ก่อนจะถึงไฟล์ฟอนต์จริง - แยกชุดอักขระตามระบบการเขียน บน
เว็บไซต์ หลายภาษา ให้แบ่งฟอนต์เป็นชุดย่อยที่ประกาศด้วยunicode-rangeเบราว์เซอร์จะดาวน์โหลดเฉพาะชุดย่อย ที่มีอักขระซึ่งหน้านั้นใช้จริง - preload เฉพาะสิ่งที่
หน้าจอ แรกต้องใช้ ด้วย<link rel="preload" href="/fonts/brand.woff2" as="font" type="font/woff2" crossorigin>แอตทริบิวต์crossoriginจำเป็นแม้บนโดเมนของคุณเอง ไม่อย่างนั้นฟอนต์จะถูกดาวน์โหลดสองครั้ง ถ้า preload มากเกินไป รูป hero จะช้าลง - เลือกค่า
font-display
ค่า font-display |
ถ้าฟอนต์มาช้า | เหมาะกับ | |
|---|---|---|---|
block |
ซ่อน |
สลับมาใช้ | ฟอนต์ไอคอน (ไอคอน SVG ดีกว่า) |
swap |
ใช้ฟอนต์สำรองทันที | สลับมาใช้ | หัวข้อและเนื้อหา |
fallback |
ใช้ฟอนต์สำรองหลังรอสั้น ๆ | ใช้เฉพาะเมื่อมาถึงภายในไม่กี่วินาที | สมดุล |
optional |
ใช้ฟอนต์สำรองหลังรอสั้น ๆ | ไม่สลับมาใช้ มักถูกแคชไว้สำหรับหน้า |
ความนิ่งมาก่อนทุกอย่าง |
เมื่อใช้ font-display: swap ให้เลือกฟอนต์สำรองที่สัดส่วนsize-adjust เพื่อให้
ทำไมเว็บไซต์ ที่ใช้ page builder ต้องระวังเป็นพิเศษ
หน้าที่
การ
ถ้า builder ของคุณโหลดไฟล์เฉพาะในที่ที่ใช้ได้ ให้
บทความ วิธีทำให้
ลำดับการทำงานที่ปลอดภัย
- วัด LCP จากข้อมูล
ภาคสนาม ถ้ามี พร้อมค่าฐานจากแล็บที่รันสามครั้ง - ทำรายการไฟล์ที่บล็อก และดูว่าไฟล์ไหนโหลดโดยธีม ปลั๊กอิน หรือบริการภายนอก
- ลบก่อน
ปรับแต่ง ไฟล์จากเครื่องมือ ที่ไม่มีใครใช้แล้ว คือวิธีแก้ที่ถูกที่สุด - defer สคริปต์ของคุณเอง และแก้การพึ่งพาแบบ inline
- ตัดและแยก CSS แล้วฝัง critical CSS ในเทมเพลตสำคัญ
- จัดการฟอนต์ ไฟล์น้อยลง preload หนึ่งหรือสองไฟล์ และเลือก
font-displayอย่างตั้งใจ - ทดสอบใหม่ แล้วเฝ้าดูข้อมูล
ภาคสนาม ซึ่งครอบคลุมช่วง 28 วันล่าสุด จึงควรเผื่อเวลาราวสี่สัปดาห์
ขั้นต่อไป
render-blocking resources แทบไม่เคยเป็นไฟล์แย่ ๆ ไฟล์เดียว มันคือผลรวมของธีม ปลั๊กอิน ฟอนต์ และสคริปต์ ที่เพิ่มเข้ามาตลอดหลายปี และหลายตัวคือการ
เมื่อไฟล์ที่บล็อกสาวกลับไปถึงตัวธีมหรือ page builder เอง การ