一次执行多个DOM更改

时间:2018-01-10 16:38:57

标签: javascript performance dom

我的前端框架非常异步。这意味着,当用户说出某些动作时,则会更改“模型”,然后调用一堆修改DOM的回调。 “模型”和相关回调的更改是异步调用的,因为某些数据必须与服务器“协商”。它导致丑陋的回流。

我已经进行了实验,如果我使用JQuery在一个代码块中进行多个DOM更改,则所有操作都会立即完成,但我的ramework需要在独立调用中异步完成。

我需要的是像DB world中的事务。在我开始编写一些批量DOM更新库之前,我想知道是否有更简单的方法。

在我的情况下,所有更改的元素都有一个父元素,所以我希望我能告诉浏览器:“不要重绘此节点的子节点。对所有子节点进行不同的更改。现在重新绘制此节点的所有子节点”。你能救我吗?

3 个答案:

答案 0 :(得分:1)

使用promises并在所有承诺解决后执行所有dom操作。请注意$.ajax返回一个promise,您可以通过返回then()中的每个来链接多个ajax调用,然后在所有请求promise都已解决后最终返回执行dom操作所需的内容

function doStuff() {
  return $.post('/echo/json/', {json: '{"item":1}'}).then(data => {
    // return function we can call when all requests completed
    return function() {
      console.log('doStuff() data', data)
    }
  })
}

function doOtherStuff() {
   return $.post('/echo/json/', {json: '{"item":22}'}).then(data => {
    // return function we can call when all requests completed
    return function() {
      console.log('doOtherStuff() data', data)
    }
  })
}



Promise.all([doStuff(), doOtherStuff()]).then(function(funcs) {
  // now all requests complete call each of the returned functions
  funcs.forEach(f => f())
})

DEMO

答案 1 :(得分:1)

我相信没有API告诉浏览器暂停reflow / restyle / rendering ,以便在您将控制权返回给事件循环并等待来自服务器的其他数据后它不会重新绘制

很难提供不存在某些内容的证据,但我认为HTML规范的"Processing model"没有提到这样的事实 - 只有像“用户代理这样的启发式方法可能希望花费更少的资源来呈现第三方内容,特别是如果用户当前不可见“ - 正在讲述。

另一个想法:浏览器如何处理暂停渲染的元素上的API calls that ask for layout/style information?返回与上次渲染相对应的陈旧信息?新创建的元素怎么样?

我发布这个答案是因为你说这个问题的重点是关于内置的浏览器支持,但我认为 考虑到浏览器的工作原理,charlietfl's answer是解决问题的正确方法。

答案 2 :(得分:0)

我相信这是ReactJS的想法。 ReactJS有一些调用虚拟DOM(Javascript对象)的东西,它可以最大限度地减少HTML DOM操作。

详细了解ReactJS https://reactjs.org/