Luồng người dùng bằng Lighthouse

Dùng thử một API Lighthouse mới để đo lường hiệu suất và các phương pháp hay nhất trong suốt luồng người dùng.

Brendan Kenny
Brendan Kenny

Lighthouse là một công cụ tuyệt vời để kiểm tra hiệu suất và các phương pháp hay nhất trong quá trình tải trang ban đầu. Tuy nhiên, thường rất khó để sử dụng Lighthouse để phân tích các khía cạnh khác trong quá trình hoạt động của một trang, chẳng hạn như:

  • Tải trang bằng bộ nhớ đệm ấm
  • Các trang có Trình chạy dịch vụ đã kích hoạt
  • Tính đến các lượt tương tác tiềm năng của người dùng

Điều này có nghĩa là Lighthouse có thể bỏ lỡ thông tin quan trọng. Các chỉ số quan trọng về trang web được tính dựa trên tất cả lượt tải trang, chứ không chỉ những trang có bộ nhớ đệm trống. Ngoài ra, các chỉ số như Điểm số tổng hợp về mức thay đổi bố cục (CLS) có thể đo lường được trong toàn bộ thời gian mở một trang.

Lighthouse có một API luồng người dùng mới cho phép kiểm thử trong phòng thí nghiệm bất cứ lúc nào trong thời gian hoạt động của trang. Puppeteer được dùng để tập lệnh tải trang và kích hoạt các lượt tương tác tổng hợp của người dùng. Bạn cũng có thể gọi Lighthouse theo nhiều cách để thu thập thông tin chi tiết chính trong các hoạt động tương tác đó. Điều này có nghĩa là hiệu suất có thể được đo lường trong quá trình tải trang trong các lượt tương tác với trang. Bạn có thể chạy các bước kiểm tra khả năng hỗ trợ tiếp cận trong CI, không chỉ trong chế độ xem ban đầu mà còn đi sâu trong quy trình thanh toán để đảm bảo không có gì bị hồi quy.

Giờ đây, hầu hết tập lệnh Puppeteer được viết để đảm bảo luồng người dùng hoạt động đều có thể chèn Lighthouse bất cứ lúc nào để đo lường hiệu suất và các phương pháp hay nhất một cách xuyên suốt. Hướng dẫn này sẽ giới thiệu các chế độ mới của Lighthouse có thể đo lường các phần khác nhau trong luồng của người dùng: thao tác điều hướng, ảnh chụp nhanh và khoảng thời gian.

Thiết lập

Các API luồng người dùng vẫn đang ở giai đoạn xem trước nhưng hiện đã có trong Lighthouse. Để dùng thử các bản minh hoạ bên dưới, bạn cần có Nút phiên bản 14 trở lên. Tạo một thư mục trống và trong thư mục đó sẽ chạy:

# 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

Tính năng "navigation" mới của Lighthouse thực ra là đặt tên cho hành vi tiêu chuẩn của Lighthouse (cho đến nay): phân tích tải nguội của trang. Đây là chế độ dùng để theo dõi hiệu suất tải trang, nhưng luồng người dùng cũng cho phép bạn xem thông tin chi tiết mới.

Cách tập lệnh Lighthouse ghi lại lượt tải trang:

  1. Sử dụng nghệ thuật múa rối để mở trình duyệt.
  2. Bắt đầu luồng người dùng Lighthouse.
  3. Chuyển đến URL mục tiêu.
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();

Đây là quy trình đơn giản nhất. Khi được mở, báo cáo sẽ hiển thị chế độ xem tóm tắt chỉ có một bước duy nhất. Nhấp vào bước đó sẽ hiển thị báo cáo Lighthouse truyền thống cho điều hướng đó.

Báo cáo luồng Lighthouse cho thấy một thao tác điều hướng
Xem báo cáo trực tiếp

Như thường lệ với Lighthouse, trước tiên, trang này được tải với mọi bộ nhớ đệm hoặc bộ nhớ cục bộ đã bị xoá. Tuy nhiên, những người dùng thực truy cập vào một trang web sẽ có kết hợp lượt truy cập với bộ nhớ đệm ấm và bộ nhớ đệm lạnh. Ngoài ra, có thể có sự khác biệt lớn về hiệu suất giữa quá trình tải nguội như thế này và việc người dùng quay lại trang có bộ nhớ đệm ấm vẫn còn.

Đang thực hiện quá trình tải ấm

Bạn cũng có thể thêm điều hướng thứ hai vào tập lệnh này, lần này tắt tính năng xóa bộ nhớ đệm và bộ nhớ mà Lighthouse thực hiện theo mặc định trong điều hướng. Ví dụ tiếp theo sau đây sẽ tải một bài viết trên chính web.dev để xem bài viết này được hưởng lợi bao nhiêu từ việc lưu vào bộ nhớ đệm:

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();

Báo cáo luồng thu được sẽ có dạng như sau:

Báo cáo luồng Lighthouse cho thấy hai chế độ điều hướng, một thao tác nguội và một thao tác ấm, có điểm hiệu suất cao hơn
Xem báo cáo trực tiếp

Sự kết hợp giữa tải nguội và tải ấm mang đến một bức tranh toàn diện hơn về những gì người dùng thực tế đang trải nghiệm. Nếu bạn có trang web mà người dùng tải nhiều trang trong cùng một lượt truy cập, thì việc này có thể mang đến cho bạn cái nhìn thực tế hơn về những gì họ đang trải nghiệm trong hiện trường.

Tổng quan nhanh

