最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why does setting textContent cause layout thrashing? - Stack Overflow

programmeradmin6浏览0评论

This blog post suggests that textContent is preferable to innerText for avoiding layout thrashing. But it is focused on retrieving an element's text; for setting element text, the opposite appears to be true -- at least in the following example.

This example uses innerText and produces no layout thrashing:

<style>
    #test {
        background-color: blue;
        float: right;
        width: 100px;
        height: 100%;
    }
</style>
Test test test
<div id="test"></div>
<script>
    setInterval(function() {
        document.querySelector('#test').innerText = 'innerText';
    }, 100);
</script>

But replace innerText with textContent and watch it thrash:

Can someone explain this behavior? What can I do to avoid layout thrashing and still change an element's text in a standards-based way?

This blog post suggests that textContent is preferable to innerText for avoiding layout thrashing. But it is focused on retrieving an element's text; for setting element text, the opposite appears to be true -- at least in the following example.

This example uses innerText and produces no layout thrashing:

<style>
    #test {
        background-color: blue;
        float: right;
        width: 100px;
        height: 100%;
    }
</style>
Test test test
<div id="test"></div>
<script>
    setInterval(function() {
        document.querySelector('#test').innerText = 'innerText';
    }, 100);
</script>

But replace innerText with textContent and watch it thrash:

Can someone explain this behavior? What can I do to avoid layout thrashing and still change an element's text in a standards-based way?

Share Improve this question edited Jun 19, 2013 at 20:18 BoltClock 724k165 gold badges1.4k silver badges1.4k bronze badges asked Jun 19, 2013 at 19:43 JohnJohn 30.2k12 gold badges82 silver badges83 bronze badges 1
  • 2 I would avoid innerText: it's non-standard and varies significantly in implementation, and is not even implemented in Firefox. What happens if you just append a text node? var textNode = document.createTextNode("innerText"); document.getElementById("test").appendChild(textNode) – Tim Down Commented Jun 19, 2013 at 23:19
Add a ment  | 

2 Answers 2

Reset to default 12

The issue:

You are correct! Just like you observed. Setting textContent does cause thrashing.

Here is what the DOM specification has to say:

textContent of type DOMString, introduced in DOM Level 3

This attribute returns the text content of this node and its descendants. When it is defined to be null, setting it has no effect. On setting, any possible children this node may have are removed and, if it the new string is not empty or null, replaced by a single Text node containing the string this attribute is set to.

The fix

A non thrashing way would be to get the element's text nodes and modify those instead of using textContent or innerText (which is non standard).

var test = document.getElementById("test");
var a = document.createTextNode("");
test.appendChild(a);
setInterval(function(){
    a.nodeValue = "Test test test";
},100);

Here is a working fiddle

Of course if the actual text will change, a paint will have to occur to update what you're seeing.

In addition to Benjamin answer, I noticed that when the value of nodeValue or innerText is different than the previous one, the entire document layout is trashed too, as you can see here: http://jsfiddle/5N7Rr/15/

(Full screen, open in new tab)

The browser trashes the entire layout because he don't knows the size of the element, so the trick to avoid entire document trashing is to set a fixed height and width AND set overflow to hidden (Important). This way you tell the browser that whatever the content of the element is, it never is going to exit the element boundaries.

EDIT 30/11/2020: I also needed to add CSS property contain: strict to explicitly tell the browser that the content is not going to exit the container.

Fiddle: http://jsfiddle/u9pra25f/

And proof (Full screen again). Notice how the layout update only affects the element:

发布评论

评论列表(0)

  1. 暂无评论