การปรับปรุง Largest Contentful Paint ในระบบนิเวศ JavaScript
Google ทำงานร่วมกับเฟรมเวิร์กเว็บยอดนิยมเพื่อช่วยให้เฟรมเวิร์กเหล่านั้นทำงานได้ดีตาม Core Web Vitals ภายใต้โปรเจ็กต์ Aurora Angular และ Next.js ได้เข้าสู่แบบอักษรในบรรทัดแล้ว ซึ่งอธิบายไว้ในส่วนแรกของบทความนี้ การเพิ่มประสิทธิภาพที่ 2 ที่จะกล่าวถึงคือการฝัง CSS ที่สำคัญ ซึ่งตอนนี้เปิดใช้โดยค่าเริ่มต้นใน Angular CLI และอยู่ระหว่างการนำไปใช้งานใน Nuxt.js
การฝังแบบอักษร
หลังจากวิเคราะห์แอปพลิเคชันหลายร้อยรายการ ทีม Aurora พบว่านักพัฒนาแอปมักจะใส่แบบอักษรในแอปพลิเคชันโดยอ้างอิงแบบอักษรในองค์ประกอบ <head>
ของ index.html
ต่อไปนี้เป็นตัวอย่างลักษณะที่ไอคอนนี้จะแสดงเมื่อรวมกับไอคอน Material
<!doctype html>
<html lang="en">
<head>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
...
</html>
แม้ว่ารูปแบบนี้จะถูกต้องและใช้งานได้อย่างสมบูรณ์ แต่ก็จะบล็อกการแสดงผลของแอปพลิเคชันและส่งคำขอเพิ่มเติม โปรดดูซอร์สโค้ดของสไตล์ชีตที่อ้างอิงใน HTML ด้านบนเพื่อให้เข้าใจสิ่งที่เกิดขึ้นมากขึ้น
/* fallback */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/font.woff2) format('woff2');
}
.material-icons {
/*...*/
}
โปรดสังเกตว่าคําจํากัดความ font-face
อ้างอิงไฟล์ภายนอกที่โฮสต์ใน fonts.gstatic.com
เมื่อโหลดแอปพลิเคชัน เบราว์เซอร์จะต้องดาวน์โหลดสไตล์ชีตต้นฉบับที่อ้างอิงในส่วนหัวก่อน
จากนั้นเบราว์เซอร์จะดาวน์โหลดไฟล์ woff2
และสุดท้ายก็จะแสดงผลแอปพลิเคชันได้
โอกาสในการเพิ่มประสิทธิภาพคือการดาวน์โหลดสไตล์ชีตเริ่มต้น ณ เวลาที่สร้างและแทรกไว้ใน index.html
ซึ่งจะข้ามการส่งข้อมูลไปกลับทั้งหมดไปยัง CDN ที่รันไทม์ จึงช่วยลดเวลาในการบล็อก
เมื่อสร้างแอปพลิเคชัน ระบบจะส่งคําขอไปยัง CDN ซึ่งจะดึงข้อมูลสไตล์ชีตและแทรกไว้ในไฟล์ HTML โดยเพิ่ม <link rel=preconnect>
ลงในโดเมน เมื่อนำเทคนิคนี้ไปใช้
เราจะได้ผลลัพธ์ต่อไปนี้
<!doctype html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin >
<style type="text/css">
@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(https://fonts.gstatic.com/font.woff2) format('woff2');}.material-icons{/*...*/}</style>
...
</html>
แบบอักษรอินไลน์พร้อมใช้งานแล้วใน Next.js และ Angular
เมื่อนักพัฒนาเฟรมเวิร์กใช้การเพิ่มประสิทธิภาพในเครื่องมือพื้นฐาน ก็จะทําให้แอปพลิเคชันที่มีอยู่และแอปพลิเคชันใหม่เปิดใช้การเพิ่มประสิทธิภาพได้ง่ายขึ้น ซึ่งจะนําไปสู่การปรับปรุงทั้งระบบนิเวศ
การปรับปรุงนี้จะเปิดใช้โดยค่าเริ่มต้นจาก Next.js v10.2 และ Angular v11 ทั้ง 2 แพลตฟอร์มรองรับการฝังแบบอักษรของ Google และ Adobe Angular คาดว่าจะเปิดตัวเวอร์ชันหลังใน v12.2
คุณสามารถค้นหาการใช้งานแบบอักษรอินไลน์ใน Next.js บน GitHub และดูวิดีโอที่อธิบายการเพิ่มประสิทธิภาพนี้ในบริบทของ Angular
การแทรก CSS ที่สําคัญในหน้า
การปรับปรุงอีกอย่างหนึ่งคือการปรับปรุงเมตริก First Contentful Paint (FCP) และ Largest Contentful Paint (LCP) ด้วยการแทรก CSS ที่สำคัญในหน้า CSS ที่สําคัญของหน้าเว็บประกอบด้วยรูปแบบทั้งหมดที่ใช้ในการแสดงผลครั้งแรก ดูข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนี้ได้ที่หัวข้อเลื่อน CSS ที่ไม่สําคัญ
เราสังเกตเห็นว่าแอปพลิเคชันจำนวนมากโหลดรูปแบบพร้อมกันซึ่งบล็อกการแสดงผลของแอปพลิเคชัน วิธีแก้ไขด่วนคือการโหลดสไตล์ต่างๆ แบบไม่พร้อมกัน แทนที่จะโหลดสคริปต์ด้วย media="all"
ให้ตั้งค่าแอตทริบิวต์ media
เป็น print
และเมื่อโหลดเสร็จแล้ว ให้แทนที่ค่าแอตทริบิวต์เป็น all
<link rel="stylesheet" href="..." media="print" onload="this.media='all'">
แต่วิธีนี้อาจทําให้เนื้อหาที่ไม่มีการจัดรูปแบบกะพริบ
วิดีโอด้านบนแสดงการแสดงผลของหน้าเว็บซึ่งโหลดสไตล์แบบไม่พร้อมกัน ปัญหาการกะพริบเกิดขึ้นเนื่องจากเบราว์เซอร์เริ่มดาวน์โหลดสไตล์ก่อน จากนั้นจึงแสดงผล HTML ต่อ เมื่อเบราว์เซอร์ดาวน์โหลดสไตล์แล้ว ระบบจะทริกเกอร์เหตุการณ์ onload
ขององค์ประกอบลิงก์ อัปเดตแอตทริบิวต์ media
เป็น all
และใช้สไตล์กับ DOM
ในระหว่างการแสดงผล HTML กับการใช้สไตล์ หน้าเว็บจะไม่มีสไตล์บางส่วน เมื่อเบราว์เซอร์ใช้สไตล์ดังกล่าว เราเห็นการกะพริบ ซึ่งทำให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ไม่ดีและส่งผลให้การจัดวางแบบสะสมที่เปลี่ยนไป (CLS) ลดลง
การแทรก CSS ที่สําคัญในหน้าพร้อมกับการโหลดสไตล์แบบไม่พร้อมกันจะช่วยปรับปรุงลักษณะการโหลดได้ เครื่องมือ Critters จะค้นหาสไตล์ที่ใช้ในหน้าเว็บโดยดูที่ตัวเลือกในสไตล์ชีตและจับคู่กับ HTML เมื่อพบรายการที่ตรงกัน ระบบจะถือว่าสไตล์ที่เกี่ยวข้องเป็นส่วนหนึ่งของ CSS ที่สําคัญ และแทรกไว้ในหน้า
ยกตัวอย่างเช่น:
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> </head> <body> <section> <button class="primary"></button> </section> </body>
/* styles.css */ section button.primary { /* ... */ } .list { /* ... */ }
ในตัวอย่างข้างต้น Critters จะอ่านและแยกวิเคราะห์เนื้อหาของ styles.css
จากนั้นจะจับคู่ตัวเลือก 2 รายการกับ HTML และพบว่าเราใช้ section button.primary
สุดท้าย Critter จะแทรกสไตล์ที่เกี่ยวข้องใน <head>
ของหน้าเว็บ ซึ่งจะทำให้เกิดผลดังนี้
<head> <link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'"> <style> section button.primary { /* ... */ } </style> </head> <body> <section> <button class="primary"></button> </section> </body>
หลังจากแทรก CSS ที่สำคัญลงใน HTML แล้ว คุณจะเห็นว่าหน้าเว็บไม่กะพริบอีกต่อไป
ตอนนี้การฝัง CSS ที่สำคัญใน Angular พร้อมใช้งานแล้ว และเปิดใช้โดยค่าเริ่มต้นใน v12 หากคุณใช้ v11 ให้เปิดโดยตั้งค่าพร็อพเพอร์ตี้ inlineCritical
เป็น true
ใน angular.json
หากต้องการเลือกใช้ฟีเจอร์นี้ใน Next.js ให้เพิ่ม experimental: { optimizeCss: true }
ลงใน next.config.js
สรุป
ในโพสต์นี้ เราได้พูดถึงการทำงานร่วมกันระหว่าง Chrome กับเฟรมเวิร์กเว็บ หากคุณเป็นผู้เขียนเฟรมเวิร์กและพบปัญหาบางอย่างที่เราจัดการในเทคโนโลยีของคุณ เราหวังว่าสิ่งที่ค้นพบจะกระตุ้นให้คุณใช้การเพิ่มประสิทธิภาพที่คล้ายกัน
ดูข้อมูลเพิ่มเติมเกี่ยวกับการปรับปรุง คุณสามารถดูรายการที่ครอบคลุมเกี่ยวกับงานการเพิ่มประสิทธิภาพที่เราทำสําหรับ Core Web Vitals ได้ในโพสต์แนะนํา Aurora