打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
利用 Lighthouse 與 Puppeteer 對全站網頁做效能檢測並產生報表 | Summer。桑莫。夏天

圖片來源

本文主要是記錄如何在專案中簡易下指令來自動執行 Lighthouse 與 Puppeteer 做全站網頁的效能檢測、產生報表與其目錄。

什麼是 Lighthouse?

Lighthouse 是由 Google 開發的開源自動化檢測網站效能的工具,檢測後能給出有建設性的建議,直接告訴我們 要改善什麼地方、要怎麼改,而且還有文件可查、有範例可看,能參考的資源很多,並且會將檢測結果和建議產出人機皆可閱讀的報表。除了效能,它還有檢測其他項目,像是 SEO、PWA,功能多多。

使用 Lighthouse 有幾種方法,有以下幾種

這裡主要是選用 Lighthouse Node CLI 來做全站各頁的檢測,這是因為稍等會看到…要檢測的網站有些頁面是需要登入的,只靠 Lighthouse 恐怕不夠用,還需搭配 End-to-End Testing 工具才能完成工作。

為何選用 Lighthouse?

雖然能做效能檢測的工具很多,除了 Lighthouse,還有 PageSpeed InsightsWebPage TestPingdom 等,相關介紹可參考這裡…這些工具各有自己的長處,但 Lighthouse 提供 Node CLI 版本,易於和自動化工具,因此就選用它了。

如何使用 Lighthouse 做效能檢測?

如前所述,由於要檢測的網站有些頁面是需要登入的,因此需要搭配 End-to-End Testing 工具做登入的動作,並導頁到要檢測的頁面來做檢測,這裡選用 Puppeteer;再來,Lighthouse 並不會幫我們做產出報表的目錄,因此我找了 Table-Builder 來協助製作目錄的表格…綜合以上需求,就必須安裝 Lighthouse、Puppeteer、Table-Builder 與 fs。

yarn add lighthouse puppeteer table-builder fs

package.json 範例

備註,除了 Puppeteer,可選用的 End-to-End Testing 工具很多,像是 WebdriverIONightwatch 都可以。

如何檢測需要登入的頁面?

如前所述,直接使用 Lighthouse 來檢測需要登入的頁面是不可行的因為根本看不到啊,要怎麼檢測解決方法是先使用 Puppeteer 來做登入,而由於要借助 End-to-End Testing 工具來做登入的動作,並導頁到要檢測的頁面來做檢測,因此就要寫一支測試程式來做這些事情。

以下程式碼片段會做以下幾件事情…

  • (1) 到達首頁。

  • (2) 點擊「登入按鈕」。

  • (3) 輸入帳號、密碼。

  • (4) 輸入密碼。

  • (5) 送出輸入的帳號、密碼,登入成功。

程式碼片段說明如下…

