ลองใช้ Lighthouse API ใหม่เพื่อวัดประสิทธิภาพและแนวทางปฏิบัติแนะนำตลอดทุกขั้นตอนการใช้งานของผู้ใช้
Lighthouse คือเครื่องมือที่ยอดเยี่ยมสำหรับการทดสอบประสิทธิภาพและแนวทางปฏิบัติแนะนำระหว่างการโหลดหน้าเว็บเริ่มต้น แต่เดิมที การใช้ Lighthouse เพื่อวิเคราะห์แง่มุมอื่นๆ ในชีวิตของหน้าเว็บมักจะเป็นเรื่องยาก เช่น
- การโหลดหน้าเว็บด้วยแคชที่อุ่นเครื่อง
- หน้าเว็บที่มี Service Worker เปิดใช้งานอยู่
- การพิจารณาการโต้ตอบที่อาจเกิดขึ้นกับผู้ใช้
ซึ่งหมายความว่า Lighthouse อาจพลาดข้อมูลสำคัญ Core Web Vitals อิงตามการโหลดหน้าเว็บทั้งหมด ไม่ใช่เฉพาะรายการที่มีแคชว่างเปล่า นอกจากนี้ เมตริกอย่างเช่น Cumulative Layout Shift (CLS) จะวัดได้ตลอดช่วงเวลาที่เปิดหน้าเว็บ
Lighthouse มี API การไหลเวียนของผู้ใช้ใหม่ที่ช่วยให้ทำการทดสอบในห้องทดลองได้ทุกเมื่อภายในช่วงอายุการใช้งานของหน้าเว็บ Puppeteer ใช้เพื่อเขียนสคริปต์การโหลดหน้าเว็บและทริกเกอร์การโต้ตอบของผู้ใช้แบบสังเคราะห์ นอกจากนี้ คุณยังเรียกใช้ Lighthouse ได้หลายวิธีเพื่อบันทึกข้อมูลเชิงลึกที่สำคัญระหว่างการโต้ตอบเหล่านั้น ซึ่งหมายความว่าระบบจะวัดประสิทธิภาพได้ระหว่างการโหลดหน้าเว็บและระหว่างการโต้ตอบกับหน้าเว็บ การตรวจสอบการช่วยเหลือพิเศษสามารถทำงานใน CI ไม่ใช่แค่ในมุมมองเริ่มต้น แต่ทำในขั้นตอนการชำระเงินเพื่อให้แน่ใจว่าไม่มีการถดถอย
สคริปต์ Puppeteer เกือบทุกรายการที่เขียนขึ้นเพื่อให้มั่นใจว่าผู้ใช้ที่ใช้งานอยู่จะแทรก Lighthouse ได้ทุกเมื่อเพื่อวัดประสิทธิภาพและแนวทางปฏิบัติแนะนำทั้งหมด บทแนะนำนี้จะอธิบายถึงโหมดใหม่ของ Lighthouse ที่สามารถวัดการไหลเวียนของผู้ใช้ในส่วนต่างๆ ได้แก่ การไปยังส่วนต่างๆ สแนปชอต และระยะเวลา
การตั้งค่า
API การไหลเวียนของผู้ใช้ยังอยู่ในช่วงพรีวิว แต่ปัจจุบันมีให้บริการใน Lighthouse แล้ว คุณต้องใช้โหนดเวอร์ชัน 14 ขึ้นไปจึงจะลองใช้การสาธิตด้านล่างได้ สร้างไดเรกทอรีเปล่าแล้วเรียกใช้:
# Default to ES modules.
echo '{"type": "module"}' > package.json
# Init npm project without the wizard.
npm init -y
# Dependencies for these examples.
npm install lighthouse puppeteer open
การนำทาง
โหมด "การนำทาง" ใหม่ของ Lighthouse จริงๆ แล้วตั้งชื่อให้กับลักษณะการทำงานมาตรฐานของ Lighthouse (จนถึงปัจจุบัน) นั่นคือวิเคราะห์ Cold Load ของหน้าเว็บ นี่คือโหมดที่ใช้เพื่อตรวจสอบประสิทธิภาพการโหลดหน้าเว็บ แต่การไหลเวียนของผู้ใช้ก็เปิดโอกาสให้ข้อมูลเชิงลึกใหม่ๆ ได้เช่นกัน
หากต้องการเขียนสคริปต์ Lighthouse เพื่อบันทึกการโหลดหน้าเว็บ ให้ทำดังนี้
- ใช้ puppeteer เพื่อเปิดเบราว์เซอร์
- เริ่มโฟลว์ผู้ใช้ Lighthouse
- นำทางไปยัง URL เป้าหมาย
import fs from 'fs';
import open from 'open';
import puppeteer from 'puppeteer';
import {startFlow} from 'lighthouse/lighthouse-core/fraggle-rock/api.js';
async function captureReport() {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
const flow = await startFlow(page, {name: 'Single Navigation'});
await flow.navigate('https://web.dev/performance-scoring/');
await browser.close();
const report = await flow.generateReport();
fs.writeFileSync('flow.report.html', report);
open('flow.report.html', {wait: false});
}
captureReport();
นี่เป็นขั้นตอนที่ง่ายที่สุด เมื่อเปิด รายงานจะแสดงมุมมองสรุปที่มีเพียงขั้นตอนเดียว การคลิกที่ขั้นตอนจะแสดงรายงาน Lighthouse แบบดั้งเดิมสำหรับการนำทางนั้น
และเช่นเดียวกับ Lighthouse ตามปกติ หน้านี้จะโหลดโดยล้างแคชหรือพื้นที่เก็บข้อมูลในเครื่องก่อน แต่ผู้ใช้จริงที่เข้าชมเว็บไซต์จะมีทั้งการเข้าชมที่มีแคชและแคชอุ่น และอาจมีความแตกต่างด้านประสิทธิภาพอย่างมากระหว่างการโหลดแบบ Cold กับแบบนี้และผู้ใช้กลับมายังหน้าโดยมีแคชที่ยังอุ่นเครื่องอยู่
กำลังบันทึกการเริ่มทำงาน
คุณสามารถเพิ่มการนำทางที่ 2 ลงในสคริปต์นี้ได้ด้วย โดยครั้งนี้จะปิดใช้การล้างแคชและพื้นที่เก็บข้อมูลซึ่ง Lighthouse ทำโดยค่าเริ่มต้นในการนำทาง ตัวอย่างถัดไปนี้โหลดบทความที่ web.dev เพื่อดูประโยชน์ที่ได้จากการแคช
async function captureReport() {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
const testUrl = 'https://web.dev/performance-scoring/';
const flow = await startFlow(page, {name: 'Cold and warm navigations'});
await flow.navigate(testUrl, {
stepName: 'Cold navigation'
});
await flow.navigate(testUrl, {
stepName: 'Warm navigation',
configContext: {
settingsOverrides: {disableStorageReset: true},
},
});
await browser.close();
const report = await flow.generateReport();
fs.writeFileSync('flow.report.html', report);
open('flow.report.html', {wait: false});
}
captureReport();
รายงานโฟลว์ที่ได้จะมีลักษณะประมาณนี้
ชุดค่าผสมของระหว่าง Cold Load และ Warm Load จะช่วยให้เห็นภาพได้ครอบคลุมยิ่งขึ้นเกี่ยวกับประสบการณ์ของผู้ใช้จริง หากคุณมีเว็บไซต์ที่ผู้ใช้โหลดหน้าเว็บหลายหน้าในการเข้าชมเดียวกัน เว็บไซต์นี้อาจช่วยให้คุณเห็นว่าผู้ใช้กำลังประสบกับการทำงานอะไรอยู่บ้าง
สแนปชอต
สแนปชอตเป็นโหมดใหม่ที่เรียกใช้การตรวจสอบ Lighthouse ณ เวลาหนึ่งๆ หน้าเว็บจะไม่โหลดซ้ำ ซึ่งต่างจากการเรียกใช้ Lighthouse ตามปกติ การทำเช่นนี้จะปลดล็อกความสามารถในการตั้งค่าหน้าเว็บและทดสอบในสถานะที่แน่นอน เช่น เมื่อมีการเปิดเมนูแบบเลื่อนลงอยู่ หรือกรอกข้อมูลในแบบฟอร์มบางส่วน
ในตัวอย่างนี้ สมมติว่าคุณต้องการตรวจสอบว่า UI ใหม่บางรายการสำหรับการตั้งค่าขั้นสูงภายใน Squoosh ผ่านการตรวจสอบ Lighthouse อัตโนมัติแล้ว การตั้งค่าเหล่านี้จะปรากฏก็ต่อเมื่อโหลดรูปภาพแล้ว และเมนูตัวเลือกจะขยายออกเพื่อแสดงการตั้งค่าขั้นสูง
ขั้นตอนนี้ใช้สคริปต์ได้ด้วย Puppeteer ซึ่งคุณสามารถถ่ายสแนปชอตของ Lighthouse ในแต่ละขั้นตอนได้
async function captureReport() {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
const flow = await startFlow(page, {name: 'Squoosh snapshots'});
await page.goto('https://squoosh.app/', {waitUntil: 'networkidle0'});
// Wait for first demo-image button, then open it.
const demoImageSelector = 'ul[class*="demos"] button';
await page.waitForSelector(demoImageSelector);
await flow.snapshot({stepName: 'Page loaded'});
await page.click(demoImageSelector);
// Wait for advanced settings button in UI, then open them.
const advancedSettingsSelector = 'form label[class*="option-reveal"]';
await page.waitForSelector(advancedSettingsSelector);
await flow.snapshot({stepName: 'Demo loaded'});
await page.click(advancedSettingsSelector);
await flow.snapshot({stepName: 'Advanced settings opened'});
browser.close();
const report = await flow.generateReport();
fs.writeFileSync('flow.report.html', report);
open('flow.report.html', {wait: false});
}
captureReport();
รายงานที่แสดงผลแสดงให้เห็นว่าโดยทั่วไปผลลัพธ์จะดี แต่อาจมีเกณฑ์การช่วยเหลือพิเศษบางอย่างที่คุณต้องตรวจสอบด้วยตนเอง ดังนี้
ช่วงเวลา
ความแตกต่างที่สำคัญที่สุดระหว่างผลลัพธ์ด้านประสิทธิภาพในภาคสนาม (เช่น จาก CrUX) และในห้องทดลอง (เช่น จาก Lighthouse) คือการขาดข้อมูลจากผู้ใช้ นี่เป็นส่วนที่ช่วงเวลา (โหมดการไหลเวียนของผู้ใช้ล่าสุด) สามารถช่วยได้
ช่วงเวลาหนึ่งๆ จะทำการตรวจสอบ Lighthouse ในช่วงระยะเวลาหนึ่ง ซึ่งอาจรวมถึงการไปยังส่วนต่างๆ หรือไม่ก็ได้ นี่เป็นวิธีที่ยอดเยี่ยมในการจับภาพสิ่งที่เกิดขึ้นกับหน้าเว็บระหว่างการโต้ตอบ เช่น โดยค่าเริ่มต้น Lighthouse จะวัด CLS ระหว่างการโหลดหน้าเว็บ แต่ในพื้นที่ดังกล่าว ระบบจะวัด CLS จากการนําทางครั้งแรกจนกว่าหน้าเว็บจะปิดลง หากการโต้ตอบของผู้ใช้เป็นทริกเกอร์ของ CLS โปรดทราบว่าก่อนหน้านี้ Lighthouse จะไม่สามารถตรวจจับและช่วยแก้ปัญหาได้
ลองดูตัวอย่างจากเว็บไซต์ทดสอบที่จำลองโฆษณาซึ่งแทรกเข้ามาในบทความระหว่างการเลื่อนโดยไม่ได้จองพื้นที่ไว้ให้ ในชุดการ์ดขนาดยาว ระบบจะเพิ่มสี่เหลี่ยมจัตุรัสสีแดงเป็นครั้งคราวเมื่อช่องของการ์ดเข้ามาในวิวพอร์ต เนื่องจากไม่ได้มีการสงวนพื้นที่ไว้สำหรับสี่เหลี่ยมจัตุรัสสีแดงเหล่านี้ การ์ดที่อยู่ด้านล่างจึงเลื่อนออกไป ทำให้เลย์เอาต์เปลี่ยนแปลง
การนำทางปกติของ Lighthouse จะมี CLS เป็น 0 อย่างไรก็ตาม เมื่อเลื่อนแล้ว หน้าเว็บจะมีการเปลี่ยนเลย์เอาต์ที่เป็นปัญหา และค่า CLS จะเพิ่มขึ้น
สคริปต์ต่อไปนี้จะสร้างรายงานการไหลเวียนของผู้ใช้ซึ่งมีการดำเนินการทั้ง 2 อย่างเพื่อแสดงความแตกต่าง
async function captureReport() {
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
// Get a session handle to be able to send protocol commands to the page.
const session = await page.target().createCDPSession();
const testUrl = 'https://pie-charmed-treatment.glitch.me/';
const flow = await startFlow(page, {name: 'CLS during navigation and on scroll'});
// Regular Lighthouse navigation.
await flow.navigate(testUrl, {stepName: 'Navigate only'});
// Navigate and scroll timespan.
await flow.startTimespan({stepName: 'Navigate and scroll'});
await page.goto(testUrl, {waitUntil: 'networkidle0'});
// We need the ability to scroll like a user. There's not a direct puppeteer function for this, but we can use the DevTools Protocol and issue a Input.synthesizeScrollGesture event, which has convenient parameters like repetitions and delay to somewhat simulate a more natural scrolling gesture.
// https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-synthesizeScrollGesture
await session.send('Input.synthesizeScrollGesture', {
x: 100,
y: 600,
yDistance: -2500,
speed: 1000,
repeatCount: 2,
repeatDelayMs: 250,
});
await flow.endTimespan();
await browser.close();
const report = await flow.generateReport();
fs.writeFileSync('flow.report.html', report);
open('flow.report.html', {wait: false});
}
captureReport();
วิธีนี้จะสร้างรายงานที่เปรียบเทียบการไปยังส่วนต่างๆ ตามปกติกับช่วงเวลาที่มีทั้งการไปยังส่วนต่างๆ และการเลื่อนหลังจากนั้น ดังนี้
เมื่อเจาะลึกในแต่ละขั้นตอนแล้ว ขั้นตอนสำหรับการนำทางเท่านั้นจะแสดง CLS เป็น 0 เว็บไซต์ดีเยี่ยม!
แต่ขั้นตอน "ไปยังส่วนต่างๆ และเลื่อน" จะบอกเล่าเรื่องราวที่แตกต่างกัน ขณะนี้มีเพียง "เวลาในการบล็อกทั้งหมด" และ Cumulative Layout Shift เท่านั้นที่พร้อมใช้งานในช่วงเวลา แต่เนื้อหาที่โหลดแบบ Lazy Loading ในหน้านี้จะมี CLS ของเว็บไซต์อย่างชัดเจน
ก่อนหน้านี้ Lighthouse จะระบุลักษณะการทำงานของ CLS ที่เป็นปัญหานี้ไม่ได้ แต่จะแสดงให้เห็นในประสบการณ์ของผู้ใช้จริงแทบจะอย่างแน่นอน การทดสอบประสิทธิภาพกับการโต้ตอบที่มีสคริปต์ช่วยปรับปรุงความแม่นยำของห้องทดลองได้อย่างมาก
ต้องการความคิดเห็น
API การไหลเวียนของผู้ใช้แบบใหม่ใน Lighthouse สามารถทำสิ่งต่างๆ ใหม่ได้มากมาย แต่การวัดสถานการณ์ที่ผู้ใช้พบอาจทำได้ยาก
หากมีคำถามหรือคำถามใดๆ ในฟอรัมแลกเปลี่ยนความเห็นของ Lighthouse ก็แจ้งข้อบกพร่องหรือคำแนะนำในเครื่องมือติดตามปัญหาได้