ในโมดูลก่อนหน้านี้ ทฤษฎีบางทฤษฎีเบื้องหลังเส้นทางการแสดงผลวิกฤติ และวิธีที่ทรัพยากรที่บล็อกการแสดงผลและการบล็อกโปรแกรมแยกวิเคราะห์สามารถทำให้ การแสดงผลครั้งแรกของหน้าเว็บ ตอนนี้คุณเข้าใจทฤษฎีเบื้องหลังบางส่วนแล้ว ตอนนี้คุณก็พร้อมแล้วที่จะเรียนรู้เทคนิคบางประการในการเพิ่มประสิทธิภาพ เส้นทางการแสดงผล
เมื่อหน้าเว็บโหลดขึ้นมา จะมีการอ้างอิงทรัพยากรจำนวนมากภายใน HTML ที่มีองค์ประกอบ หน้าเว็บที่มีรูปลักษณ์และเลย์เอาต์ผ่าน CSS รวมถึงการโต้ตอบ ผ่าน JavaScript ในโมดูลนี้ เราจะพูดถึงแนวคิดสำคัญจำนวนหนึ่งที่เกี่ยวข้องกับ เรากล่าวถึงทรัพยากรเหล่านี้และผลกระทบต่อเวลาที่ใช้ในการโหลดหน้าเว็บ
แสดงผลการบล็อก
ตามที่ได้กล่าวไว้ในโมดูลก่อนหน้า CSS เป็นทรัพยากรrender-blocking เนื่องจากเบราว์เซอร์จะบล็อกเบราว์เซอร์ไม่ให้แสดงผลเนื้อหาใดๆ จนถึง CSS Object Model (CSSOM) สร้างขึ้น เบราว์เซอร์จะบล็อกการแสดงผลเพื่อป้องกัน Flash เนื้อหาแบบไม่มีสไตล์ (FOUC) ซึ่งไม่เป็นที่ต้องการในแง่ประสบการณ์ของผู้ใช้
ในวิดีโอก่อนหน้านี้ มี FOUC สั้นๆ ที่คุณสามารถดูหน้าเว็บได้โดย สไตล์ใดก็ได้ หลังจากนั้น สไตล์ทั้งหมดจะถูกนำมาใช้เมื่อ CSS ของหน้าเว็บ เสร็จสิ้นการโหลดจากเครือข่าย และหน้าเวอร์ชันที่ไม่มีการจัดรูปแบบ แทนด้วยรูปแบบที่มีการจัดรูปแบบทันที
โดยทั่วไปแล้ว FOUC เป็นสิ่งที่คุณ ปกติแล้ว ไม่ได้เห็น แต่แนวคิด เป็นสิ่งสำคัญที่ต้องทำความเข้าใจเพื่อให้คุณทราบว่าทำไมเบราว์เซอร์จึงบล็อกการแสดงผล ของหน้าเว็บจนกว่าจะดาวน์โหลดและใช้ CSS กับหน้าเว็บนั้น แสดงผลการบล็อก อาจไม่ใช่สิ่งที่ไม่พึงประสงค์เสมอไป แต่คุณต้องการลดระยะเวลาการใช้งาน การเพิ่มประสิทธิภาพ CSS อยู่เสมอ
การบล็อกโปรแกรมแยกวิเคราะห์
ทรัพยากรในการบล็อกโปรแกรมแยกวิเคราะห์จะขัดจังหวะโปรแกรมแยกวิเคราะห์ HTML เช่น <script>
ที่ไม่มีแอตทริบิวต์ async
หรือ defer
เมื่อโปรแกรมแยกวิเคราะห์พบ
<script>
เบราว์เซอร์จะต้องประเมินและเรียกใช้สคริปต์ก่อน
ดำเนินการแยกวิเคราะห์ HTML ที่เหลือต่อ นี่คือการออกแบบ เนื่องจากเป็นสคริปต์
แก้ไขหรือเข้าถึง DOM ระหว่างที่ยังสร้าง DOM อยู่
<!-- This is a parser-blocking script: -->
<script src="/script.js"></script>
เมื่อใช้ไฟล์ JavaScript ภายนอก (ไม่มี async
หรือ defer
) โปรแกรมแยกวิเคราะห์จะ
ถูกบล็อกตั้งแต่ตอนที่ค้นพบไฟล์จนกว่าจะดาวน์โหลด แยกวิเคราะห์ และ
ดำเนินการแล้ว เมื่อใช้ JavaScript ในบรรทัด โปรแกรมแยกวิเคราะห์จะถูกบล็อกในทำนองเดียวกันจนถึง
สคริปต์ในหน้าจะถูกแยกวิเคราะห์และดำเนินการ
เครื่องสแกนการโหลดล่วงหน้า
ตัวสแกนการโหลดล่วงหน้าเป็นการเพิ่มประสิทธิภาพเบราว์เซอร์ในรูปแบบ HTML รอง
โปรแกรมแยกวิเคราะห์ที่สแกนการตอบสนอง HTML แบบ Raw เพื่อค้นหาและดึงข้อมูลแบบคาดเดา
ก่อนที่โปรแกรมแยกวิเคราะห์ HTML หลักจะค้นพบทรัพยากรดังกล่าว สำหรับ
ตัวอย่างเช่น ตัวสแกนการโหลดล่วงหน้าจะช่วยให้เบราว์เซอร์สามารถเริ่มการดาวน์โหลด
ทรัพยากรที่ระบุในองค์ประกอบ <img>
แม้ว่าโปรแกรมแยกวิเคราะห์ HTML จะถูกบล็อกก็ตาม
ขณะดึงข้อมูลและประมวลผลทรัพยากร เช่น CSS และ JavaScript
หากต้องการใช้ประโยชน์จากเครื่องสแกนการโหลดล่วงหน้า ควรมีทรัพยากรที่สำคัญรวมอยู่ด้วย ในมาร์กอัป HTML ที่ส่งโดยเซิร์ฟเวอร์ รูปแบบการโหลดทรัพยากรต่อไปนี้ ไม่พบโดยตัวสแกนการโหลดล่วงหน้า:
- รูปภาพที่โหลดโดย CSS โดยใช้พร็อพเพอร์ตี้
background-image
รูปภาพเหล่านี้ การอ้างอิงอยู่ใน CSS และไม่สามารถค้นพบด้วยตัวสแกนการโหลดล่วงหน้า - สคริปต์ที่โหลดแบบไดนามิกในรูปแบบของมาร์กอัปองค์ประกอบ
<script>
ที่แทรก ลงใน DOM โดยใช้ JavaScript หรือโมดูลที่โหลดโดยใช้import()
แบบไดนามิก - HTML ที่แสดงผลในไคลเอ็นต์โดยใช้ JavaScript มาร์กอัปดังกล่าวอยู่ภายใน สตริงในทรัพยากร JavaScript และไม่สามารถค้นพบได้ด้วยการโหลดล่วงหน้า สแกนเนอร์
- การประกาศของ CSS
@import
รูปแบบการโหลดทรัพยากรเหล่านี้เป็นทรัพยากรที่ค้นพบล่าช้าทั้งหมด ดังนั้น
ไม่ได้รับประโยชน์จากเครื่องสแกนการโหลดล่วงหน้า โปรดหลีกเลี่ยงหากทำได้ ถ้า
การหลีกเลี่ยงรูปแบบดังกล่าวไม่ได้อย่างไรก็ตาม คุณอาจสามารถใช้
คำแนะนำ preload
รายการเพื่อหลีกเลี่ยงความล่าช้าในการค้นหาทรัพยากร
CSS
CSS จะกำหนดงานนำเสนอและเลย์เอาต์ของหน้าเว็บ ตามที่อธิบายไว้ก่อนหน้านี้ CSS เป็นทรัพยากรที่บล็อกการแสดงผล ดังนั้นการเพิ่มประสิทธิภาพ CSS ผลกระทบต่อเวลาในการโหลดหน้าเว็บโดยรวม
การทำให้มีขนาดเล็กลง
การลดขนาดไฟล์ CSS จะลดขนาดไฟล์ของทรัพยากร CSS ซึ่งทำให้ ดาวน์โหลดได้เร็วขึ้น โดยทั่วไปแล้ว การดำเนินการดังกล่าวเกิดจากการนำเนื้อหาออกจาก ไฟล์ CSS ที่มา เช่น การเว้นวรรคและอักขระที่มองไม่เห็นอื่นๆ และเอาต์พุต ผลลัพธ์ไปยังไฟล์ที่เพิ่มประสิทธิภาพใหม่:
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
ในรูปแบบพื้นฐานที่สุด การลดรูป CSS คือการเพิ่มประสิทธิภาพที่มีประสิทธิภาพ ปรับปรุง FCP ของเว็บไซต์ และแม้กระทั่ง LCP ในบางกรณี เครื่องมือ เช่น bundlers สามารถดำเนินการเพิ่มประสิทธิภาพนี้ให้คุณโดยอัตโนมัติในเวอร์ชันที่ใช้งานจริง งานสร้าง
นำ CSS ที่ไม่ได้ใช้ออก
ก่อนแสดงผลเนื้อหาใดๆ เบราว์เซอร์จำเป็นต้องดาวน์โหลดและแยกวิเคราะห์ทั้งหมด ของสไตล์ชีต เวลาที่ใช้ในการแยกวิเคราะห์จะรวมถึงรูปแบบที่ ไม่ได้ใช้ในหน้าปัจจุบัน หากคุณใช้ Bundler ที่รวม CSS ทั้งหมด มาไว้ในไฟล์เดียว ผู้ใช้ของคุณมีแนวโน้มที่จะดาวน์โหลด CSS มากกว่า ที่จำเป็นต่อการแสดงผลหน้าปัจจุบัน
หากต้องการค้นหา CSS ที่ไม่ได้ใช้สำหรับหน้าปัจจุบัน ให้ใช้เครื่องมือการครอบคลุมใน Chrome เครื่องมือสำหรับนักพัฒนาเว็บ
การนำ CSS ที่ไม่ได้ใช้ออกจะมีผล 2 เท่า นอกเหนือจากการลดการดาวน์โหลด เท่ากับเป็นการเพิ่มประสิทธิภาพการสร้างแผนผังการแสดงผล เนื่องจากเบราว์เซอร์ต้องการ ประมวลผลกฎ CSS น้อยลง
หลีกเลี่ยงการประกาศ CSS @import
แม้ว่าจะดูสะดวก แต่ก็ควรหลีกเลี่ยงการประกาศ @import
ใน CSS ดังนี้
/* Don't do this: */
@import url('style.css');
เช่นเดียวกับวิธีการทำงานขององค์ประกอบ <link>
ใน HTML การประกาศ @import
ใน CSS ช่วยให้คุณนำเข้าทรัพยากร CSS ภายนอกจากภายในสไตล์ชีตได้
ความแตกต่างสำคัญระหว่าง 2 วิธีนี้คือองค์ประกอบ <link>
ของ HTML
เป็นส่วนหนึ่งของการตอบสนอง HTML ดังนั้นจึงค้นพบเร็วกว่า CSS มาก
ดาวน์โหลดไฟล์โดยการประกาศ @import
สาเหตุก็คือเพื่อให้การประกาศ @import
ไฟล์ CSS ที่มีไฟล์นั้นจะต้องดาวน์โหลดก่อน ช่วงเวลานี้
จะทำให้เกิดสิ่งที่เรียกว่าห่วงโซ่คำขอ ซึ่งในกรณีของ CSS ความล่าช้า
ใช้เวลานานเท่าใดกว่าที่หน้าเว็บจะแสดงผลในตอนแรก ข้อเสียอีกประการคือ
ไม่พบสไตล์ชีตที่โหลดโดยใช้การประกาศ @import
โดย
เครื่องสแกนโหลดล่วงหน้า ทรัพยากรที่บล็อกการแสดงผลจึงถูกค้นพบล่าช้า
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
ในกรณีส่วนใหญ่ คุณสามารถแทนที่ @import
ด้วยการใช้แท็ก
องค์ประกอบ <link rel="stylesheet">
องค์ประกอบ <link>
ทำให้สามารถใส่สไตล์ชีต
ดาวน์โหลดพร้อมกันและลดเวลาในการโหลดโดยรวม แทนที่จะเป็น @import
ประกาศ ซึ่งจะดาวน์โหลดสไตล์ชีตติดต่อกัน
CSS ที่สำคัญในหน้า
เวลาที่ใช้ในการดาวน์โหลดไฟล์ CSS อาจเพิ่ม FCP ของหน้าเว็บได้ แบบอินไลน์
รูปแบบวิกฤติในเอกสาร <head>
จะลบคำขอเครือข่ายสำหรับ
ทรัพยากร CSS และเมื่อทำอย่างถูกต้อง จะสามารถปรับปรุงเวลาในการโหลดเริ่มต้นเมื่อ
ไม่ได้เตรียมแคชเบราว์เซอร์ของผู้ใช้ไว้ โหลด CSS ที่เหลือได้
แบบไม่พร้อมกัน หรือต่อท้ายที่ส่วนท้ายขององค์ประกอบ <body>
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
แต่ผลเสียคือ การใส่ CSS จำนวนมากจะทำให้เพิ่มไบต์ให้กับ CSS เริ่มต้นมากขึ้น การตอบกลับ HTML เนื่องจากทรัพยากร HTML มักจะไม่สามารถแคชได้นานมาก หรือที่ หมายความว่า CSS ในบรรทัดจะไม่ถูกแคชสำหรับหน้าถัดไปที่อาจ ใช้ CSS เดียวกันในสไตล์ชีตภายนอก ทดสอบและวัดผลของหน้าเว็บ เพื่อให้แน่ใจว่าจะคุ้มค่ากับความพยายาม
การสาธิต CSS
JavaScript
JavaScript กระตุ้นการโต้ตอบส่วนใหญ่บนเว็บ แต่ก็มีค่าใช้จ่าย การจัดส่ง JavaScript มากเกินไปอาจทำให้หน้าเว็บตอบสนองได้ช้าระหว่างที่อยู่ในหน้าเว็บ โหลด และอาจทำให้เกิดปัญหาการตอบสนองซึ่งทำให้การโต้ตอบช้าลง ซึ่งอาจทำให้ผู้ใช้รู้สึกไม่พอใจ
JavaScript ที่บล็อกการแสดงผล
ขณะโหลดองค์ประกอบ <script>
โดยไม่มีแอตทริบิวต์ defer
หรือ async
ค่า
เบราว์เซอร์จะบล็อกการแยกวิเคราะห์และการแสดงผลจนกว่าจะดาวน์โหลด แยกวิเคราะห์ และ
ดำเนินการแล้ว ในทำนองเดียวกัน สคริปต์ในหน้าจะบล็อกโปรแกรมแยกวิเคราะห์จนกว่าจะมีการแยกวิเคราะห์สคริปต์
และดำเนินการแล้ว
async
พบกับ defer
async
และ defer
อนุญาตให้สคริปต์ภายนอกโหลดโดยไม่ต้องบล็อก HTML
โปรแกรมแยกวิเคราะห์ในขณะที่สคริปต์ (รวมถึงสคริปต์ในหน้า) ที่มี type="module"
เลื่อนออกไปโดยอัตโนมัติ อย่างไรก็ตาม async
และ defer
มีความแตกต่างบางอย่างที่
การทำความเข้าใจ
ระบบจะแยกวิเคราะห์สคริปต์ที่โหลดด้วย async
และดำเนินการทันทีเมื่อดาวน์โหลด
ขณะที่สคริปต์ที่โหลดด้วย defer
จะทำงานเมื่อแยกวิเคราะห์เอกสาร HTML
เสร็จสิ้นแล้ว ซึ่งจะเกิดขึ้นพร้อมกับเหตุการณ์ DOMContentLoaded
ของเบราว์เซอร์
นอกจากนี้ สคริปต์ async
รายการอาจทำงานผิดปกติ ขณะที่สคริปต์ defer
รายการ
จะได้รับการดำเนินการตามลำดับที่ปรากฏในมาร์กอัป
การแสดงผลฝั่งไคลเอ็นต์
โดยทั่วไปแล้ว คุณควรหลีกเลี่ยงการใช้ JavaScript ในการแสดงผลเนื้อหาที่สำคัญหรือ องค์ประกอบ LCP ของหน้าเว็บ วิธีนี้เรียกว่าการแสดงผลฝั่งไคลเอ็นต์ และเป็นเทคนิค ใช้อย่างกว้างขวางในแอปพลิเคชันหน้าเว็บเดียว (SPA)
มาร์กอัปที่แสดงผลโดย JavaScript หยุดเครื่องสแกนการโหลดล่วงหน้าในฐานะทรัพยากร ที่อยู่ในมาร์กอัปที่แสดงผลโดยไคลเอ็นต์จะค้นพบไม่ได้ด้วย ช่วงเวลานี้ อาจทำให้ดาวน์โหลดทรัพยากรสำคัญ เช่น รูปภาพ LCP ได้ล่าช้า เบราว์เซอร์ เริ่มดาวน์โหลดรูปภาพ LCP หลังจากเรียกใช้สคริปต์และเพิ่มเท่านั้น ลงใน DOM ในทางกลับกัน สคริปต์จะทำงานได้ก็ต่อเมื่อ ถูกค้นพบ ดาวน์โหลด และแยกวิเคราะห์ ซึ่งเราเรียกว่าคำขอที่สำคัญ เชน และควรหลีกเลี่ยง
นอกจากนี้ การแสดงผลมาร์กอัปโดยใช้ JavaScript มีแนวโน้มที่จะสร้าง งานที่ใช้เวลานานกว่ามาร์กอัปที่ดาวน์โหลดจากเซิร์ฟเวอร์เพื่อตอบสนองต่อการนำทาง อีกครั้ง การใช้ การแสดงผล HTML ฝั่งไคลเอ็นต์อย่างครอบคลุมอาจส่งผลกระทบในเชิงลบ เวลาในการตอบสนองของการโต้ตอบ โดยเฉพาะอย่างยิ่งในกรณีที่ DOM ของหน้าเว็บ ใหญ่มาก ซึ่งทำให้แสดงผลจำนวนมากเมื่อ JavaScript แก้ไข DOM
การทำให้มีขนาดเล็กลง
การลดขนาด JavaScript จะลดขนาดไฟล์ของทรัพยากรสคริปต์ เช่นเดียวกับ CSS ซึ่งอาจทำให้ดาวน์โหลดได้เร็วขึ้น ทำให้เบราว์เซอร์ ในการแยกวิเคราะห์และคอมไพล์ JavaScript ได้รวดเร็วยิ่งขึ้น
นอกจากนี้ การลดขนาด JavaScript ยังก้าวไปมากกว่าการลดขนาด เนื้อหาอื่นๆ เช่น CSS เมื่อลดขนาด JavaScript จะทำให้ JavaScript ไม่เพียงถูกตัดออก ของสิ่งต่างๆ เช่น การเว้นวรรค แท็บและความคิดเห็น แต่ใช้สัญลักษณ์ในแหล่งที่มา JavaScript ถูกตัดให้สั้นลง กระบวนการนี้บางครั้งเรียกว่า uglification ถึง ดูความแตกต่าง โปรดดูซอร์สโค้ด JavaScript ต่อไปนี้:
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
เมื่อซอร์สโค้ด JavaScript ก่อนหน้านี้ถูกอ่านแล้ว ผลลัพธ์อาจมีลักษณะดังนี้ ดังเช่นข้อมูลโค้ดต่อไปนี้
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
ในตัวอย่างก่อนหน้านี้ คุณจะเห็นว่าตัวแปรที่มนุษย์อ่านได้
scriptElement
ในแหล่งที่มาถูกย่อลงเป็น t
เมื่อนำไปใช้กับ
การรวบรวมสคริปต์ จึงช่วยประหยัดได้พอสมควรโดยที่ไม่กระทบ
คุณลักษณะที่ JavaScript เวอร์ชันที่ใช้งานจริงของเว็บไซต์มีให้
หากคุณใช้ Bundler ในการประมวลผลซอร์สโค้ดของเว็บไซต์ การอัปเดต มักมีการดำเนินการกับบิลด์เวอร์ชันที่ใช้งานจริงโดยอัตโนมัติ Uglifier เช่น Terser ตัวอย่างเช่น สามารถกำหนดค่าได้สูงซึ่งช่วยให้คุณสามารถปรับแต่ง ความรวดเร็วของอัลกอริทึม Uglification เพื่อประหยัดค่าใช้จ่ายสูงสุด อย่างไรก็ตาม ค่าเริ่มต้นสำหรับเครื่องมือตรวจสอบมักจะเพียงพอสำหรับการประกาศเตือน ความสมดุลที่เหมาะสมระหว่างขนาดเอาต์พุตและการรักษาความสามารถไว้
การสาธิต JavaScript
ทดสอบความรู้ของคุณ
วิธีใดเป็นวิธีที่ดีที่สุดในการโหลดไฟล์ CSS หลายไฟล์ในเบราว์เซอร์
@import
ของ CSS<link>
หลายรายการตัวสแกนการโหลดล่วงหน้าของเบราว์เซอร์ทำอะไรได้บ้าง
<link rel="preload">
ใน
ทรัพยากร HTML
เพราะเหตุใดเบราว์เซอร์จึงบล็อกการแยกวิเคราะห์ HTML ชั่วคราวโดยค่าเริ่มต้น เพื่อดาวน์โหลดทรัพยากร JavaScript
ถัดไป: การช่วยเบราว์เซอร์ด้วยคำแนะนำเกี่ยวกับแหล่งข้อมูล
ตอนนี้คุณก็รู้แล้วว่าทรัพยากรที่โหลดในองค์ประกอบ <head>
จะทำสิ่งต่างๆ ต่อไปนี้ได้
ส่งผลต่อการโหลดหน้าเว็บเริ่มต้นและเมตริกต่างๆ ก็ถึงเวลาดำเนินการต่อ ในอีก
รวมถึงสำรวจคำแนะนำเกี่ยวกับทรัพยากร และวิธีที่สิ่งเหล่านี้จะให้เคล็ดลับที่มีประโยชน์แก่
เบราว์เซอร์เพื่อเริ่มโหลดทรัพยากรและเปิดการเชื่อมต่อกับแบบข้ามต้นทาง
เร็วกว่าเบราว์เซอร์หากไม่มีเซิร์ฟเวอร์