How I Created 488 "Live Images"

bitsofco.de bitsofco.de3 years ago in #Dev Love339

I’ve recently been going down a rabbit hole of making improvements to my CanIUse embed. To give a bit of a background, it is an interactive embed I created to easily embed data from caniuse.com in my blog posts and anywhere else. I previously wrote about how I first created the embed and how I progressively enhanced it by adding a fallback screenshot captured with puppeteer and hosted on Cloudinary. The next improvement on my path down this hole was to create what I’m calling “live images” for each feature on caniuse.com. What I wanted to do was have a URL linking to an image (hosted on Cloudinary) that I would periodically update with the support table for that feature. For example, to get the latest image of CSS Grid support, anyone could use this URL: https://caniuse.bitsofco.de/image/css-grid.png That image will be periodically updated (right now I’m doing once a day) and could then be used in places where Javascript is completely unsupported, e.g. Github READMEs, or just as a fallback for the full blown embed. Since it’s also hosted on Cloudinary, any file type is supported and can be accessed on the fly, simply by changing the extension. https://caniuse.bitsofco.de/image/css-grid.webp https://caniuse.bitsofco.de/image/css-grid.jpeg https://caniuse.bitsofco.de/image/css-grid.gif Here’s how I did this! Step 1: Capture 488 images using Puppeteer The first step is to create the images for the live embed, which involved capturing a screenshot of the embed page. I’ve covered in previous articles how to use puppeteer to capture a screenshot, so I won’t go over that again here. However, there are 488 features on caniuse.com, and there is one thing to mention about trying to take 488 screenshots using Puppeteer in a row. You need to be careful about how you’re navigating to 488 different pages with Puppeteer. At first, I was launching a new browser then attempting to to open 488 different pages on that browser. const features = [ … ]; const browser = await puppeteer.launch({ … }); const screenshots = []; for (let i = 0; i < features.length; i++) { // Opening a new page for each feature – didn’t work const page = await browser.newPage(); await page.goto(`https://caniuse.bitsofco.de/embed/index.html?feat=${features[i]}&screenshot=true`); screenshots.push({ feature: feature, screenshot: await page.screenshot({ … }); }); } await browser.close(); return screenshots; Doesn’t work This didn’t work because, unsurprisingly, you can’t open 488 different pages on the browser. After about 12 pages, Puppeteer would crash. I was able to fix this by slightly changing this around and using the same page to navigate to the 488 different pages. const features = [ … ]; const browser = await puppeteer.launch({ … }); // Open a single page for all features const page = await browser.newPage(); const screenshots = []; for (let i = 0; i < features.length; i++) { await page.goto(`https://caniuse.bitsofco.de/embed/index.html?feat=${features[i]}&screenshot=true`); screenshots.push({ feature: feature, screenshot: await page.screenshot({ … }); }); } await browser.close(); return screenshots; Works! Step 2: Upload 488 images to Cloudinary I have also covered how to upload images from Puppeteer to Cloudinary in a previous article, so I won’t go into that here again. Luckily, there was no issue uploading 488 images to Cloudinary in one go, so I didn’t have to make any special considerations there. The only thing I had to make sure I did was to make the file name of the image the exact slug as used by caniuse.com. So, for example, the slug for CSS Grid is css-grid, and that’s the file name for the image too. I also had to ensure that any new images with that same name will override the previous image, and not just create another image. To…

Like to keep reading?

This article first appeared on bitsofco.de. If you'd like to keep reading, follow the white rabbit.

View Full Article

Leave a Reply