async function navigateToIndex() {  const browser = await puppeteer.launch({ headless: true });  const page = await browser.newPage();  const indexURL = context['env'] === 'DEV' ? DEV_HOST : PROD_HOST;  console.log('Navigating to index...');  await page.goto(ENV); // (1) 到達首頁  console.log('Starting login, entering username and password...');  await page.click('#login'); // (2) 點擊「登入按鈕」  await page.type('#account', 'test'); // (3) 輸入帳號  await page.type('#password', 'test'); // (4) 輸入密碼  await page.click('#submit'); // (5) 送出輸入的帳號、密碼  console.log('Login success!'); // 登入成功  return browser;}

如何檢測全站頁面、產生報表?

接下來,依舊使用 Puppeteer 幫我們遍歷全站網頁,並針對每個網頁用 Lighthouse 做檢測,然後產出報表。

如下程式碼,TEST_PAGES 是一個存放頁面列表的常數變數(例如:這個存放頁面列表的常數變數可能是長成這樣 [{id: '...', link: '...'}]),利用 for 迴圈將整個網站的每個頁面都跑一遍;當中使用 Lighthouse 檢測,這裡會產出兩種格式的報表-HTML 與 JSON,再利用 Lighthouse 內建的 reportGenerator 畫出報表;最後使用 TableBuilder 做總結,產生一份簡單的目錄來作 report cover。

以下程式碼片段會做以下幾件事情…

  • (1) 存放所有的 overview 紀錄,等等做目錄用。

  • (2) 將整個網站的每個頁面跑一次。

  • (3) 產出兩種格式的報表-HTML 與 JSON。

  • (4) overview 所需的資料,包含 「Performance」、「Accessibility」、「Best Practices」、「SEO」、「Progressive Web App」五個項目與其分數,分數以小數點表示,滿分為 1。

  • (5) 產生每頁的報表。

程式碼片段說明如下…

browser = await navigateToIndex();page = (await browser.pages())[0];const records = []; // (1) 存放所有的 overview 紀錄,等等做目錄用console.log('Running Lighthouse...');for (let i = 0; i < TEST_PAGES.length; i += 1) {  // (2) 將整個網站的每個頁面跑一次  const report = await lighthouse(    `${ENV}${TEST_PAGES[i].link}`,    {      // lighthouse 檢測中...      port: new URL(browser.wsEndpoint()).port,      output: 'json',      logLevel: 'info',      disableDeviceEmulation: true,      chromeFlags: ['--disable-mobile-emulation'],    },    config,  );  // (3) 產出兩種格式的報表-HTML 與 JSON  const json = reportGenerator.generateReport(report.lhr, 'json');  const html = reportGenerator.generateReport(report.lhr, 'html');  const categories = Object.values(report.lhr.categories);  const record = {};  console.log(`Review results for ${TEST_PAGES[i].id}...`);  record[    'Page'  ] = `<a href='./lighthouse-results-${TEST_PAGES[i].id}.html' target='blank'>${TEST_PAGES[i].id}</a>`;  // (4) overview 所需的資料,包含 「Performance」、「Accessibility」、「Best Practices」、「SEO」、「Progressive Web App」五個項目與其分數,分數以小數點表示,滿分為 1  for (let i = 0; i < categories.length; i += 1) {    const key = `${categories[i].title}`;    record[key] = categories[i].score;    console.log(`Lighthouse scores: ${categories[i].title} ${categories[i].score}`);  }  records.push(record);  // (5) 產生每頁的報表  console.log('Writing results...');  fs.writeFileSync(`reports/performance/lighthouse-results-${TEST_PAGES[i].id}.json`, json);  fs.writeFileSync(`reports/performance/lighthouse-results-${TEST_PAGES[i].id}.html`, html);}

製作目錄

報表產生好了,但總需要有目錄和簡述到底成果如何吧?因此這裡會做一個簡單的目錄,並列出每一頁「Performance」、「Accessibility」、「Best Practices」、「SEO」、「Progressive Web App」五個項目的個別分數。

以下程式碼片段會做以下幾件事情…

  • (1) 設定表頭,包含 「Performance」、「Accessibility」、「Best Practices」、「SEO」、「Progressive Web App」五個項目。

  • (2) 使用 TableBuilder 產生一份簡單的目錄。

  • (3) 將產出的結果寫入 HTML 檔案。

程式碼片段說明如下…

// (1) 設定表頭,包含 「Performance」、「Accessibility」、「Best Practices」、「SEO」、「Progressive Web App」五個項目const headers = {  Page: 'Page',  Performance: 'Performance',  Accessibility: 'Accessibility',  'Best Practices': 'Best Practices',  SEO: 'SEO',  'Progressive Web App': 'Progressive Web App',};// (2) 使用 TableBuilder 產生一份簡單的目錄const table = new TableBuilder({ class: 'repor-table' })  .setHeaders(headers) // see above json headers section  .setData(records) // see above json data section  .render();// (3) 將產出的結果寫入 HTML 檔案fs.writeFileSync(`reports/performance/lighthouse-report-index.html`, table);

產生的目錄如下圖所示(很陽春,待改善 ╮(╯_╰)╭)。

點此看產生的目錄檔範例。

完整程式碼可參考這裡

YARN / NPM Scripts

這裡寫了幾種檢測效能的 script-檢測單一頁面、依照開發或正式機環境做檢測。

指定單一網址做檢測,yarn lighthouse 後可接受一個網址。注意,這只適用於不用登入的頁面。

yarn lighthouse https://next-meal.vercel.app/

依照開發環境做檢測,由於有搭配 End-to-End Testing 工具來做登入,因此適用需要登入的頁面,且能做全站網頁檢測。

yarn perf-dev

依照正式機環境做檢測,同上,由於有搭配 End-to-End Testing 工具來做登入,因此適用需要登入的頁面,且能做全站網頁檢測。

yarn perf-prod

package.json 的設定範例如下,或參考這裡

"lighthouse": "./node_modules/lighthouse/lighthouse-cli/index.js --output-path=./reports/performance/lighthouse-results.html $url","perf-dev": "node test/performance/index.js --env=DEV","perf-prod": "node test/performance/index.js --env=PROD"

後續工作

之後會有文章來記錄結合 CI/CD、將以上使用 Lighthouse 與 Puppeteer 做檢測的方式抽出來成為一個單獨的工具的文章,敬請期待 (๑·̀ㅂ·́)و✧

參考資料


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
在puppeteer和request之间互相传输cookies
第一个参数:min_behot_time
利用puppeteer采集百度数据,并写入json文件
puppeteer基本用法(puppeteer教程)
利用puppeteer破解极验的滑动验证
java+puppeteer实现html转pdf文件
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服