โฟลว์ของผู้ใช้ Lighthouse

ลองใช้ Lighthouse API ใหม่เพื่อวัดประสิทธิภาพและแนวทางปฏิบัติแนะนำตลอดทุกขั้นตอนการใช้งานของผู้ใช้

เบรนแดน เคนนี
Brendan Kenny

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 เพื่อบันทึกการโหลดหน้าเว็บ ให้ทำดังนี้

  1. ใช้ puppeteer เพื่อเปิดเบราว์เซอร์
  2. เริ่มโฟลว์ผู้ใช้ Lighthouse
  3. นำทางไปยัง 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 ที่แสดงการนําทางเดียว
ดูรายงานแบบเรียลไทม์

และเช่นเดียวกับ 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();

รายงานโฟลว์ที่ได้จะมีลักษณะประมาณนี้

รายงานโฟลว์ของ Lighthouse แสดงการนําทาง 2 รายการ โดยรายการหนึ่งเป็นแบบเย็นและอบอุ่น 1 รายการ ซึ่งมีคะแนนประสิทธิภาพสูงกว่า
ดูรายงานแบบเรียลไทม์

ชุดค่าผสมของระหว่าง Cold Load และ Warm Load จะช่วยให้เห็นภาพได้ครอบคลุมยิ่งขึ้นเกี่ยวกับประสบการณ์ของผู้ใช้จริง หากคุณมีเว็บไซต์ที่ผู้ใช้โหลดหน้าเว็บหลายหน้าในการเข้าชมเดียวกัน เว็บไซต์นี้อาจช่วยให้คุณเห็นว่าผู้ใช้กำลังประสบกับการทำงานอะไรอยู่บ้าง

สแนปชอต

สแนปชอตเป็นโหมดใหม่ที่เรียกใช้การตรวจสอบ Lighthouse ณ เวลาหนึ่งๆ หน้าเว็บจะไม่โหลดซ้ำ ซึ่งต่างจากการเรียกใช้ Lighthouse ตามปกติ การทำเช่นนี้จะปลดล็อกความสามารถในการตั้งค่าหน้าเว็บและทดสอบในสถานะที่แน่นอน เช่น เมื่อมีการเปิดเมนูแบบเลื่อนลงอยู่ หรือกรอกข้อมูลในแบบฟอร์มบางส่วน

ในตัวอย่างนี้ สมมติว่าคุณต้องการตรวจสอบว่า UI ใหม่บางรายการสำหรับการตั้งค่าขั้นสูงภายใน Squoosh ผ่านการตรวจสอบ Lighthouse อัตโนมัติแล้ว การตั้งค่าเหล่านี้จะปรากฏก็ต่อเมื่อโหลดรูปภาพแล้ว และเมนูตัวเลือกจะขยายออกเพื่อแสดงการตั้งค่าขั้นสูง

เมนูการตั้งค่าขั้นสูงของ Squoosh
เมนูการตั้งค่าขั้นสูงของ Squoosh

ขั้นตอนนี้ใช้สคริปต์ได้ด้วย 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();

รายงานที่แสดงผลแสดงให้เห็นว่าโดยทั่วไปผลลัพธ์จะดี แต่อาจมีเกณฑ์การช่วยเหลือพิเศษบางอย่างที่คุณต้องตรวจสอบด้วยตนเอง ดังนี้

รายงานโฟลว์ของ Lighthouse ที่แสดงชุดสแนปชอตที่ถ่าย
ดูรายงานแบบเรียลไทม์

ช่วงเวลา

ความแตกต่างที่สำคัญที่สุดระหว่างผลลัพธ์ด้านประสิทธิภาพในภาคสนาม (เช่น จาก 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();

วิธีนี้จะสร้างรายงานที่เปรียบเทียบการไปยังส่วนต่างๆ ตามปกติกับช่วงเวลาที่มีทั้งการไปยังส่วนต่างๆ และการเลื่อนหลังจากนั้น ดังนี้

รายงานโฟลว์ของ Lighthouse ที่แสดงชุดสแนปชอตที่ถ่าย
ดูรายงานแบบเรียลไทม์

เมื่อเจาะลึกในแต่ละขั้นตอนแล้ว ขั้นตอนสำหรับการนำทางเท่านั้นจะแสดง CLS เป็น 0 เว็บไซต์ดีเยี่ยม!

รายงาน Lighthouse ที่ครอบคลุมเฉพาะการไปยังส่วนต่างๆ ในหน้าเว็บซึ่งมีเมตริกสีเขียวทั้งหมด

แต่ขั้นตอน "ไปยังส่วนต่างๆ และเลื่อน" จะบอกเล่าเรื่องราวที่แตกต่างกัน ขณะนี้มีเพียง "เวลาในการบล็อกทั้งหมด" และ Cumulative Layout Shift เท่านั้นที่พร้อมใช้งานในช่วงเวลา แต่เนื้อหาที่โหลดแบบ Lazy Loading ในหน้านี้จะมี CLS ของเว็บไซต์อย่างชัดเจน

รายงาน Lighthouse ที่ครอบคลุมการไปยังส่วนต่างๆ ในหน้าเว็บและการเลื่อนด้วย CLS ที่ล้มเหลว

ก่อนหน้านี้ Lighthouse จะระบุลักษณะการทำงานของ CLS ที่เป็นปัญหานี้ไม่ได้ แต่จะแสดงให้เห็นในประสบการณ์ของผู้ใช้จริงแทบจะอย่างแน่นอน การทดสอบประสิทธิภาพกับการโต้ตอบที่มีสคริปต์ช่วยปรับปรุงความแม่นยำของห้องทดลองได้อย่างมาก

ต้องการความคิดเห็น

API การไหลเวียนของผู้ใช้แบบใหม่ใน Lighthouse สามารถทำสิ่งต่างๆ ใหม่ได้มากมาย แต่การวัดสถานการณ์ที่ผู้ใช้พบอาจทำได้ยาก

หากมีคำถามหรือคำถามใดๆ ในฟอรัมแลกเปลี่ยนความเห็นของ Lighthouse ก็แจ้งข้อบกพร่องหรือคำแนะนำในเครื่องมือติดตามปัญหาได้