Display Thousands/Millions of different background images Kindly help me check this code, I want to be able to make it load thousands/millions of different pictures as HTML background without crashing or slowing down the browser.

The images can be created dynamically, or linked to its folder, I was able to do that for up to 1000 images/colors per canvas, and add up many more canvas, but at 30 canvas, which is 30,000 images/colors the browser stops to respond(slowish). Tested only on google chrome, so help me achieve tens of millions random colors/pictures.

FYI: The images must be displayed all at once.


  Rihana Photo Mosaic or picturemosaics this is similar to what i want to achieve, as you can see about 36,000 images without any performance issue, they even boast of more than 5 million pictures. Mine should be easier because my pictures are to be random or in a pattern not necessarily being in a mosaic form. If you have another method or way to achieve it, that would be helpful too.


&lt;html&gt;
&lt;body&gt;
  &lt;script&gt;
  var cInt=0;
  var loopCInt=0;
  while (loopCInt&lt;3){
   var canvasName = document.createElement("canvas");
   canvasName.setAttribute('width', "1000");
   canvasName.setAttribute('height', "1000");
   var canvasIdName="myCanvas"+cInt;
   canvasName.setAttribute('id', canvasIdName);
   document.body.appendChild(canvasName);
    var c = document.getElementById(canvasIdName);
    var ctx = c.getContext("2d");
    var i = 0;
    var right=0;
    var tops=0;
    var goDown=0;
    while (i &lt;= 1000) {
      ctx.beginPath();
      ctx.rect(right, goDown, 30, 30);
      ctx.fillStyle = '#'+Math.random().toString(16).slice(-6);
      ctx.fill();
      i++;
      right=right+30;
      tops++;
      if (tops==30){
        goDown=goDown+30;
        right=0;
        tops=0;
      }
    }

  loopCInt++;
  cInt++;
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
Sluggishness

Memory limits

Take a look at a random folder of images on your computer, and observe it's size. Thousands of images will amount to gigabytes of space, which means all that needs to be loaded into memory. You can simply not do that reliably.

There is also not really a point in rendering things that the user cannot see.

Thousands or millions of images?

Consider why you think you need to display thousands or millions of images. Consider a pretty sizeable screen of 1920 by 1080 pixels. If you have 30 pixels in width and 30 pixels of height, you can fit 60 * 36, or 2304 images on screen. At some point you will not be able to make out anything.

Multiple canvas elements

There does not seem to be a reason to use multiple canvas elements. If you want a background with hundreds of images, you can redraw the same canvas as you scroll. In fact, this is probably the best way of dealing with your current situation.

Coding style

Wrap your code in an IIFE

Wrap your code in an Immediately Invoked Function Expression. This causes the variables to not spill into other code you or others write. An IIFE looks something like this:

(function () {
  // ...
})();


Look at your variable names

Some of your variable names do not really make sense. cInt seems an iteration of your canvas element. I am not sure why you use loopCInt at all. Replace it with canvasIdentifier or canvasIteration. canvasName is actually a CanvasElement, not a name. goDown looks like a function name at first glance, but is actually the number of pixels from the top, so just name it top. right is actually what you would refer to as left if you worked with absolutely positioned elements, namely the number of pixels from the left edge.

Bookkeeping

You are using a while loop, and because of that have a lot of lines related to bookkeeping. Since you are managing both a row and a column in a single loop, it is not very readable either. I would recommend replacing it with two for loops.

Factor out functions

You want to start factoring out functions with some kind of behaviour earlier than later in your code. You currently have one giant blob of code that, while it does what you want to do, is a nightmare to read through when you expand it. A pretty obvious thing to abstract out is to move things to draw the scene into their own function. You can then call that function to draw or redraw things.

Factor out magic numbers/strings

You currently set "1000" for the width and height, and draw squares of 30 by 30. Move these numbers/strings to their own variable that you can easily change. This allows you to re-use them and quickly change them when you decide, for example, to have a border of 10 pixels around your canvas.

Example

Below I applied some of these to your code. I also put in an example where the canvas is redrawn when you scroll the screen. I added a random number generator that can be seeded, so that I can show off that you can create a consistent screen. You can probably improve on that, considering that it now generates too many colors.



// https://stackoverflow.com/a/19301306/2209007
function RandomGenerator() {
  var m_w = 123456789;
  var m_z = 987654321;
  var mask = 0xffffffff;
  
  // Takes any integer
  this.seed = function(i) {
      m_w = i;
      m_z = 987654321;
  }

  // Returns number between 0 (inclusive) and 1.0 (exclusive),
  // just like Math.random().
  this.random = function()
  {
      m_z = (36969 * (m_z &amp; 65535) + (m_z &gt;&gt; 16)) &amp; mask;
      m_w = (18000 * (m_w &amp; 65535) + (m_w &gt;&gt; 16)) &amp; mask;
      var result = ((m_z &lt;&lt; 16) + m_w) &amp; mask;
      result /= 4294967296;
      return result + 0.5;
  }
  
  this.randomHexColor = function()
  {
    var hexFFFFFF = 16777215;
  
    return '#' + Math.floor(this.random() * hexFFFFFF).toString(16);
  }
}

(function() {
  var canvas = document.getElementById('background-canvas');
  var ctx = canvas.getContext("2d");
  var windowWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  var windowHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  canvas.setAttribute('width', windowWidth);
  canvas.setAttribute('height', windowHeight);
  
  var imageWidth = 30;
  var imageHeight = 30;
  
  var randomGenerator = new RandomGenerator();
  
  function draw(offset)
  {
    window.requestAnimationFrame(function () {
      randomGenerator.seed(1);

      for (var top = -offset; top &lt; windowHeight; top += imageHeight) {
        for (var left = 0; left &lt; windowWidth; left += imageWidth) {
          if (offset &lt; -imageHeight) {
            randomGenerator.randomHexColor();
            continue;
          }
          ctx.beginPath();
          ctx.rect(left, top, imageWidth, imageHeight);
          ctx.fillStyle = randomGenerator.randomHexColor();
          ctx.fill();
        }
      }
    });
  }

  draw(0);
  
  document.addEventListener('scroll', function() {
    var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
    
    draw(scrollTop);
  });
})();
#background-canvas {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: -1;
}

body {
  height: 200vh;
}
&lt;canvas id="background-canvas"&gt;&lt;/canvas&gt;