Javascript Parallax Scrolling Text I built a 404 page which involves parallax scrolling text. The program updates the position of 100-200 text nodes at each animation frame called with window.requestAnimationFrame. It runs decently well on my MacBook (although it occupies significant CPU), but on weaker computers like my phone, it runs very sluggishly.

How can I optimize my code to achieve better performance?



var scene;

function randint(low, high) { // Return a random integer between low and high
  return Math.floor(( Math.random()*(high-low) ))+low;
}

// Add a layer to the scene

function addLayer() {
  // Make  a "layer" in the parallax animation
  var layer = document.createElement("div");
  // Give it a random Z value (0 to 1)
  layer.setAttribute("class", "layer");
  layer.setAttribute("data-z", Math.random().toFixed(2));

  // Make a div inside that says "404"
  layer.appendChild(document.createTextNode("404"));
  // Random X position
  layer.style.left = randint(-10, window.innerWidth) + "px";
  // Below bottom of screen
  layer.style.top = window.innerHeight + "px";
  // Font size and weight based on Z value
  var z = parseFloat(layer.getAttribute("data-z"));
  layer.style.fontSize = Math.floor(z * 150) + "px";
  layer.style.fontWeight = Math.ceil(z * 4) * 100;
  // Random opacity
  layer.style.opacity = (Math.random() / 10).toFixed(2);

  // Add nodes to appropriate parents
  scene.appendChild(layer);
}

function updatePositions() {
  var layers = scene.getElementsByTagName("div");
  var layer, div, z;
  for (var i = 0; i &lt; layers.length; i++) {
    layer = layers[i];
    z = parseFloat(layer.getAttribute("data-z"));
    y = parseInt(layer.style.top.slice(0, layer.style.top.length - 2));
    layer.style.top = (y - Math.ceil(z * 10)).toFixed(2) + "px";

    if (y &lt; (-150)) { // Max fontsize is 150px
      scene.removeChild(layer);
    }
  }
}

function updateColor() {
  var hue = (parseFloat(document.body.getAttribute("data-hue")) + 0.25) % 360;
  document.body.setAttribute("data-hue", hue.toString());
  var hex = chroma(hue, 1, 1, "hsv").brighten().hex();
  document.body.style.color = hex;
  document.getElementsByTagName("a")[0].style.backgroundColor = hex;
}

function update() {
  addLayer();
  updatePositions();
  updateColor();
  window.requestAnimationFrame(update); // Recur
}

scene = document.getElementById("scene");
window.requestAnimationFrame(update);
body {
  background-color: #222;
  margin: 0;
  width: 100vw;
  height: 100vh;

  /* Global font settings */
  color: #fff;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

#scene {
  position: fixed;
  top: 0;
  left: 0;
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.layer {
  position: absolute;
}

.main {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;

  text-align: center;

  opacity: 0.5;
}

h1 {
  font-size: 200px;
  margin-bottom: 0;
}

.main p {
  font-size: 150%;
  margin-top: 0;
}

.main a {

  color: #222;
  background-color: #fff;
  padding: 10px;

  text-decoration: none;
  font-size: 150%;
  font-weight: 600;
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/1.1.1/chroma.min.js"&gt;&lt;/script&gt;
&lt;body data-hue="0"&gt;
  &lt;!-- Background --&gt;
  &lt;div id="scene"&gt;&lt;/div&gt;
  &lt;!-- Foreground  --&gt;
  &lt;div class="main"&gt;
    &lt;h1&gt;404&lt;/h1&gt;
    &lt;p&gt;That page couldn't be found.&lt;/p&gt;
    &lt;a href="http://luke.deentaylor.com/"&gt;Home&lt;/a&gt;
  &lt;/div&gt;

&lt;/body&gt;




Running this snippet in full window will more accurately emulate how it will appear on my website.

Here's a JSFiddle if it's preferred.
According to my experience, web animations don't use CPU as such, but rather prefer the GPU at times for rendering. On phones, custom animations like yours will run without any moderation of fps, and so a lag is kinda expected. On top of it, js doesn't use parallel threads of course, so it won't even use the remaining core if they are available. 

What I'd suggest is use some good library to run these. I remember using Three.js and it ran on my Lumia 520 at 8FPS but still without lag, as the animation was optimized for low FPS. The same ran on my PC at 60FPS smoothly just the same. 

Hope this helps.