GoogleChrome / lighthouse

Automated auditing, performance metrics, and best practices for the web.
https://developer.chrome.com/docs/lighthouse/overview/
Apache License 2.0
28.33k stars 9.37k forks source link

Mobile mode is not working even after giving mobile configuration from lighthouse #16126

Closed umeshaccion closed 1 week ago

umeshaccion commented 3 months ago

FAQ

URL

https://www.google.com

What happened?

report_mobile.json you can see above report where screenshot are not coming in mobile mode even after using mobile config.

What did you expect?

Should emulate like mobile. which used happen in lighthouse version 9.6.8.

What have you tried?

Have tried mobile configuration passing in userflow method import { screenEmulationMetrics, throttling, userAgents, } from "lighthouse/core/config/constants.js"; import config from "lighthouse/core/config/desktop-config.js"; const mobileConfig = { config: { extends: "lighthouse:default", settings: { formFactor: "mobile", onlyCategories: categories, throttling: constants.throttling.mobileSlow4G, screenEmulation: constants.screenEmulationMetrics.mobile, emulatedUserAgent: constants.userAgents.mobile, output: outputType, }, }, };

const flowMobile = await new UserFlow(currentPage, mobileConfig);

How were you running Lighthouse?

node

Lighthouse Version

12.1.0

Chrome Version

126.0.6478.128

Node Version

20.9.0

OS

windows 10

Relevant log output

It should work in mobile mode and emulate like mobile
connorjclark commented 3 months ago

The code you provided is not complete and does not compile. Please provide real code. What is the error you see?

also, if you are upgrading from v9 then review the breaking changes

https://github.com/GoogleChrome/lighthouse/releases/tag/v10.0.0 https://github.com/GoogleChrome/lighthouse/releases/tag/v11.0.0 https://github.com/GoogleChrome/lighthouse/releases/tag/v12.0.0

umeshaccion commented 3 months ago

@connorjclark Thank you for quick reply. Below is my code which takes some arguments at runtime and generates the report. When I used lighthouse version 9, mobile mode screenshots in the reports were good. Now I have upgraded 12.01 so Even after giving Mobile mode configuration it doesn't run in mobile mode.

import fs from "fs"; import { screenEmulationMetrics, throttling, userAgents, } from "lighthouse/core/config/constants.js"; import config from "lighthouse/core/config/desktop-config.js"; import { UserFlow } from "lighthouse/core/user-flow.js"; import { ReportGenerator } from "lighthouse/report/generator/report-generator.js"; import Module from "module"; import puppeteer from "puppeteer";

const cmdArgs = process?.argv; const portNoIndex = 2; const categoryIndex = 3; const outputTypeIndex = 4; const isMobileIndex = 5; const isDesktopIndex = 5; const fileNameInitialsIndex = 6;

let categories = getCmdLineArgs(cmdArgs, categoryIndex, "category"); let outputType = getCmdLineArgs(cmdArgs, outputTypeIndex, "outputType"); let isMobile = getCmdLineArgs(cmdArgs, isMobileIndex, "isMobile"); let isDesktop = getCmdLineArgs(cmdArgs, isDesktopIndex, "isDesktop"); let fileNameInitials = getCmdLineArgs( cmdArgs, fileNameInitialsIndex, "fileNameInitials" ); let portNo = getCmdLineArgs(cmdArgs, portNoIndex, "portNo");

console.log("categories : " + categories); console.log("outputType : " + outputType); console.log( "output path for report and file name initials : " + fileNameInitials ); console.log(" Desktop mode : " + isDesktop); console.log(" mobile mode : " + isMobile);

// desktop config to generate report let desktopConfig = { config }; desktopConfig.config.settings.onlyCategories = categories; desktopConfig.config.settings.output = outputType;

// mobile config to generate report const mobileConfig = { config: { extends: "lighthouse:default", settings: { formFactor: "mobile", onlyCategories: categories, throttling: throttling.mobileSlow4G, screenEmulation: screenEmulationMetrics.mobile, emulatedUserAgent: userAgents.mobile, output: outputType, }, }, };

if ( !checkValidityOfCmdLineArgs( categories, outputType, isMobile, isDesktop, fileNameInitials ) ) { doExit(); } else { initiateProcess(); }

function checkValidityOfCmdLineArgs( categories, outputType, isMobile, isDesktop, fileNameInitials ) { if ( categories == "" && outputType == "" && !isMobile && !isDesktop && fileNameInitials == "" ) { console.log( "Category, port.no, output type, output path, device are manadatory." ); console.log( "For ex. node " ); return false; }

if (categories == "") { console.log( "Category, port.no, output type, output path, device are manadatory." ); console.log( "For ex. node <width,height> " ); console.log( "Categories are not specified like accessiblity,seo,best-practices in command line args." ); return false; }

if (outputType == "") { console.log( "Category, port.no, output type, output path, device are manadatory." ); console.log( "For ex. node <width,height> " ); console.log( "Output type like html,json is not specified in command line args." ); return false; }

if (!isMobile && !isDesktop) { console.log( "Category, port.no, output type, output path, device are manadatory." ); console.log( "For ex. node <width,height> " ); console.log("Desktop or mobile is not specified in command line args."); return false; }

if (fileNameInitials == "") { console.log( "Category, port.no, output type, output path, device are manadatory." ); console.log( "For ex. node <width,height> " ); console.log("Output path is not specified in command line args."); return false; } return true; }

