question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Puppeteer taking screenshot before background-image is loaded

See original GitHub issue

Steps 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:closed
  • Created 5 years ago
  • Reactions:9
  • Comments:11

github_iconTop GitHub Comments

1reaction
iocroncommented, Jun 30, 2021

I’ve used a Promise Timeout as a workaround to solve this, its not what I really wanted, but its better than nothing 😄

await page.waitForTimeout(2000);
await page.pdf({ path: 'example.puppeteer.pdf', format: 'A4', printBackground: true })

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):

await page.evaluate(async () => {
  const selectors = Array.from(document.querySelectorAll("img"));
  await Promise.all(selectors.map(img => {
    if (img.complete) return;
    return new Promise((resolve, reject) => {
      img.addEventListener('load', resolve);
      img.addEventListener('error', reject);
    });
  }));
})

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

Read more comments on GitHub >

github_iconTop Results From Across the Web

Puppeteer wait for all images to load then take screenshot
I am using Puppeteer to try to take a screenshot of a website after all images have loaded but can't get it to...
Read more >
Puppeteer taking screenshot before background-image is ...
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 ......
Read more >
How to Take Screenshots with Puppeteer - Bannerbear
This article will show you examples of using Puppeteer to take simple screenshots, full-page screenshots, multiple screenshots and screenshots of a particular ...
Read more >
Speedy Screenshots, or How I Improved the Robustness of ...
A post by Zach Leatherman (zachleat)
Read more >
Puppeteer get all css styles applied to element ... - YouTube
In this video, I am going to show you how we can get single or all styles applied to an element using puppeteer....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found