DEV Community

Cover image for Loading Images with Web Workers

Loading Images with Web Workers

Trezy on June 10, 2019

Web workers are magical. They allow for multi-threading in JavaScript, a language that has been single-threaded since the beginning. Their practica...
Collapse
 
makingthings profile image
James Grubb • Edited

Hello, thanks for the tutorial. I'm looking for ways to dynamically update the image URL in the document's head. Specifically, a meta tag using the OpenGraph protocol

<meta
      property="og:image"
      content="http://ia.media-imdb.com/images/rock.jpg" 
    /> //<-- us a cronjob to update the content property to serve a new image every day
Enter fullscreen mode Exit fullscreen mode

Is this something that a Web Worker could do?

Collapse
 
trezy profile image
Trezy

Unfortunately, no. Web Workers can't access the DOM to make changes. You'd need to do that from the UI thread.

Collapse
 
monochromer profile image
monochromer • Edited

Don't forget about URL.revokeObjectURL(objectURL)

imageElement.onload = () => {
    imageElement.removeAttribute('data-src')
    URL.revokeObjectURL(objectURL);    
  }
Enter fullscreen mode Exit fullscreen mode

This techinque can be used as polyfill for imageElement.decode()

Collapse
 
trezy profile image
Trezy

That's a great callout, @monochromer ! I updated the article with that piece of information. 🥰

Collapse
 
cikaldev profile image
Ian Cikal

Hi Trez, thank you for the article..

Correct me if i'm wrong, in Step 6 you write this,

// Get the original element for this image
const imageElement = document.querySelectorAll(`img[data-src='${imageData.imageURL}']`)
Enter fullscreen mode Exit fullscreen mode

but the images never showing. instead i have the error message inside console setAttribute() is not a function ... after change into this one, the errors gone and images showing. :)

// the problem is located at "querySelector()"
const imageElement = document.querySelector(`img[data-src='${imageData.imageURL}']`)
Enter fullscreen mode Exit fullscreen mode

If you have a time please update the sample code, for future reader,
Again thank you for the article.

Collapse
 
imkevdev profile image
Kevin Farrugia • Edited

Thank you, great read. However, this is incorrect.

Fun fact: tags actually block your application load. If you have 100 images on your page, the browser will download all 100 of them before it renders your page.

<img> tags delay your PageLoad event but do not block rendering.

Collapse
 
kamcio profile image
kamcio

What's the point of this? Doesn't the browsers already decode the images in a separate thread?

Collapse
 
trezy profile image
Trezy

Browsers decode the image separately, yes, but they don't load the images separately. While images are being downloaded they're blocking the UI thread and preventing anything else from being rendered until the image is done downloading. The upside of this approach is that if you have some massive 10k image to load, the rest of your UI can be rendered while the web worker handles the heavy lift of downloading the image.

It's the same reason that you move <script> tags to the bottom of the <body> or mark as async. The download of those scripts will block your UI rendering, so you want to delay them as long as possible, or mark them for async download.

Collapse
 
andreigheorghiu profile image
Andrei Gheorghiu

Your claims are false.
They demonstrate two things: a) you haven't looked at the source code; b) you haven't actually tested your claims.

Image loading does not block rendering. It's as simple as that. If they do block anything, they block other images from loading.

In short: when the browser has to load more resources than its current limit of concurrent requests (which is 4-6 for most of the common browsers), it does its best at prioritizing based on resource type and its position in page (it will always try to render the elements currently on screen first (and it's not always the "above the fold": if you're scrolled down and refresh, it will actually prioritize the elements visible at exactly your current scroll). The main point is that images are almost in all cases the last in the list of priorities. So, if image loading does block something, it blocks other images from loading).

But they don't block rendering or JavaScript execution. Ever.

Collapse
 
kamcio profile image
kamcio

So why not just use some lazy loading technique?

Thread Thread
 
trezy profile image
Trezy

Well, this is essentially lazy loading. The difference between this and traditional lazy loading techniques is that it takes work off of the UI thread and loads the images in parallel, whereas traditionally you would wait until the UI has loaded, then set the src attribute on the img tags so they use the typical browser loading methods. It's the difference between loading your UI and images at the same time, versus loading your UI first, then your images after.

Collapse
 
makingthings profile image
James Grubb

Hello, thanks for the tutorial. I'm looking for ways to dynamically update the image URL in the document's head. Specifically, a meta tag using the OpenGraph protocol

      property="og:image"
      content="http://ia.media-imdb.com/images/rock.jpg" 
    /> //<-- us a cronjob to update the content property to serve a new image every day
Enter fullscreen mode Exit fullscreen mode

Is this something that a Web Worker could do?

Collapse
 
snewcomer profile image
Scott Newcomer

Thanks for the article! Do you happen to know what browser specifics caused performance problems when you don't load images with web workers?

Take lazy loading images as an example. Downloading images isn't render blocking. However, without lazy loading, FMP and/or TTI for the site I work on was 2-3 seconds greater on a normal connection.

I'm not sure which steps (decoding/resizing/rasterization) happen off vs. on thread. So, overall I'm still figuring out what browser specifics are blocking/causing performance problems...

developers.google.com/web/fundamen...

Collapse
 
hdden profile image
HDDen

Hello! Great work!
Please, can you explain me, how blob-urls cooperate with caching? For every page load images will be retrieving from cache, or bypass it and download from web instead?

Collapse
 
tamunoibi profile image
Ib Aprekuma

This was very helpful. Tbank you

Collapse
 
baimaoli profile image
Bai MaoLi

Its amazing tutorial.
I was just having issue with image loading in my smart tv app.
In smart tv app, had to show many images in one page, but it was so slow.
I also tried with javascript lazyload event, but when there are many images to load, the key event(when user fast up/down keys), it was also slow.
I think web worker can solve this issue.
Thanks for good tutorial.

Collapse
 
ashrulkhair profile image
Ashrul Khair

hi, i m interesting to learn something new about web worker, i just wonder to know, how about load img and data in same time, i mean if we have service and that service work every 1 second to fetch data and also load img from path (source path get from fetch data), if you have time please anwers my question sir, thanks a lot. regards from indonesia.

Collapse
 
ganeshshetty195 profile image
Ganesh Shetty

Good one
However Image wont block render tree