เผยแพร่เมื่อวันที่ 31 มีนาคม 2014
การระบุและแก้ไขปัญหาคอขวดด้านประสิทธิภาพของเส้นทางการแสดงผลที่สำคัญนั้นต้องใช้ความรู้เกี่ยวกับข้อผิดพลาดที่พบได้ทั่วไป ทัวร์ชมพร้อมคําแนะนําเพื่อระบุรูปแบบประสิทธิภาพที่พบบ่อยจะช่วยคุณเพิ่มประสิทธิภาพหน้าเว็บ
การเพิ่มประสิทธิภาพเส้นทางการแสดงผลที่สําคัญช่วยให้เบราว์เซอร์แสดงหน้าเว็บได้เร็วที่สุด หน้าเว็บที่เร็วขึ้นจะทําให้เกิดการมีส่วนร่วมมากขึ้น หน้าเว็บที่ดูมากขึ้น และ Conversion ที่เพิ่มขึ้น เราจำเป็นต้องเพิ่มประสิทธิภาพทรัพยากรที่จะโหลดและลำดับที่จะโหลดทรัพยากรนั้นเพื่อลดเวลาที่ผู้เข้าชมจะเห็นหน้าจอว่างเปล่า
เพื่อช่วยให้เห็นภาพของกระบวนการนี้ ให้เริ่มจากกรณีที่เรียบง่ายที่สุดเท่าที่จะเป็นไปได้ แล้วค่อยๆ สร้างหน้าเว็บของเราให้มีแหล่งข้อมูล รูปแบบ และตรรกะแอปพลิเคชันเพิ่มเติม ในกระบวนการนี้ เราจะเพิ่มประสิทธิภาพในแต่ละกรณี เราจะพิจารณาด้วยว่าเกิดข้อผิดพลาดตรงจุดไหน
จนถึงตอนนี้ เรามุ่งเน้นที่สิ่งที่เกิดขึ้นในเบราว์เซอร์หลังจากที่ทรัพยากร (ไฟล์ CSS, JS หรือ HTML) พร้อมประมวลผล เราไม่สนใจเวลาในการดึงข้อมูลทรัพยากรจากแคชหรือจากเครือข่าย เราจะถือว่าข้อมูลต่อไปนี้เป็นจริง
- การรับส่งข้อมูลของเครือข่าย (เวลาในการนำไปใช้งาน) ไปยังเซิร์ฟเวอร์ใช้เวลา 100 มิลลิวินาที
- เวลาในการตอบสนองของเซิร์ฟเวอร์คือ 100 มิลลิวินาทีสำหรับเอกสาร HTML และ 10 มิลลิวินาทีสำหรับไฟล์อื่นๆ ทั้งหมด
ประสบการณ์ Hello World
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Critical Path: No Style</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
เริ่มต้นด้วยมาร์กอัป HTML พื้นฐานและรูปภาพเดียว โดยไม่มี CSS หรือ JavaScript จากนั้นเปิดแผงเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome และตรวจสอบการแสดงโฆษณาสื่อกลางตามลำดับขั้นที่ได้
ตามที่คาดไว้ ไฟล์ HTML ใช้เวลาดาวน์โหลดประมาณ 200 มิลลิวินาที โปรดทราบว่าส่วนที่โปร่งใสของเส้นสีน้ำเงินแสดงระยะเวลาที่เบราว์เซอร์รอในเครือข่ายโดยไม่ได้รับไบต์การตอบกลับใดๆ ส่วนที่เป็นเส้นทึบแสดงเวลาในการดาวน์โหลดจนเสร็จสมบูรณ์หลังจากที่ได้รับไบต์การตอบกลับแรก การดาวน์โหลด HTML มีขนาดเล็กมาก (<4K) เราจึงต้องการเพียงการติดต่อแบบไปกลับครั้งเดียวเพื่อดึงข้อมูลไฟล์ฉบับเต็ม ดังนั้น เอกสาร HTML จะใช้เวลาประมาณ 200 มิลลิวินาทีในการดึงข้อมูล โดยครึ่งหนึ่งของเวลาอยู่ในการรอในเครือข่าย และอีกครึ่งหนึ่งรอการตอบสนองของเซิร์ฟเวอร์
เมื่อเนื้อหา HTML พร้อมใช้งานแล้ว เบราว์เซอร์จะแยกวิเคราะห์ไบต์ แปลงเป็นโทเค็น และสร้างต้นไม้ DOM โปรดสังเกตว่าเครื่องมือสำหรับนักพัฒนาเว็บรายงานเวลาของเหตุการณ์ DOMContentLoaded ที่ด้านล่าง (216 มิลลิวินาที) ได้สะดวก ซึ่งสอดคล้องกับเส้นแนวตั้งสีน้ำเงิน ช่องว่างระหว่างการสิ้นสุดการดาวน์โหลด HTML กับเส้นแนวตั้งสีน้ำเงิน (DOMContentLoaded) คือเวลาที่เบราว์เซอร์ใช้ในการสร้างต้นไม้ DOM ซึ่งในกรณีนี้ใช้เวลาเพียงไม่กี่มิลลิวินาที
โปรดทราบว่า "รูปภาพสุดเจ๋ง" ของเราไม่ได้บล็อกเหตุการณ์ domContentLoaded
เราพบว่าเราสามารถสร้าง Render Tree และแม้แต่ระบายสีหน้าเว็บโดยไม่ต้องรอเนื้อหาแต่ละรายการในหน้านั้น ทรัพยากรบางอย่างก็สำคัญต่อการแสดงครั้งแรกที่รวดเร็ว อันที่จริงแล้ว เมื่อพูดถึงเส้นทางการแสดงผลที่สำคัญ เรามักจะพูดถึงมาร์กอัป HTML, CSS และ JavaScript รูปภาพไม่ได้บล็อกการแสดงผลเริ่มต้นของหน้าเว็บ แต่เราก็ควรพยายามแสดงรูปภาพโดยเร็วที่สุด
อย่างไรก็ตาม เหตุการณ์ load
(หรือที่เรียกว่า onload
) ถูกบล็อกในภาพ: เครื่องมือสําหรับนักพัฒนาเว็บรายงานเหตุการณ์ onload
ที่ 335 มิลลิวินาที โปรดทราบว่าเหตุการณ์ onload
หมายถึงจุดที่ระบบดาวน์โหลดและประมวลผลทรัพยากรทั้งหมดที่หน้าเว็บจําเป็นต้องใช้ เมื่อถึงจุดนี้ แถบหมุนที่แสดงการโหลดในเบราว์เซอร์จะหยุดหมุน (เส้นแนวตั้งสีแดงใน Waterfall)
การเพิ่ม JavaScript และ CSS เข้ามา
หน้า "Hello World Experience" ของเราอาจดูเรียบง่าย แต่เบื้องหลังนั้นมีอะไรเกิดขึ้นมากมาย ในทางปฏิบัติ เราจะต้องได้รับมากกว่าแค่ HTML: เป็นไปได้ว่าจะต้องมีสไตลชีต CSS และสคริปต์อย่างน้อย 1 รายการเพื่อเพิ่มความโต้ตอบในหน้าเว็บ เพิ่มทั้ง 2 อย่างพร้อมกันเพื่อดูว่าจะเกิดอะไรขึ้น
<!DOCTYPE html>
<html>
<head>
<title>Critical Path: Measure Script</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
</head>
<body onload="measureCRP()">
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script src="timing.js"></script>
</body>
</html>
ก่อนเพิ่ม JavaScript และ CSS
เมื่อใช้ JavaScript และ CSS
การเพิ่มไฟล์ CSS และ JavaScript ภายนอกจะเพิ่มคําขออีก 2 รายการลงใน Waterfall ซึ่งเบราว์เซอร์จะส่งคําขอทั้งหมดในเวลาใกล้เคียงกัน อย่างไรก็ตาม โปรดทราบว่าตอนนี้ความแตกต่างของเวลาระหว่างเหตุการณ์ domContentLoaded
กับ onload
ลดลงอย่างมาก
เกิดอะไรขึ้น
- ซึ่งต่างจากตัวอย่าง HTML ธรรมดาคือ เราต้องดึงข้อมูลและแยกวิเคราะห์ไฟล์ CSS เพื่อสร้าง CSSOM และต้องใช้ทั้ง DOM และ CSSOM เพื่อสร้างต้นไม้แสดงผล
- เนื่องจากหน้าเว็บมีไฟล์ JavaScript ที่บล็อกโปรแกรมแยกวิเคราะห์ด้วย เหตุการณ์
domContentLoaded
จึงถูกบล็อกจนกว่าจะมีการดาวน์โหลดและแยกวิเคราะห์ไฟล์ CSS เนื่องจาก JavaScript อาจค้นหา CSSOM เราจึงต้องบล็อกไฟล์ CSS ดังกล่าวจนกว่าจะมีการดาวน์โหลดก่อนจึงจะเรียกใช้ JavaScript ได้
จะเกิดอะไรขึ้นหากเราแทนที่สคริปต์ภายนอกด้วยสคริปต์ในหน้า แม้ว่าสคริปต์จะฝังอยู่ในหน้าเว็บโดยตรง แต่เบราว์เซอร์จะไม่สามารถเรียกใช้สคริปต์ได้จนกว่า CSSOM จะสร้างขึ้น กล่าวโดยย่อคือ JavaScript ที่ฝังอยู่จะบล็อกโปรแกรมวิเคราะห์ด้วย
ซึ่งหมายความว่าแม้จะมีการบล็อกใน CSS แล้ว แต่การแทรกในบรรทัดสคริปต์จะทำให้หน้าเว็บแสดงผลเร็วขึ้นไหม ลองทำดูว่าเกิดอะไรขึ้น
JavaScript ภายนอก
JavaScript ในบรรทัด:
เราส่งคำขอน้อยลง 1 รายการ แต่ทั้งเวลา onload
และ domContentLoaded
นั้นแทบจะเท่าเดิม เหตุผล เราทราบดีว่า JavaScript จะอยู่ในรูปแบบอินไลน์หรือภายนอกก็ได้ เพราะทันทีที่เบราว์เซอร์พบแท็กสคริปต์ ก็จะบล็อกและรอจนกว่า CSSOM จะสร้างขึ้น นอกจากนี้ ในตัวอย่างแรก เบราว์เซอร์จะดาวน์โหลดทั้ง CSS และ JavaScript พร้อมกันและดาวน์โหลดเสร็จในเวลาใกล้เคียงกัน ในกรณีนี้ การวางโค้ด JavaScript ไว้ภายในบรรทัดเดียวกันไม่ได้ช่วยอะไรมากนัก แต่มีกลยุทธ์หลายอย่างที่ทําให้หน้าเว็บแสดงผลเร็วขึ้นได้
ก่อนอื่น โปรดทราบว่าสคริปต์อินไลน์ทั้งหมดจะบล็อกโปรแกรมวิเคราะห์ แต่สำหรับสคริปต์ภายนอก เราสามารถเพิ่มแอตทริบิวต์ async
เพื่อเลิกบล็อกโปรแกรมวิเคราะห์ได้ ให้ยกเลิกการแทรกบรรทัดแล้วลองทำดังนี้
<!DOCTYPE html>
<html>
<head>
<title>Critical Path: Measure Async</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
</head>
<body onload="measureCRP()">
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script async src="timing.js"></script>
</body>
</html>
JavaScript (ภายนอก) ที่บล็อกโปรแกรมแยกวิเคราะห์:
JavaScript แบบ Async (ภายนอก):
ดีขึ้นมาก เหตุการณ์ domContentLoaded
จะทริกเกอร์ไม่นานหลังจากที่ระบบแยกวิเคราะห์ HTML แล้ว เบราว์เซอร์จะรู้ว่าไม่ต้องบล็อก JavaScript และเนื่องจากไม่มีสคริปต์ตัวแยกวิเคราะห์อื่นๆ ที่บล็อกอยู่ การสร้าง CSSOM จึงดําเนินการไปพร้อมๆ กันได้
อีกทางเลือกหนึ่งคือ เราจะแทรกทั้ง CSS และ JavaScript ดังนี้
<!DOCTYPE html>
<html>
<head>
<title>Critical Path: Measure Inlined</title>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style>
p {
font-weight: bold;
}
span {
color: red;
}
p span {
display: none;
}
img {
float: right;
}
</style>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script>
var span = document.getElementsByTagName('span')[0];
span.textContent = 'interactive'; // change DOM text content
span.style.display = 'inline'; // change CSSOM property
// create a new element, style it, and append it to the DOM
var loadTime = document.createElement('div');
loadTime.textContent = 'You loaded this page on: ' + new Date();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);
</script>
</body>
</html>
โปรดทราบว่าเวลา domContentLoaded
นั้นมีประสิทธิภาพเหมือนกับในตัวอย่างก่อนหน้านี้ เราได้แทรกทั้ง CSS และ JS ไว้ในหน้าเว็บแทนการทําเครื่องหมาย JavaScript เป็น async ซึ่งทำให้หน้า HTML ของเรามีขนาดใหญ่ขึ้นมาก แต่ข้อดีคือเบราว์เซอร์ไม่ต้องรอดึงข้อมูลภายนอก เนื่องจากทุกอย่างอยู่ในหน้าเว็บแล้ว
ดังที่คุณเห็น แม้ว่าหน้าเว็บจะเรียบง่ายมาก แต่การเพิ่มประสิทธิภาพเส้นทางการแสดงผลที่สำคัญก็ไม่ใช่เรื่องง่าย เราจําเป็นต้องทําความเข้าใจกราฟความเกี่ยวข้องระหว่างทรัพยากรต่างๆ ระบุทรัพยากรที่ "สําคัญ" และต้องเลือกกลยุทธ์ต่างๆ ในการใช้ทรัพยากรเหล่านั้นในหน้าเว็บ ปัญหานี้ไม่มีวิธีแก้ปัญหาที่ตายตัว เนื่องจากแต่ละหน้ามีความแตกต่างกัน คุณต้องทำตามขั้นตอนที่คล้ายกันด้วยตนเองเพื่อหากลยุทธ์ที่เหมาะสมที่สุด
แต่มาดูกันว่าเราจะย้อนกลับไประบุรูปแบบประสิทธิภาพทั่วไปได้ไหม
รูปแบบประสิทธิภาพ
หน้าเว็บที่เรียบง่ายที่สุดประกอบด้วยมาร์กอัป HTML เท่านั้น ไม่มี CSS, JavaScript หรือทรัพยากรประเภทอื่นๆ ในการแสดงผลหน้านี้ เบราว์เซอร์ต้องเริ่มคําขอ รอให้เอกสาร HTML มาถึง แยกวิเคราะห์ สร้างขึ้น DOM และสุดท้ายแสดงผลบนหน้าจอ
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Critical Path: No Style</title>
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
เวลาระหว่าง T0 และ T1 จะบันทึกเวลาในการประมวลผลของเครือข่ายและเซิร์ฟเวอร์ ในกรณีที่ดีที่สุด (หากไฟล์ HTML มีขนาดเล็ก) เครือข่ายจะดึงข้อมูลทั้งเอกสารได้ด้วยการติดต่อเพียง 1 ครั้ง การทำงานของโปรโตคอลการรับส่ง TCP อาจทำให้ไฟล์ที่มีขนาดใหญ่กว่านี้ต้องมีการส่งข้อมูลไป-กลับมากขึ้น ดังนั้น ในกรณีที่ดีที่สุด หน้าเว็บด้านบนจะมีเส้นทางการแสดงผลที่สำคัญแบบไปกลับ 1 รอบ (ขั้นต่ำ)
ลองดูหน้าเดียวกันนี้ แต่มีไฟล์ CSS ภายนอก
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
</body>
</html>
อีกครั้ง เราจะต้องส่งข้อมูลไปมาทางเครือข่ายเพื่อดึงข้อมูลเอกสาร HTML แล้วมาร์กอัปที่ดึงมาบอกเราว่าเราต้องการใช้ไฟล์ CSS ด้วย ซึ่งหมายความว่าเบราว์เซอร์ต้องกลับไปที่เซิร์ฟเวอร์เพื่อรับ CSS ก่อนที่จะแสดงผลหน้าเว็บบนหน้าจอได้ ด้วยเหตุนี้ หน้านี้จึงต้องมีการส่งข้อมูลไป-กลับอย่างน้อย 2 ครั้งก่อนที่จะแสดงได้ ขอย้ำอีกครั้งว่าไฟล์ CSS อาจใช้เวลาไป-กลับหลายครั้ง ดังนั้นจึงให้ความสำคัญกับ "ขั้นต่ำ"
คําศัพท์ที่เราใช้อธิบายเส้นทางการแสดงผลที่สําคัญมีดังนี้
- ทรัพยากรสําคัญ: ทรัพยากรที่อาจบล็อกการแสดงผลเริ่มต้นของหน้า
- ความยาวเส้นทางวิกฤต: จำนวนครั้งของการเดินทางไปกลับ หรือเวลารวมที่ต้องใช้ในการดึงข้อมูลทรัพยากรที่สำคัญทั้งหมด
- ไบต์สําคัญ: จํานวนไบต์ทั้งหมดที่จําเป็นสําหรับการแสดงผลหน้าเว็บครั้งแรก ซึ่งเป็นผลรวมของขนาดไฟล์การโอนของทรัพยากรสําคัญทั้งหมด ตัวอย่างแรกของเราที่มีหน้า HTML หน้าเดียวมีทรัพยากรวิกฤติเพียงแหล่งเดียว (เอกสาร HTML) ความยาวเส้นทางวิกฤติก็เท่ากับหนึ่งเครือข่ายไปกลับ (สมมติว่าไฟล์มีขนาดเล็ก) และไบต์วิกฤตรวมเพียงขนาดการโอนของเอกสาร HTML เอง
ตอนนี้ให้เปรียบเทียบสิ่งเหล่านี้กับลักษณะเส้นทางวิกฤตของตัวอย่าง HTML และ CSS ก่อนหน้านี้:
- ทรัพยากรสําคัญ 2 รายการ
- การเดินทางไปกลับอย่างน้อย 2 รอบสำหรับความยาวเส้นทางวิกฤติขั้นต่ำ
- ไบต์สําคัญ 9 KB
เราต้องใช้ทั้ง HTML และ CSS เพื่อสร้างต้นไม้การแสดงผล ด้วยเหตุนี้ ทั้ง HTML และ CSS จึงถือเป็นทรัพยากรสําคัญ: ระบบจะดึงข้อมูล CSS หลังจากที่เบราว์เซอร์ได้รับเอกสาร HTML แล้วเท่านั้น ดังนั้นความยาวเส้นทางที่สำคัญจึงมีอย่างน้อย 2 รอบ แหล่งข้อมูลทั้ง 2 รายการรวมกันมีจำนวนไบต์ที่สำคัญทั้งหมด 9 KB
ตอนนี้ให้เพิ่มไฟล์ JavaScript เพิ่มเติมลงในส่วนผสม
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script src="app.js"></script>
</body>
</html>
เราได้เพิ่ม app.js
ซึ่งเป็นทั้งเนื้อหา JavaScript ภายนอกในหน้าเว็บและทรัพยากรการบล็อกโปรแกรมแยกวิเคราะห์ (ซึ่งสำคัญมาก) ยิ่งไปกว่านั้น ในการเรียกใช้ไฟล์ JavaScript เราต้องบล็อกและรอ CSSOM โปรดทราบว่า JavaScript สามารถค้นหา CSSOM ได้ ดังนั้นเบราว์เซอร์จึงหยุดชั่วคราวจนกว่าจะมีการดาวน์โหลด style.css
และสร้าง CSSOM
อย่างไรก็ตาม ในทางปฏิบัติ หากเราดู "การแสดงภาพ Waterfall ของเครือข่าย" ของหน้านี้ คุณจะเห็นการเริ่มคําขอทั้ง CSS และ JavaScript ในเวลาใกล้เคียงกัน เบราว์เซอร์จะรับ HTML, ค้นพบทั้ง 2 ทรัพยากร และเริ่มคําขอทั้ง 2 รายการ ด้วยเหตุนี้ หน้าที่แสดงในรูปภาพก่อนหน้าจึงมีลักษณะวิกฤติดังต่อไปนี้
- ทรัพยากรสําคัญ 3 รายการ
- การส่งข้อมูลไปกลับอย่างน้อย 2 ครั้งสำหรับความยาวเส้นทางที่สำคัญขั้นต่ำ
- ไบต์สําคัญ 11 KB
ตอนนี้เรามีทรัพยากรสําคัญ 3 รายการซึ่งมีไบต์สําคัญรวมกัน 11 KB แต่ความยาวเส้นทางสําคัญยังคงเป็น 2 รอบเนื่องจากเราสามารถโอน CSS และ JavaScript พร้อมกันได้ การหาลักษณะของเส้นทางการแสดงผลที่สำคัญหมายความว่าคุณจะสามารถระบุทรัพยากรที่สำคัญและเข้าใจวิธีที่เบราว์เซอร์จะกำหนดเวลาการดึงข้อมูล
หลังจากแชทกับนักพัฒนาเว็บไซต์แล้ว เราพบว่า JavaScript ที่รวมไว้ในหน้าเว็บไม่จำเป็นต้องบล็อก เนื่องจากเรามีข้อมูลวิเคราะห์และโค้ดอื่นๆ บางส่วนที่ไม่จําเป็นต้องบล็อกการแสดงผลของหน้าเว็บ เมื่อทราบแล้ว เราสามารถเพิ่มแอตทริบิวต์ async
ในองค์ประกอบ <script>
เพื่อเลิกบล็อกโปรแกรมแยกวิเคราะห์ได้ ดังนี้
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" />
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script src="app.js" async></script>
</body>
</html>
สคริปต์แบบไม่ต่อเนื่องมีข้อดีหลายประการ ดังนี้
- สคริปต์จะไม่บล็อกโปรแกรมวิเคราะห์อีกต่อไปและไม่ได้อยู่ในเส้นทางการแสดงผลที่สำคัญ
- เนื่องจากไม่มีสคริปต์สําคัญอื่นๆ CSS จึงไม่ต้องบล็อกเหตุการณ์
domContentLoaded
- ยิ่งเหตุการณ์
domContentLoaded
เริ่มทํางานเร็วเท่าใด ตรรกะการทํางานของแอปพลิเคชันอื่นๆ ก็จะเริ่มทํางานเร็วขึ้นเท่านั้น
ด้วยเหตุนี้ หน้าเว็บที่เพิ่มประสิทธิภาพจึงกลับมาเป็นทรัพยากรสําคัญ 2 รายการ (HTML และ CSS) โดยมีความยาวเส้นทางสําคัญขั้นต่ำ 2 รอบ และไบต์สําคัญทั้งหมด 9KB
สุดท้ายนี้ หากต้องใช้ชีตสไตล์ CSS สำหรับสิ่งพิมพ์เท่านั้น ชีตสไตล์จะมีลักษณะเป็นอย่างไร
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link href="style.css" rel="stylesheet" media="print" />
</head>
<body>
<p>Hello <span>web performance</span> students!</p>
<div><img src="awesome-photo.jpg" /></div>
<script src="app.js" async></script>
</body>
</html>
เนื่องจากทรัพยากร style.css ใช้สำหรับสิ่งพิมพ์เท่านั้น เบราว์เซอร์จึงไม่จำเป็นต้องบล็อกทรัพยากรดังกล่าวเพื่อแสดงผลหน้าเว็บ ดังนั้น ทันทีที่การสร้าง DOM เสร็จสมบูรณ์ เบราว์เซอร์ก็จะมีข้อมูลเพียงพอที่จะแสดงผลหน้าเว็บ ด้วยเหตุนี้ หน้านี้จึงมีทรัพยากรสําคัญเพียงรายการเดียว (เอกสาร HTML) และความยาวเส้นทางการแสดงผลที่สําคัญขั้นต่ำคือ 1 รอบ