Bản tổng quan nhanh là một chế độ mới chạy các lượt kiểm tra Lighthouse tại một thời điểm duy nhất. Không giống như cách chạy Lighthouse thông thường, trang không được tải lại. Tính năng này cho phép bạn thiết lập một trang và kiểm tra trang đó ở trạng thái chính xác: ví dụ: với một trình đơn thả xuống đang mở hoặc một biểu mẫu được điền một phần.

Trong ví dụ này, giả sử bạn muốn kiểm tra xem một số giao diện người dùng mới cho các chế độ Cài đặt nâng cao trong Squoosh có vượt qua các bước kiểm tra tự động của Lighthouse hay không. Các chế độ cài đặt này chỉ xuất hiện nếu hình ảnh đã được tải và trình đơn tuỳ chọn được mở rộng để cho thấy các chế độ cài đặt nâng cao.

Trình đơn cài đặt nâng cao Squoosh
Trình đơn cài đặt nâng cao của Squoosh

Quy trình này có thể viết tập lệnh bằng Puppeteer và bạn thực sự có thể chụp ảnh nhanh Lighthouse ở mỗi bước:

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();

Báo cáo kết quả cho thấy rằng các kết quả thường tốt, nhưng có thể có một số tiêu chí về khả năng hỗ trợ tiếp cận cần được kiểm tra theo cách thủ công:

Báo cáo luồng Lighthouse cho thấy một tập hợp các ảnh chụp nhanh được chụp
Xem báo cáo trực tiếp

Khoảng thời gian

Một trong những điểm khác biệt lớn nhất giữa kết quả về hiệu suất trong thực tế (chẳng hạn như từ CrUX) và trong phòng thí nghiệm (chẳng hạn như từ Lighthouse) là thiếu hoạt động đầu vào của người dùng. Đây là trường hợp khoảng thời gian (chế độ luồng người dùng gần đây nhất) có thể hữu ích.

Quá trình kiểm tra Lighthouse sẽ diễn ra trong một khoảng thời gian, có thể bao gồm hoặc không bao gồm hoạt động điều hướng. Đây là một cách tuyệt vời để ghi lại những gì đang xảy ra trên một trang trong các lượt tương tác. Ví dụ: theo mặc định, Lighthouse đo lường CLS (Mức thay đổi bố cục tích luỹ) trong quá trình tải trang, nhưng trong thực tế, CLS (Mức thay đổi bố cục tích luỹ) được đo lường từ thời điểm điều hướng ban đầu cho đến khi trang đóng lại. Nếu hoạt động tương tác của người dùng là yếu tố kích hoạt CLS, thì đây là điều mà trước đây Lighthouse không thể phát hiện và giúp khắc phục.

Để chứng minh điều này, sau đây là một trang web thử nghiệm mô phỏng quảng cáo được chèn vào một bài viết trong quá trình cuộn mà không có khoảng trống dành riêng cho chúng. Trong một loạt các thẻ dài, thỉnh thoảng một hình vuông màu đỏ sẽ xuất hiện khi vị trí của thẻ đó xuất hiện trong khung nhìn. Vì không gian không được dành riêng cho các hình vuông màu đỏ này, nên các thẻ bên dưới bị dịch chuyển ra ngoài, điều này khiến bố cục thay đổi.

Hoạt động điều hướng thông thường bằng Lighthouse sẽ có CLS bằng 0. Tuy nhiên, khi người dùng cuộn, trang sẽ có vấn đề về việc thay đổi bố cục và giá trị CLS (Mức thay đổi bố cục tích luỹ) sẽ tăng lên.

Dùng thử trang web minh hoạ

Tập lệnh sau đây sẽ tạo báo cáo luồng người dùng có cả hai hành động để cho thấy sự khác biệt.

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();

Thao tác này sẽ tạo một báo cáo so sánh một thao tác điều hướng thông thường với một khoảng thời gian chứa cả thao tác điều hướng và thao tác cuộn sau đó:

Báo cáo luồng Lighthouse cho thấy một tập hợp các ảnh chụp nhanh được chụp
Xem báo cáo trực tiếp

Khi đi sâu vào từng bước, bước chỉ dùng để điều hướng cho thấy CLS (Mức thay đổi bố cục tích luỹ) bằng 0. Trang web rất hay!

Báo cáo Lighthouse chỉ bao gồm điều hướng trang với tất cả các chỉ số màu xanh lục

Tuy nhiên, tính năng "Điều hướng và cuộn" cho một câu chuyện khác. Hiện tại, chỉ có Tổng thời gian chặn và Điểm thay đổi bố cục tích luỹ trong khoảng thời gian, nhưng nội dung tải từng phần trên trang này rõ ràng đạt CLS (Mức thay đổi bố cục tích luỹ) cho trang web.

Báo cáo Lighthouse trình bày cách di chuyển và cuộn trang khi có CLS không đạt

Trước đây, Lighthouse không thể xác định hành vi CLS có vấn đề này, mặc dù gần như chắc chắn hành vi này sẽ xuất hiện trong trải nghiệm của người dùng thực. Việc kiểm thử hiệu suất qua các tương tác theo tập lệnh cải thiện đáng kể độ trung thực của phòng thí nghiệm.

Mong nhận được phản hồi

Các API luồng người dùng mới trong Lighthouse có thể thực hiện nhiều chức năng mới, nhưng việc đo lường loại tình huống mà người dùng gặp phải có thể vẫn phức tạp.

Vui lòng liên hệ với chúng tôi nếu bạn có thắc mắc trên diễn đàn thảo luận của Lighthouse, cũng như gửi lỗi hoặc đề xuất trong công cụ theo dõi lỗi.