כדאי לנסות את Lighthouse API החדש כדי למדוד את הביצועים ואת השיטות המומלצות לאורך תהליך השימוש.
Lighthouse הוא כלי מצוין לבדיקת הביצועים והשיטות המומלצות במהלך טעינת הדף הראשונית. עם זאת, בעבר היה קשה להשתמש ב-Lighthouse כדי לנתח היבטים אחרים של חיי הדף, כמו:
- טעינות של דפים עם מטמון חם
- דפים עם קובץ שירות (service worker) מופעל
- התייחסות לאינטראקציות אפשריות של משתמשים
כלומר, יכול להיות ש-Lighthouse יפספס מידע חיוני. הנתונים הבסיסיים על חוויית המשתמש (Core Web Vitals) מבוססים על כל הטעינות של הדפים, ולא רק על אלה עם מטמון ריק. בנוסף, מדדים כמו Cumulative Layout Shift (CLS) ניתנים למדידה במשך כל הזמן שבו הדף פתוח.
ב-Lighthouse יש ממשק API חדש של תהליך השימוש שמאפשר בדיקות מעבדה בכל שלב במהלך חיי הדף. Puppeteer משמש לכתיבת סקריפטים לטעינת דפים ולהפעלת אינטראקציות סינתטיות של משתמשים. אפשר להפעיל את Lighthouse בכמה דרכים כדי לתעד תובנות מרכזיות במהלך האינטראקציות האלה. המשמעות היא שאפשר למדוד את הביצועים במהלך טעינת הדף וגם במהלך אינטראקציות עם הדף. אפשר להריץ בדיקות נגישות ב-CI, לא רק בתצוגה הראשונית אלא עמוק בתוך תהליך התשלום, כדי לוודא שלא חלה נסיגה.
עכשיו אפשר להוסיף את Lighthouse כמעט לכל סקריפט של Puppeteer שנכתב כדי לוודא שתהליך השימוש תקין, כדי למדוד את הביצועים ואת השיטות המומלצות לאורך התהליך. במדריך הזה נסביר על המצבים החדשים של Lighthouse שאפשר למדוד בהם חלקים שונים בתהליכי השימוש של המשתמשים: ניווטים, קובצי snapshot ותקופות זמן.
הגדרה
ממשקי ה-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:
- משתמשים ב-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, הדף הזה נטען אחרי שמתבצע ניקוי של כל המטמון או האחסון המקומי, אבל למשתמשים אמיתיים שמבקרים באתר יהיו ביקורים שונים עם מטמון קר ומטמון חם, ויכול להיות הבדל משמעותי בביצועים בין טעינת דף קרה כזו לבין משתמש שחוזרים לדף עם מטמון שעדיין חם.
תיעוד של טעינה במצב ביניים
אפשר גם להוסיף לסקריפט הזה ניווט שני, הפעם עם השבתה של ניקוי המטמון והאחסון ש-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();
דוח התהליך שנוצר נראה בערך כך:
השילוב של עומסי טעינה קרים וחמים מספק תמונה מלאה יותר של החוויה של משתמשים אמיתיים. אם יש לכם אתר שבו משתמשים טוענים הרבה דפים באותו ביקור, הנתון הזה יכול לספק לכם תמונה ריאליסטית יותר של חוויית השימוש שלהם באתר.
תמונת מצב
קובצי snapshot הם מצב חדש שבו מתבצעות בדיקות של Lighthouse בנקודת זמן אחת. בניגוד להרצה רגילה של Lighthouse, הדף לא נטען מחדש. כך תוכלו להגדיר דף ולבדוק אותו במצב המדויק שלו: למשל, עם תפריט נפתח פתוח או טופס שמלא חלקית.
בדוגמה הזו, נניח שאתם רוצים לבדוק שממשק משתמש חדש להגדרות המתקדמות ב-Squoosh עובר את הבדיקות האוטומטיות של Lighthouse. ההגדרות האלה מוצגות רק אם נטענה תמונה ותפריט האפשרויות מורחב כדי להציג את ההגדרות המתקדמות.
אפשר לכתוב סקריפט לתהליך הזה באמצעות Puppeteer, ואפשר גם לצלם קובץ snapshot של 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 יעלה.
הסקריפט הבא ייצור דוח של תהליך השימוש של המשתמשים עם שתי הפעולות, כדי להראות את ההבדל.
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. אתר מצוין!
עם זאת, בשלב 'ניווט וגלילה' התמונה שונה. בשלב הזה, רק 'סה"כ זמן חסימה' ו'הזזות מצטברות בפריסת הדף' זמינים בטווחי זמן, אבל ברור שהתוכן שנטען באיטרציה בדף הזה גורם לירידה חדה ב-CLS של האתר.
בעבר, מערכת Lighthouse לא הייתה יכולה לזהות את ההתנהגות הבעייתית הזו של CLS, אבל היא הייתה כמעט בוודאות מופיעה בחוויית השימוש של משתמשים אמיתיים. בדיקות ביצועים של אינטראקציות לפי סקריפט משפרות באופן משמעותי את הדיוק של בדיקות המעבדה.
מבקשים משוב
ממשקי ה-API החדשים של תהליך השימוש ב-Lighthouse יכולים לבצע פעולות רבות חדשות, אבל עדיין יכול להיות שיהיה קשה למדוד את הסוגים של התרחישים שבהם המשתמשים נתקלים.
בכל שאלה, אפשר לפנות אלינו בפורומים לדיון של Lighthouse, ולדווח על באגים או הצעות בכלי למעקב אחר בעיות.