คำแนะนำแบบทีละขั้นในการใช้ WebPageTest เพื่อระบุและแก้ไขปัญหาความไม่เสถียรของเลย์เอาต์
ในโพสต์ก่อนหน้านี้ผมได้เขียนเกี่ยวกับการวัด Cumulative Layout Shift (CLS) ใน WebPageTest CLS คือการรวมการเปลี่ยนแปลงเลย์เอาต์ทั้งหมด โพสต์นี้เลยคิดว่าคงน่าสนใจหากได้เจาะลึกรายละเอียดและตรวจสอบการเปลี่ยนแปลงเลย์เอาต์แต่ละรายการในหน้าเว็บ เพื่อพยายามทำความเข้าใจสิ่งที่อาจเป็นสาเหตุของความไม่เสถียรและพยายามแก้ไขปัญหาจริงๆ
การวัดการเปลี่ยนแปลงเลย์เอาต์
เมื่อใช้ Layout Instability API เราจะรับรายการเหตุการณ์ Layout Shift ทั้งหมดในหน้าเว็บได้
new Promise(resolve => {
new PerformanceObserver(list => {
resolve(list.getEntries().filter(entry => !entry.hadRecentInput));
}).observe({type: "layout-shift", buffered: true});
}).then(console.log);
ซึ่งจะสร้างอาร์เรย์ของการเปลี่ยนเลย์เอาต์ที่ไม่ได้เกิดเหตุการณ์การป้อนข้อมูลขึ้นก่อน:
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 210.78500000294298,
"duration": 0,
"value": 0.0001045969445437389,
"hadRecentInput": false,
"lastInputTime": 0
}
]
ในตัวอย่างนี้มีการเปลี่ยนแปลงเล็กน้อยมากเพียงครั้งเดียวที่ 0.01% ที่ 210 มิลลิวินาที
การรู้เวลาและความรุนแรงของการเปลี่ยนแปลงจะมีประโยชน์ในการช่วยจำกัดขอบข่ายของสิ่งที่อาจเป็นสาเหตุของการเปลี่ยนแปลงนั้น กลับมาที่ WebPageTest สำหรับสภาพแวดล้อมในห้องทดลองเพื่อทำการทดสอบเพิ่มเติมกัน
การวัดการเปลี่ยนแปลงของเลย์เอาต์ใน WebPageTest
การวัดการเปลี่ยนแปลงเลย์เอาต์แต่ละรายการจะต้องใช้เมตริกที่กําหนดเอง ซึ่งคล้ายกับการวัด CLS ใน WebPageTest อย่างไรก็ตาม กระบวนการนี้ง่ายขึ้นเพราะ Chrome 77 มีความเสถียรแล้ว Layout Instability API จะเปิดใช้งานโดยค่าเริ่มต้น ดังนั้นคุณควรเรียกใช้ข้อมูลโค้ด JS ดังกล่าวบนเว็บไซต์ใดๆ ภายใน Chrome 77 และรับผลลัพธ์ได้ทันที ใน WebPageTest คุณจะใช้เบราว์เซอร์ Chrome เริ่มต้นได้และไม่ต้องกังวลเรื่องแฟล็กบรรทัดคำสั่งหรือการใช้ Canary
มาแก้ไขสคริปต์ดังกล่าวเพื่อสร้างเมตริกที่กำหนดเองสำหรับ WebPageTest กัน
[LayoutShifts]
return new Promise(resolve => {
new PerformanceObserver(list => {
resolve(JSON.stringify(list.getEntries().filter(entry => !entry.hadRecentInput)));
}).observe({type: "layout-shift", buffered: true});
});
คำสัญญาในสคริปต์นี้จะแปลค่าเป็น JSON ของอาร์เรย์แทนที่จะเป็นอาร์เรย์ เนื่องจากเมตริกที่กําหนดเองจะสร้างได้เฉพาะข้อมูลประเภทพื้นฐาน เช่น สตริงหรือตัวเลข
เว็บไซต์ที่ฉันจะทำการทดสอบคือ ismyhostfastyet.com ซึ่งเป็นเว็บไซต์ที่ฉันสร้างขึ้นเพื่อเปรียบเทียบประสิทธิภาพในการโหลดในชีวิตจริงของโฮสต์เว็บ
การระบุสาเหตุของความไม่เสถียรของเลย์เอาต์
ในผลลัพธ์ เราจะเห็นว่าเมตริกที่กำหนดเองของ LayoutShift มีค่าต่อไปนี้
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3087.2349999990547,
"duration": 0,
"value": 0.3422101449275362,
"hadRecentInput": false,
"lastInputTime": 0
}
]
โดยสรุปแล้ว เลย์เอาต์ที่มีการเปลี่ยนแปลงเลย์เอาต์เดียวอยู่ที่ 34.2% เกิดขึ้นที่ 3, 087 มิลลิวินาที เราจะใช้มุมมองแถบฟิล์มของ WebPageTest เพื่อช่วยระบุตัวผู้ต้องหา
การเลื่อนไปที่เครื่องหมายประมาณ 3 วินาทีในแผ่นฟิล์มแสดงให้เราเห็นถึงสาเหตุของการเปลี่ยนแปลงเลย์เอาต์ 34% ก็คือตารางสีสันสดใส เว็บไซต์ดึงข้อมูลไฟล์ JSON แบบไม่พร้อมกัน จากนั้นแสดงผลในตาราง ในตอนแรกตารางว่างเปล่า ดังนั้นการรอให้ตารางเต็มเมื่อโหลดผลลัพธ์จะทําให้เกิดการเปลี่ยนแปลง
แต่ยังไม่หมดเพียงเท่านี้ เมื่อหน้าเว็บเสร็จสมบูรณ์ที่ประมาณ 4.3 วินาที เราจะเห็นว่า <h1>
ของหน้าเว็บ "โฮสต์ของฉันเร็วไหม" ปรากฏขึ้น ที่เป็นเช่นนี้เพราะเว็บไซต์ใช้แบบอักษรของเว็บและยังไม่ได้ดำเนินการเพิ่มประสิทธิภาพการแสดงผล เลย์เอาต์ไม่ได้มีการเปลี่ยนแปลงเมื่อเกิดเหตุการณ์นี้ขึ้น แต่ยังคงทำให้ผู้ใช้ได้รับประสบการณ์ที่ไม่ดีจากการต้องรอนานๆ จึงจะอ่านชื่อได้
การแก้ไขความไม่เสถียรของเลย์เอาต์
เมื่อเราทราบว่าตารางที่สร้างขึ้นแบบไม่พร้อมกันทำให้ 1 ใน 3 ของวิวพอร์ตมีการเปลี่ยนแปลงแล้ว ก็ถึงเวลาแก้ไขแล้ว เราไม่ทราบเนื้อหาของตารางจนกว่าจะมีการโหลดผลลัพธ์ JSON จริงๆ แต่เรายังคงสามารถเติมข้อมูลตัวยึดตำแหน่งบางอย่างในตารางได้ เพื่อให้ตัวเลย์เอาต์ค่อนข้างเสถียรเมื่อแสดงผล DOM
ต่อไปนี้เป็นโค้ดสำหรับสร้างข้อมูลตัวยึดตำแหน่ง
function getRandomFiller(maxLength) {
var filler = '█';
var len = Math.ceil(Math.random() * maxLength);
return new Array(len).fill(filler).join('');
}
function getRandomDistribution() {
var fast = Math.random();
var avg = (1 - fast) * Math.random();
var slow = 1 - (fast + avg);
return [fast, avg, slow];
}
// Temporary placeholder data.
window.data = [];
for (var i = 0; i < 36; i++) {
var [fast, avg, slow] = getRandomDistribution();
window.data.push({
platform: getRandomFiller(10),
client: getRandomFiller(5),
n: getRandomFiller(1),
fast,
avg,
slow
});
}
updateResultsTable(sortResults(window.data, 'fast'));
ระบบจะสร้างข้อมูลตัวยึดตำแหน่งขึ้นมาแบบสุ่มก่อนที่จะจัดเรียง โดยจะมีอักขระ "█" ซ้ำหลายครั้งเพื่อสร้างตัวยึดตำแหน่งที่เป็นภาพสำหรับข้อความและการกระจายค่าหลัก 3 ค่าที่สร้างขึ้นแบบสุ่ม และฉันได้เพิ่มรูปแบบบางอย่างเพื่อทำให้สีทั้งหมดออกจากตารางจางลงเพื่อแสดงอย่างชัดเจนว่าข้อมูลยังโหลดไม่สมบูรณ์
ลักษณะของตัวยึดตำแหน่งที่คุณใช้ไม่สำคัญต่อความเสถียรของเลย์เอาต์ วัตถุประสงค์ของตัวยึดตำแหน่งคือเพื่อให้ผู้ใช้มั่นใจว่าเนื้อหาจะเข้ามาและหน้าเว็บไม่เสียหาย
นี่คือลักษณะของตัวยึดตำแหน่งขณะที่ระบบกำลังโหลดข้อมูล JSON
การแก้ไขปัญหาแบบอักษรของเว็บจะง่ายขึ้นมาก เนื่องจากเว็บไซต์ใช้ Google Fonts เราจึงจำเป็นต้องส่งไปในพร็อพเพอร์ตี้ display=swap
ในคำขอ CSS ไม่มีแล้ว Fonts API จะเพิ่มรูปแบบ font-display: swap
ในการประกาศแบบอักษร ซึ่งจะช่วยให้เบราว์เซอร์แสดงผลข้อความในแบบอักษรสำรองได้ทันที ต่อไปนี้คือมาร์กอัปที่เกี่ยวข้องพร้อมการแก้ไข
<link href="https://fonts.googleapis.com/css?family=Chivo:900&display=swap" rel="stylesheet">
การยืนยันการเพิ่มประสิทธิภาพ
หลังจากเรียกใช้หน้าเว็บอีกครั้งผ่าน WebPageTest แล้ว เราจะสร้างการเปรียบเทียบก่อนและหลังเพื่อแสดงภาพความแตกต่างและวัดระดับใหม่ของความไม่เสถียรของเลย์เอาต์ได้
[
{
"name": "",
"entryType": "layout-shift",
"startTime": 3070.9349999997357,
"duration": 0,
"value": 0.000050272187989256116,
"hadRecentInput": false,
"lastInputTime": 0
}
]
ตามเมตริกที่กำหนดเอง ยังคงมีการเปลี่ยนแปลงเลย์เอาต์เกิดขึ้นที่ 3, 071 มิลลิวินาที (ใกล้เคียงกับก่อนหน้า) แต่ความรุนแรงของการเปลี่ยนแปลงจะน้อยกว่ามาก นั่นคือ 0.005% ผมอยู่กับสิ่งนี้ได้
นอกจากนี้ แถบฟิล์มยังเห็นได้ชัดเจนว่าแบบอักษร <h1>
จะเปลี่ยนไปใช้แบบอักษรของระบบทันที ซึ่งทำให้ผู้ใช้อ่านได้เร็วขึ้น
บทสรุป
เว็บไซต์ที่ซับซ้อนอาจพบการเปลี่ยนแปลงของเลย์เอาต์มากกว่าในตัวอย่างนี้ แต่กระบวนการแก้ไขยังคงเหมือนเดิม นั่นคือเพิ่มเมตริกความไม่เสถียรของเลย์เอาต์ลงใน WebPageTest, เปรียบเทียบผลลัพธ์ด้วยแถบฟิล์มที่โหลดภาพเพื่อระบุตัวปัญหา และแก้ไขโดยใช้ตัวยึดตำแหน่งเพื่อสงวนพื้นที่ของหน้าจอไว้
(อีกเรื่องหนึ่ง) การวัดความไม่เสถียรของเลย์เอาต์ที่พบจากผู้ใช้จริง
การที่สามารถเรียกใช้ WebPageTest ในหน้าเว็บได้ทั้งก่อนและหลังการเพิ่มประสิทธิภาพและได้เห็นการปรับปรุงเมตริก แต่สิ่งที่สำคัญจริงๆ คือประสบการณ์ของผู้ใช้กำลังดีขึ้นจริงๆ นั่นไม่ใช่สาเหตุที่เราพยายามทำให้เว็บไซต์ดีขึ้นตั้งแต่แรกใช่ไหม
ดังนั้นคงจะดีไม่น้อยหากเราเริ่มวัดประสบการณ์ที่ไม่เสถียรของเลย์เอาต์ของผู้ใช้จริงไปพร้อมๆ กับเมตริกประสิทธิภาพเว็บแบบเดิมของเรา นี่เป็นส่วนสำคัญของลูปความคิดเห็นการเพิ่มประสิทธิภาพ เนื่องจากการมีข้อมูลจากภาคสนามทำให้เราทราบว่าปัญหาอยู่ที่ไหน และการแก้ไขของเราสร้างความแตกต่างในเชิงบวกหรือไม่
นอกจากการรวบรวมข้อมูลความไม่เสถียรของเลย์เอาต์ของคุณเองแล้ว โปรดดูรายงาน UX ของ Chrome ซึ่งมีข้อมูล Cumulative Layout Shift จากประสบการณ์ของผู้ใช้จริงในเว็บไซต์นับล้านแห่ง ซึ่งจะช่วยให้คุณเข้าใจประสิทธิภาพการทำงานของคุณ (หรือคู่แข่ง) หรือใช้ข้อมูลดังกล่าวเพื่อสำรวจสถานการณ์ความไม่เสถียรของเลย์เอาต์ในเว็บต่างๆ ได้