首先,我对“css contains”的想法是这样的。
- 带有“contain: strict”的 dom 树会将渲染周期与整个 dom 树隔离开来。
- 如果这个孤立的 dom 树发生变化,浏览器将能够获得性能优势。因为计算成本降低了。
例子
<!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>
但是,在这个例子中,当应用了“contain:strict”时,你可以看到渲染性能变差了……<br />为什么会这样?我想知道为什么。