Position vs Translate Waterfall

Benchmark created on


Description

top:y, left:x vs transform: translate

Preparation HTML

<script>
const Methods = {
  POSITION: 0,
  TRANSLATE: 1
};

// Range: [min, max]
function rand(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function renderChild(container, children, method) {
  const gap = 12;

  const child = document.createElement("div");
  const width = 100;
  const height = rand(100, 200);

  const sums = children.map((col) => col.reduce((a, b) => a + b, 0));
  const col = sums.indexOf(Math.min(...sums));
  const x = col * width + gap * (col + 1);
  const y = sums[col] + gap * (children[col].length + 1);
  children[col].push(height);

  child.style.position = "absolute";
  child.style.width = `${width}px`;
  child.style.height = `${height}px`;
  const [r, g, b] = [rand(0, 255), rand(0, 255), rand(0, 255)];
  child.style.background = `rgb(${r}, ${g}, ${b})`;

  if (method === Methods.POSITION) {
    child.style.top = `${y}px`;
    child.style.left = `${x}px`;
  } else if (method === Methods.TRANSLATE) {
    child.style.top = 0;
    child.style.left = 0;
    child.style.transform = `translate3d(${x}px, ${y}px, 0)`;
  }

  container.appendChild(child);
}
</script>

Setup

var children = [[], []];
var container = document.createElement("div");
document.body.append(container);

Teardown

container.remove()

Test runner

Ready to run.

Testing in
TestOps/sec
Position
for (let i = 0; i < 20; ++i) {
  renderChild(container, children, Methods.POSITION);
  await new Promise(requestAnimationFrame);
}
ready
Translate
for (let i = 0; i < 20; ++i) {
  renderChild(container, children, Methods.TRANSLATE);
  await new Promise(requestAnimationFrame);
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.