0

If I have only one image source and I do this:

var url = 'http://path/to/some/image.jpg'

for(var i=0; i < 100; i++){
   var imgsrc = url + "?rand=" + (Math.random() * 99999999);
   $('<img src="+imgsrc+" />').appendTo(...);
}

Is this absolutely the same strain on browser memory like loading 100 completely different images or there is something else?

I can see that in console that browser loads every image, but I need to be sure because I have a test application which loads lots if images, and I need to replicate test environment without setting source to each new image individually.

1
  • Yep, with this code you'll only have a hundred of errors. (except if you've got a valid image file named +imgsrc+ in the same folder as your html, in which case, it will take the cached version of it, but I doubt it's what your meant.) Commented Feb 4, 2017 at 8:18

2 Answers 2

1

So I set out to test this, and it seems that the browser will think that images served from different URLs are different images and will not de-duplicate them, caching or network request wise, even if only the query-string changes.

Test process

So first the setup, a minimal express server:

testServer/
  index.js
  index.html
  assets/
    static-image.jpg

index.js:

const express = require('express')
const app = express()

app.get('/', (req, res) => {
  res.sendFile('index.html', { root: __dirname })
})

app.get('/img', (req, res) => {
  const tag = req.query.rand
  res.sendFile('assets/static-img.jpg', { root: __dirname })
})

app.listen(process.env.PORT || 8080)

index.html:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">

    <title>Test page</title>
  </head>

  <body>
    <div id="images">
    </div>

    <script>

      const url = '/img'
      const container = document.getElementById('images')

      for (let i=0; i < 100; i++) {
        const imgSrc = `${url}?rand=${Math.random() * 99999999}`
        const img = new Image(200, 200)
        img.src = imgSrc
        container.appendChild(img)
      }

    </script>
  </body>
</html>

Now let's start the app with node index.js and load localhost:8080 in our browser:

index.html

The image has been correctly loaded on every instance, let's check the log of received HTTP headers to see if the image has been downloaded every time:

http://localhost:8080/

GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sat, 04 Feb 2017 08:39:55 GMT
Etag: W/"1da-15a08479c08"
Content-Type: text/html; charset=UTF-8
Content-Length: 474
Date: Sat, 04 Feb 2017 08:45:11 GMT
Connection: keep-alive
----------------------------------------------------------
http://localhost:8080/img?rand=9601808.592702283

GET /img?rand=9601808.592702283 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/
Connection: keep-alive

HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 07 Feb 2106 06:28:15 GMT
Etag: W/"85c0-3e7fffffc18"
Content-Type: image/jpeg
Content-Length: 34240
Date: Sat, 04 Feb 2017 08:45:12 GMT
Connection: keep-alive
----------------------------------------------------------
http://localhost:8080/img?rand=46816320.75854376

GET /img?rand=46816320.75854376 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/
Connection: keep-alive

HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 07 Feb 2106 06:28:15 GMT
Etag: W/"85c0-3e7fffffc18"
Content-Type: image/jpeg
Content-Length: 34240
Date: Sat, 04 Feb 2017 08:45:12 GMT
Connection: keep-alive
----------------------------------------------------------
http://localhost:8080/img?rand=70878177.06809631

GET /img?rand=70878177.06809631 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/
Connection: keep-alive

HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 07 Feb 2106 06:28:15 GMT
Etag: W/"85c0-3e7fffffc18"
Content-Type: image/jpeg
Content-Length: 34240
Date: Sat, 04 Feb 2017 08:45:12 GMT
Connection: keep-alive
----------------------------------------------------------
http://localhost:8080/img?rand=51281025.02663941

GET /img?rand=51281025.02663941 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/
Connection: keep-alive

HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 07 Feb 2106 06:28:15 GMT
Etag: W/"85c0-3e7fffffc18"
Content-Type: image/jpeg
Content-Length: 34240
Date: Sat, 04 Feb 2017 08:45:12 GMT
Connection: keep-alive
----------------------------------------------------------
http://localhost:8080/img?rand=72492129.69256185

GET /img?rand=72492129.69256185 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/
Connection: keep-alive

HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 07 Feb 2106 06:28:15 GMT
Etag: W/"85c0-3e7fffffc18"
Content-Type: image/jpeg
Content-Length: 34240
Date: Sat, 04 Feb 2017 08:45:12 GMT
Connection: keep-alive
----------------------------------------------------------
[...]

And now let's check if the cache contains 100 separate instance of the image:

about:cache: about:cache

To make certain that the browser doesn't combine the identical images on disk, I checked the size of the browser's cache before and after:

# Before loading test page
~/.cache/mozilla/firefox/u3lc193j.default/cache2 $   du -d0
335376  .
# After loading test page
~/.cache/mozilla/firefox/u3lc193j.default/cache2 $   du -d0
355724  .
# That's a way bigger difference than the size of the image
~/cacheTest/imageCache/assets/ $   du static-img.jpg
1528

So we have the answer: loading the same image with different query strings will indeed fill up the image cache.

This was tested on Firefox 52 and Chrome 55.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, I can see that in console, but I need to be sure because I have a test application which loads lots if images, and I need to replicate test environment without setting source to each new image individually.
I added the result of comparing the size of the cache before and after loading the page, if that can make you more sure.
If you want to be completely sure that you avoid every caching mechanism in every browser, why not just create 100 different images in the first place? I'm sure there are tools that do that in your favorite server-side language, here's one example if you use Node.
0
var url = 'http://path/to/some/image.jpg';

for( var i = 0; i < 100; i++){
    var imgsrc = url + "?rand=" + (Math.random() * 99999999);
    var img = new Image();
    $('<img src="+imgsrc+" />').appendTo(...);
}

Operator: x += y

Meaning: x = x + y

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.