JS渲染引擎:给我学好文档碎片再交给我

1,216 阅读4分钟

就让这大雨全部落下,就让这节点装在文档碎片啊~~~ 今天在写代码的时候突然想到,要是我要往页面插入的不是一个DOM节点,而是好多好多个,多到渲染引擎都“烦”你了,这个时候应该怎么办呢?欸嘿,今天就来介绍一下文档碎片......


一、实际场景

  • 在div中添加10000个span标签,虽然看起来很无聊,但是可以更好的看出性能的变化。
<body> 
    <div id="container"></div>
    <script>
        let str = ''
        for (var count = 0; count < 10000; count++) {
            let content = document.getElementById('container')
            str += '<span>测试</span>'
            content.innerHTML = str
        }
    </script>
</body>

建议电脑性能不好的不要轻易尝试,我的笔记本已经瑟瑟发抖了。很显然,这段代码是有问题的,它不断的获取DOM节点,改变界面样式,渲染引擎就要要不断的工作,极大的降低了游览器的性能,这不,等我打完这段字,页面终于是出来了。

image.png


二、那么如何优化呢?

.innerHtml = 整体

  • 先把字符串拼接好,然后一次性挂载上去。
<body> 
    <div id="container"></div>
    <script>
        let str = ''
        let content = document.getElementById('container')
        for (var count = 0; count < 10000; count++) {
            str += '<span>测试</span>'
        }
        content.innerHTML = str
    </script>
</body>

避免了多次的获取DOM节点,大大的提高了浏览器性能,这样写还是不太优雅,所以,我们引入了文档碎片这个概念。

文档碎片

  • 文档碎片(Document Fragment),在Web开发中通常指的是一个轻量级的、不完全的DOM树部分,它并不属于任何文档,也不与文档中的任何节点关联。文档碎片主要用于在内存中创建和操作DOM节点,而不会触发浏览器的重绘或回流,从而提升页面的性能。
  • 使用场景:
    • 批量插入节点:当你需要向DOM树中添加大量节点时,可以先在一个文档碎片中构建这些节点,然后一次性将整个文档碎片插入到DOM树中。这样可以减少DOM操作次数,避免频繁的重绘和回流,提高页面渲染速度。
    • 复杂DOM操作:在文档碎片中进行复杂的DOM操作,如节点的创建、移动、删除等,可以避免这些操作影响到页面的布局和渲染,直到所有操作完成后再将文档碎片一次性添加到页面中。
    • 离线构建DOM:在文档碎片中构建DOM结构,可以不受页面渲染的限制,可以更自由地进行DOM操作,等到构建完成后,再将整个文档碎片插入到页面中。
<body>
    <div id="container"></div>
    <script>
        const fragment = document.createDocumentFragment();
        const container = document.getElementById('container');
        
        for (let i = 0; i < 10000; i++) {
            const span = document.createElement('span');
            span.textContent = '测试';
            fragment.appendChild(span);
        }

        container.appendChild(fragment);
    </script>
</body>

聊到优化,就要提提浏览器的渲染规则了,这样你才能知道为什么能优化。OK,Let's go.


三、浏览器渲染

前期回顾:前面从图片懒加载实战简单的了解了一下打开浏览器时,会干的操作:打开浏览器时,它会干一些什么操作呢?--图片懒加载实战带着你一起慢慢体验 - 掘金 (juejin.cn)

  • 紧接着,浏览器会根据渲染树计算每个元素的位置和大小,这个过程称为布局或回流。 最后,浏览器将布局好的元素绘制到屏幕上,完成页面的初次渲染,称为绘制操作。

可以优化的原因

  • 每当你修改DOM树,如添加、删除或更改节点,浏览器需要重新计算渲染树的部分或全部,这个过程被称为回流。回流之后,如果元素的外观发生变化,浏览器还需要重绘。这些操作都是耗时的,尤其是对于复杂的页面布局。减少了回流和重绘制。
  • 当你使用文档片段时,你实际上是在内存中构建DOM树的一部分,而不在实际的DOM树上。这意味着在将文档片段附加到DOM树之前,所有的操作都不会触发回流或重绘。只有当整个文档片段被一次性插入到DOM树中时,才会触发一次回流和重绘。
  • 减少了回流与重绘的次数,页面的渲染性能得到了提升,尤其是再移动端或低性能设备上,优化的异常明显。

所以下次就不要一直“纠缠”渲染引擎啦,一定把文旦碎片掌握了,今天的分享就到这,感谢陪伴......