תהליכי העבודה ב-Lighthouse

כדאי לנסות את Lighthouse API החדש כדי למדוד את הביצועים ואת השיטות המומלצות לכל אורך התהליך של המשתמשים.

ברנדן קני
ברנדן קני

Lighthouse הוא כלי מצוין לבדיקת ביצועים ושיטות מומלצות במהלך הטעינה הראשונית של הדף. עם זאת, בעבר היה קשה להשתמש ב-Lighthouse כדי לנתח היבטים אחרים בחיי הדף, למשל:

  • הדף נטען עם מטמון חם
  • דפים עם Service Worker מופעל
  • התייחסות לאינטראקציות פוטנציאליות של משתמשים

לכן, מערכת Lighthouse עשויה לפספס מידע חיוני. מדדי הליבה לבדיקת חוויית המשתמש באתר מבוססים על כל טעינות הדפים, לא רק על אלה שהמטמון שלהם ריק. בנוסף, אפשר למדוד מדדים כמו Cumulative Layout Shift (CLS) במשך כל התקופה שבה דף פתוח.

ב-Lighthouse יש API חדש לניהול של תהליכי משתמשים שמאפשר לבצע בדיקות Lab בכל שלב במהלך משך החיים של הדף. Puppeteer משמש לסקריפטים של טעינות דפים ולהפעלת אינטראקציות סינתטיות של משתמשים. אפשר להפעיל את Lighthouse בכמה דרכים כדי לתעד תובנות חשובות במהלך האינטראקציות האלה. המשמעות היא שאפשר למדוד את הביצועים גם במהלך טעינת דף וגם במהלך אינטראקציות עם הדף. אפשר להריץ בדיקות נגישות ב-CI, לא רק בתצוגה הראשונית, אלא גם עמוק בתוך תהליך התשלום, כדי לוודא ששום דבר לא חוזר על עצמו.

עכשיו אפשר להוסיף את Lighthouse בכל שלב כדי למדוד את הביצועים והשיטות המומלצות לאורך כל העבודה, ונכתב כמעט כל סקריפט של Puppeteer כדי להבטיח תהליך עבודה פעיל של משתמשים. במדריך הזה מפורטות המצבים החדשים של Lighthouse שבאמצעותם אפשר למדוד חלקים שונים בתהליכי העבודה של המשתמשים: ניווטים, תמונות מצב ופרקי זמן.

הגדרה

ממשקי ה-API של מסלול המשתמש עדיין נמצאים בתצוגה מקדימה, אבל הם זמינים ב-Lighthouse היום. כדי לנסות את ההדגמות שלמטה, צריך להשתמש ב-Node בגרסה 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: ניתוח הטעינה הקרה של דף. זו המצב שאפשר להשתמש בו כדי לעקוב אחרי ביצועי טעינת דפים, אבל תהליכי העבודה של המשתמשים גם פותחים את האפשרות לקבל תובנות חדשות.

כדי ליצור סקריפט מ-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 start) לבין משתמש שחוזר לדף עם מטמון עדיין חם.

לכידת עומס חם

ניתן גם להוסיף לסקריפט הזה גם ניווט נוסף, הפעם להשבית את ניקוי המטמון והאחסון ש-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 שבו מוצגים שני מסלולי ניווט, אחד קר והשני חם, בעל ציון ביצועים גבוה יותר
הצגת הדוח בזמן אמת

השילוב של עומסים קרים וחמימים מספק תמונה מלאה יותר לגבי החוויה של משתמשים אמיתיים. אם יש לכם אתר שבו המשתמשים טוענים דפים רבים באותו ביקור, ייתכן שתוכלו לראות באופן מציאותי יותר את מה שהם חווים בשטח הזה.

Snapshots

קובצי snapshot הם מצב חדש שבו מתבצעות ביקורות של Lighthouse בנקודת זמן מסוימת. בשונה מהרצה רגילה של Lighthouse, הדף לא נטען מחדש. כך אין אפשרות להגדיר דף ולבדוק אותו במצבו המדויק: עם תפריט נפתח פתוח או מילוי חלקי של טופס, לדוגמה.

בדוגמה הזו, נניח שאתם רוצים לבדוק שממשק משתמש חדש להגדרות המתקדמות ב-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) לבין שיעור ה-Lab (כמו Lighthouse) הוא היעדר קלט של משתמשים. כאן אפשר למצוא את טווח הזמן – מצב הזרימה האחרון של המשתמש.

במשך תקופת זמן מסוימת פועלות ביקורות של Lighthouse לאורך תקופה מסוימת, וייתכן שהן יכללו ניווט. זוהי דרך מצוינת לתעד את מה שקורה בדף במהלך אינטראקציות. לדוגמה: כברירת מחדל, מערכת Lighthouse מודדת CLS במהלך טעינת דף, אבל בשדה הזה, מדד ה-CLS נמדד החל מהניווט הראשוני עד לסגירת הדף. אם אינטראקציות של משתמשים הן הגורם שמפעיל את ה-CLS, בעבר לא ניתן היה לאתר את הבעיה בעזרת Lighthouse ולעזור לפתור אותה.

כדי להדגים את זה, תוכלו להיעזר באתר בדיקה שמדמה מודעות מוחדרות לכתבה במהלך הגלילה בלי ששמור להן מקום. בסדרה ארוכה של כרטיסים, מתווסף מדי פעם ריבוע אדום כשהמשבצת שלו נכנסת לאזור התצוגה. מכיוון שלא נותר מקום לריבועים האדומים האלה, הכרטיסים שתחתיהם מזיזים הצידה, וכתוצאה מכך הפריסה משתנה.

ערך CLS של ניווט רגיל ב-Lighthouse יהיה 0. עם זאת, לאחר גלילה, יהיו שינויים בעייתיים בפריסה של הדף וערך ה-CLS יעלה.

להתנסות באתר ההדגמה

הסקריפט הבא יפיק דוח של זרימת המשתמש עם שתי הפעולות, כדי להציג את ההבדל.

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 עוסק רק בניווט בדפים עם כל המדדים הירוקים

עם זאת, השלב 'ניווט וגלילה' מספר סיפור שונה. בשלב זה רק 'זמן חסימה כולל' ו'שינוי פריסה מצטבר' זמינים בטווחי זמן, אבל התוכן שנטען בעצלנות בדף הזה תומך בבירור ב-CLS של האתר.

דוח Lighthouse כולל דיווח על ניווט וגלילה בדפים עם CLS שנכשלו

בעבר, ב-Lighthouse לא הייתה אפשרות לזהות את התנהגות ה-CLS הבעייתית הזו, אם כי כמעט ודאי ניתן היה לראות אותה גם אצל משתמשים אמיתיים. בדיקת ביצועים של אינטראקציות באמצעות סקריפטים משפרת משמעותית את איכות שיעור ה-Lab.

מחפשים משוב

ממשקי ה-API החדשים של זרימת המשתמשים ב-Lighthouse יכולים לעשות הרבה דברים חדשים, אבל עדיין יכול להיות קשה למדוד את סוגי התרחישים שהמשתמשים נתקלים בהם.

אתם יכולים לפנות אלינו אם יש לכם שאלות בפורומי הדיונים של Lighthouse, ולדווח על באגים או הצעות באתר המעקב אחר בעיות.