function getCmdLineArgs(cmdArgs, index, type) { let result; switch (type) { case "category": result = cmdArgs[index]?.indexOf(",") > -1 ? cmdArgs[index]?.split(",") : cmdArgs[index] ? [cmdArgs[index]] : ""; break; case "outputType": result = cmdArgs[index]?.indexOf(",") > -1 ? cmdArgs[index]?.split(",") : cmdArgs[index] ? [cmdArgs[index]] : ""; break; case "isMobile": result = cmdArgs[index] == "mobile" ? true : false; break; case "isDesktop": console.log(cmdArgs[index]); result = cmdArgs[index] == "desktop" ? true : false; break; case "fileNameInitials": result = cmdArgs[index] ? cmdArgs[index] : ""; break; case "portNo": result = cmdArgs[index]; break; default: // code to execute if expression doesn't match any of the values } return result; }

async function connectToBrowser(portNo) { / getting port from command line arguments and preparing url to connect already opened browser . / const browserURL = "http://127.0.0.1:" + portNo; // connecting using connect method by passing browserURL const browser = await puppeteer.connect({ browserURL, });

return browser; }

async function getActivePageFromBrowser(browser) { // getting already opened page in the browser const pages = await browser.pages();

// getting active tab status const activeTabStatus = await Promise.all( pages.map(async (p) => { const state = await p.evaluate(() => document.webkitHidden); return !state; }) );

const currentPage = await pages.filter( (_v, index) => activeTabStatus[parseInt(index)] )[0];

return currentPage; }

async function generateDesktopSnapshot(currentPage, desktopConfig) { const screenInfo = await currentPage.evaluate(() => { let screenObj = { height: window.document.body.scrollHeight, width: window.screen.availWidth, }; return screenObj; });

console.log(screenInfo);

currentPage.setViewport({ width: screenInfo.width, height: screenInfo.height, deviceScaleFactor: 1, }); // change width and height in config is equal to screen width and height desktopConfig.config.settings.screenEmulation.width = screenInfo.width; desktopConfig.config.settings.screenEmulation.height = screenInfo.height;

// created flow object for desktop and mobile

const flowDesktop = await new UserFlow(currentPage, desktopConfig); await flowDesktop.snapshot();

return { htmlReport: await flowDesktop.generateReport(), jsonReport: await ReportGenerator.generateReport( await flowDesktop.createFlowResult(), "json" ), }; }

async function generateMobileSnapshot(currentPage, mobileConfig) { // await scrollToBottom(currentPage); // console.log(mobileConfig); await currentPage.setViewport({ width: mobileConfig.config.settings.screenEmulation.width, height: mobileConfig.config.settings.screenEmulation.height, isMobile: true, deviceScaleFactor: 2, }); const flowMobile = new UserFlow(await currentPage, await mobileConfig); await flowMobile.snapshot(); return { htmlReport: await flowMobile.generateReport(), jsonReport: await ReportGenerator.generateReport( await flowMobile.createFlowResult(), "json" ), }; }

async function generateLighthouseReport(path, result) { fs.writeFileSync(path, result); }

async function initiateProcess() { try { // connect to browser var desktopSnapshot, mobileSnapshot;

var browserObject = await connectToBrowser(portNo);
// get active page from live browser
var activePage = await getActivePageFromBrowser(browserObject);

if (isDesktop) {
  desktopSnapshot = await generateDesktopSnapshot(
    activePage,
    desktopConfig
  );
  generateLighthouseReport(
    fileNameInitials + "_desktop.html",
    desktopSnapshot.htmlReport
  );
  generateLighthouseReport(
    fileNameInitials + "_desktop.json",
    desktopSnapshot.jsonReport
  );
}

if (isMobile) {
  mobileSnapshot = await generateMobileSnapshot(activePage, mobileConfig);
  generateLighthouseReport(
    fileNameInitials + "_mobile.html",
    mobileSnapshot.htmlReport
  );
  generateLighthouseReport(
    fileNameInitials + "_mobile.json",
    mobileSnapshot.jsonReport
  );
}

await doExit();

} catch (error) { // handle error console.log("something went wrong.."); console.log(error); console.error(error); doExit(); } }

async function scrollToBottom(page) { await page.evaluate(() => { const scrollHeight = document.body.scrollHeight; window.scrollTo(0, scrollHeight); }); }

async function doExit() { process.exit(0); }

Module.exports = { getCmdLineArgs, checkValidityOfCmdLineArgs, connectToBrowser, getActivePageFromBrowser, generateDesktopSnapshot, generateMobileSnapshot, generateLighthouseReport, };

connorjclark commented 3 months ago

I can't process that really. Put it in a gist or repo?

Did you consult the breaking change logs I shared?

umeshaccion commented 3 months ago

@connorjclark I have gone through change logs I don't see any breaking changes I used in my code.

I have uploaded code in git, you can clone it from here https://github.com/umeshaccion/sample-lighthouse.git.

Once you clone you can do npm install and you can trigger index.js using below commands. Before running index.js you need to open browser and have it's port no. handy so you can pass in arguments while triggering index.js.

node /index.js <categories[]> <output type []>

ex. node "C:\nexial-lighthouse\nexial-lighthouse\index.js" 12332 accessibility,performance html,json mobile C:\Users\al11172\Desktop\report\report1

adamraine commented 1 week ago

@umeshaccion the git link you sent is a 404.

Additionally, I tried copying and running the script in https://github.com/GoogleChrome/lighthouse/issues/16126#issuecomment-2247310785 according to your instructions in https://github.com/GoogleChrome/lighthouse/issues/16126#issuecomment-2255076061. The script changes the emulated screen size but nothing else, so I really can't reproduce this unless you provide a much more minified script.

As for the problem you reported, you can try removing calls to setViewport and only use the Lighthouse config to specify the desired viewport size.

umeshaccion commented 1 week ago

Hi @adamraine Thank you for reply. Later I found out my issue is already reported and it's status is open. Below is link of the issue

https://github.com/GoogleChrome/lighthouse/issues/14134(https://github.com/GoogleChrome/lighthouse/issues/14134)