Open aldobarrios81 opened 9 months ago
I can't reproduce this. Does restarting your Chrome help?
I have the same error, it happens in Incognito mode. But, when I restarted the browser, it worked.
I get this too when trying to generate mobile and desktop report at the same time with Promise.all()
, using node. I solved it my by launching Chrome in a separate worker thread with tinypool. But I’d rather have one Chrome instance running where I generate the reports, that would take less resources. I really have to scale up my box.
I tried to open a new tab with Puppeteer for each form-factor but that didn’t help.
Any ideas how to isolate the report runs in the same Chrome process?
Here's my Tinypool setup if anyone’s interested:
export default async function ({ formFactors, ...runnerOpts }: JobData) {
try {
const pool = new Tinypool({
filename: new URL('./worker.js', import.meta.url).href,
idleTimeout: 1000,
})
return Promise.all<NormalizedResult>(
formFactors.map(formFactor => pool.run({ ...runnerOpts, formFactor }))
)
} catch (err: any) {
console.error(err, 'REPORT_POOL_ERROR')
throw err
}
}
Not exactly the same as with OP, but here's a repro anyway. This should fail with ProtocolError: Protocol error (Tracing.start): Tracing has already been started (possibly in another tab)
:
import * as chromeLauncher from 'chrome-launcher'
import lighthouse from 'lighthouse'
import lrDesktopConfig from 'lighthouse/core/config/lr-desktop-config.js'
import lrMobileConfig from 'lighthouse/core/config/lr-mobile-config.js'
const chrome = await chromeLauncher.launch({
chromeFlags: [
'--disable-dev-shm-usage',
'--disable-setuid-sandbox',
'--headless',
'--no-sandbox',
],
})
export default async function ({
formFactors,
url,
}: {
formFactors: ('mobile' | 'desktop')[]
url: string
}) {
try {
const results = await Promise.all(
formFactors.map(formFactor =>
lighthouse(
url,
{ formFactor, port: chrome.port },
formFactor === 'mobile' ? lrMobileConfig : lrDesktopConfig
)
)
)
return results
} catch (err) {
console.error(err)
throw err
}
}
A bit off-topic but here's some observation running Chrome in a Node worker thread using Tinypool (a fork of Piscina).
This is the memory utilization:
After every peak the pool is nuked await pool.destroy()
and chrome killed chrome.kill()
. But as you see the memory is not fully cleared, classic memory leak. That might be an issue with Tinypool/Piscina, there’s a similar issue here https://github.com/piscinajs/piscina/issues/442. Shot in the dark but in the sharp repo people say that moving Alpine solved their memory issues because it has a different memory allocator https://github.com/lovell/sharp/issues/955#issuecomment-390398044.
I know Chrome need a lot of memory, but it's out of control here, 1 gig is not that much but this was me just testing for few times, in a prod env you'd need much much more, which will get costly.
So I'm thinking it would be less resource intensive to have one Chrome instance which can run reports parallel in separate tabs etc, after the report is done close the tab and I assume the tabs memory is released. Something like that.
I can't reproduce the original issue. Keeping this open to track improvements to the error message that explain why running multiple Lighthouse instances at the same time can be bad.
@hilja taking a look at your code, running multiple Lighthouse tests at the same time on the same browser instance is not supported for the reason the error message explains. Each browser instance can only support tracing on one tab at a time.
You could try getting a new browser instance for each Lighthouse test by calling chromeLauncher.launch
once for each call to lighthouse
.
running multiple Lighthouse tests at the same time on the same browser instance is not supported
Got it. Is that a fundamental limitation of Lighthouse or something that might change in the future?
Off-topic but, I managed to figure this out pretty well after-all. I was initiating Tinypool
inside the function, where as I should've done it outside 😅
Also I found out that the load of the machine effects the results quote a lot, so ideally you'd only run one LH test per machine. This sounds ridiculously expensive and wasteful, but I'm hosted on fly.io and their VMs can be powered down easily since the cold start is about 1 second. Also powered down machines at fly are free (at least for now) so I can have like 30 of them with not much more cost than having one 24/7 running machine. I set the concurrent connections limit to 1 per machine and let their load balancer handle the task distribution. It's all very experimental at the moment and it's not in production yet but so far it's been working okay.
In this scenario memory leaks also don't matter, plus I switched to Alpine (running chromium) which apparently handles memory fragmentation better, it’s largely black magic to me but it has something to do with jemalloc maybe.
Got it. Is that a fundamental limitation of Lighthouse or something that might change in the future?
This error is actually a limitation of Chrome itself and unlikely to change in the future.
FAQ
URL
https://machupicchuperuagency.com/
What happened?
Protocol error (Tracing.start): Tracing has already been started (possibly in another tab).
What did you expect?
Complete report
What have you tried?
No response
How were you running Lighthouse?
Chrome DevTools
Lighthouse Version
11.2.0
Chrome Version
No response
Node Version
No response
OS
No response
Relevant log output
No response