Jaewon Kim
Jaewon Kim

Reputation: 21

css contain makes the performance worse

First of all, my thoughts on "css contain” are this.

  1. A dom tree with “contain: strict” will isolate the rendering cycle from the entire dom tree.
  2. If there is a change in this isolated dom tree, browser will be able to get performance benefits. because the computational cost is reduced.

Example

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Containment Level 1 Test</title>
  <style>
    .box-btn + .box-btn {margin-top:10px;}
    .section {height:100px;contain:none;}
    h2, p {margin:0;padding:0;}
  </style>
</head>
<body>
  <!-- html -->
  <div class="box-btn">
    <!-- 73ms -->
    <button type="button" class="btn-change" data-target="first" data-contain="strict">change first title<br/>with contain:strict</button>
    <!-- 73ms -->
    <button type="button" class="btn-change" data-target="first" data-contain="layout">change first title<br/>with contain:layout</button>
    <!-- 32ms -->
    <button type="button" class="btn-change" data-target="first" data-contain="size">change first title<br/>with contain:size</button>
    <!-- 32ms -->
    <button type="button" class="btn-change" data-target="first" data-contain="none">change first title<br/>with contain:none</button>
  </div>
  <div class="box-btn">
    <!-- 3826ms -->
    <button type="button" class="btn-change" data-target="all" data-contain="strict">change all titles<br/>with contain:strict</button>
    <!-- 3869ms -->
    <button type="button" class="btn-change" data-target="all" data-contain="layout">change all titles<br/>with contain:layout</button>
    <!-- 1764ms -->
    <button type="button" class="btn-change" data-target="all" data-contain="size">change all titles<br/>with contain:size</button>
    <!-- 1735ms -->
    <button type="button" class="btn-change" data-target="all" data-contain="none">change all titles<br/>with contain:none</button>
  </div>
  <div id="container"></div>

  <!-- template -->
  <script type="text/template" id="template">
    <div class="section">
      <h2>section title</h2>
      <p>i'm a section contents</p>
    </div>
  </script>

  <!-- javascript -->
  <script>
    const elBtnChanges = document.querySelectorAll('.btn-change');
    const elContainer = document.querySelector('#container');
    const template = document.querySelector('#template').innerHTML;

    // initialize all dom tree
    for (let i = 0; i < 10000; ++i)
      elContainer.insertAdjacentHTML('beforeend', template)

    const elSections = Array.prototype.slice.call(document.querySelectorAll('.section'));
    const elTitles = elSections.map(elSection => elSection.querySelector('h2'));

    // event : click button
    elBtnChanges.forEach(elBtnChange => {
      elBtnChange.addEventListener('click', (e) => {
        const isAllTarget = e.currentTarget.getAttribute('data-target') === 'all';
        const containValue = e.currentTarget.getAttribute('data-contain');

        // change only one title
        if (isAllTarget) {
          elSections.forEach(elSection => elSection.style.contain = containValue);
          elTitles.forEach(elTitle => elTitle.innerHTML = 'Hello World<br/>Man~');
        } else {
          elSections[0].style.contain = containValue;
          elTitles[0].innerHTML = 'Hello World<br/>Man~';
        }
      })
    })
  </script>
</body>
</html>

However, in this example, when “contain: strict” applied, you can see that rendering performance is worsening…
Why does this happen? I wonder why.

Upvotes: 2

Views: 402

Answers (0)

Related Questions