javascript - 你能异步创建数千个 DOM 元素吗?

标签 javascript google-chrome

我正在构建一个表情符号选择器,最艰巨的任务是为每个表情符号创建约 1500 个 DOM 元素,这会阻塞/使页面无响应大约 500-700 毫秒。

我已经对此进行了调试,似乎 DOM 元素的创建阻碍了 JS 执行的其余部分:

function load_emojis(arr){
  var $emojis = [];
  # arr.length = 1500
  _.each(arr, function(){
    $emojis.push($('<span/>').append($('<img/>')));
  });

  $('.emojis').html($emojis);
}

有没有办法异步/在另一个线程中执行整个事情,这样它就不会阻塞跟随它的 JS?

我试图将它放在 setTimeout 中,但它似乎仍然在同一个线程中执行,因此仍然阻止 JS 执行。

最佳答案

JavaScript 不是线程化的;它就像大多数 UI 库一样,它在一个带有事件循环的线程中完成所有事情;异步行为可能在后台线程中起作用(JS 程序员不可见;它们不显式管理甚至查看 线程),但结果总是传送到单个前台线程进行处理。

直到您的 JS 代码完成并且控制返回到事件循环时,元素渲染才真正完成;如果你渲染了太多东西,当浏览器需要绘制它时就会出现延迟,而你也无能为力。您最多可以想到的是通过显式创建元素而不是传递一团文本进行解析来减少解析开销,但即便如此,您的选择也是有限的。

根据浏览器、月相等,可能有帮助的事情包括:

  1. 创建并填充一个根本不属于 DOM 的单个父元素,然后在完成填充后将该单个父元素添加到 DOM(可以避免涉及维护 DOM 结构的工作)
  2. 创建一个您将重复添加的结构模板,然后 use cloneNode(True)复制该模板,并填写之后的小差异;这避免了解析 X 节点树的工作,因为它实际上是同一个节点树,通过一些属性调整重复了很多次。
  3. 如果图像大于视口(viewport),则只插入/渲染最初可见的元素,在用户滚动时将其他元素添加到背景中(也可能主动添加它们,但数量要足够少且要有足够的 setTimeout/setInterval 窗口,任何给定的插入都不会花费很长时间,并且 UI 保持响应)。
  4. “许多图像的阵列”的一个重要方面是停止使用 1500 多张图像,而是使用单个整体图像。然后你要么:

    一个。通过 CSS 以给定的固定偏移量和大小重复使用单片图像(图像被解压缩和渲染一次,并且该图像的 View 被重复映射到不同的偏移量或...

    使用 the map/area tags只插入一次图像,但使点击在图像的每个部分表现不同(将 DOM 布局工作减少到单个图像;所有其他 DOM 元素必须存在于树中,但不需要渲染)

关于javascript - 你能异步创建数千个 DOM 元素吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44684911/

相关文章:

javascript - 如何在 Angularjs 中创建一个新实例? CRUD的save方法不起作用

javascript - 在 View 中调用belongs_to关系

javascript - React Native 和 React 的 .map 类似吗?

CSS 响应百分比错误

performance - 如何读取 Chrome DevTools 中的网络选项卡 - 加载时间

javascript - 按钮在 html Canvas 上不起作用

javascript - vb.net 窗口打开

javascript - 为什么 getUserMedia() 在 chrome 中显示权限被拒绝错误

css - 如何使用 chrome dev 协议(protocol)获取 CSS Coverage 数据?

angular - Chrome 87.0.4280 (Windows 10.0.0) : Executed 0 of null (skipped 229) ERROR (34. 875 秒/0 秒)