Puppeteer taking screenshot before background-image is loaded
See original GitHub issueSteps to reproduce
Tell us about your environment:
- Puppeteer version: 1.11.0
- Platform / OS version: Ubuntu
- Node.js version: node 8-slim (docker image)
I’m setting some html content using
page.setContent(html)
and then calling the page.screenshot()
.
This html contains a css style
.demo { background-image: url(https://someurl.com/test.jpg); }
.
In the development environment it renders, perfectly. But in production which runs in docker, it sometime does not render the image fully. It only renders, partial image.
page.setContent(html)
waits until load event is fired if waitUntil option is not set.
**1. Then how come some times it fires load event, even before the background-image is being loaded in puppeteer ** ?
I tested the html in browser, and verified that the ‘load’ event was being fired only after all the resources have been loaded including the background-image in CSS.
2. Can we use networkidle0
for resolving this, or will it also fire before in some times as it is happening with the load
option. ?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:9
- Comments:11
Top GitHub Comments
https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagepdfoptions
I’ve used a Promise Timeout as a workaround to solve this, its not what I really wanted, but its better than nothing 😄
A more dynamic way would be do detect all background images set by CSS/Inline-Style, then evaluating them if they have been fully loaded. Something like (this is just a example for img tags, but can be rewritten into detecting background images as well):
But it can take a toll on the performance, if you have a very large single page to check (I’ve thousands of pages, so I haven’t used it 😄 and the promise timeout worked very well for my case).
Another workaround would be to load your background images before-hand, means use img tags at the very top of your body and make them invisible, then you can use those images as backgrounds anywhere you want and the good thing, they have been already (pre-)loaded 😃 This usually forces the browser to load them before any other media (it’s a sprite technique I learned, if you want your users to see important images/backgrounds/sprites/icons as soon as possible).
Hope it helps you as well, have fun & enjoy 😃
[EDIT]: If page.waitForTimeout is not available in your version, then use
await new Promise(r => setTimeout(r, 2000));
instead