Reputation: 455
My frontend framework is very asynchronous. It means, that when the user exetutes some action, then the "model" is changed and after that a bunch of callbacks modifying the DOM are called. Changes of the "model" and dependent callbacks are called asynchronously, because some data has to be "consulted" with server. It leads to ugly reflows.
I've experimented and if I make multiple DOM changes in one code block using JQuery, all is done at once, but my ramework needs it to be done asynchronously in independent calls.
What I need is something like transactions in DB world. Before I start to code some batch DOM update library, I want to know if there is not simpler way.
In my case, all changed elements have one parent, so I wish I could tell the browser: "Do not redraw children of this node. Make different changes to all children. Now redraw all children of this node". Can you help me?
Upvotes: 4
Views: 2381
Reputation: 32063
I believe there's no API to tell the browser to pause reflow/restyle/rendering so that it doesn't repaint after you returned control to the event loop and are waiting for additional data from the server.
It's hard to present a proof that something doesn't exist, but I think the fact that the HTML spec's "Processing model" doesn't mention anything like this -- only heuristics like "user agent might wish to spend less resources rendering third-party content, especially if it is not currently visible to the user" -- is telling.
Another thought: how would the browser handle API calls that ask for layout/style information on elements that have their rendering paused? Return the stale information corresponding to the last rendering? What about the newly created elements?
I'm posting this answer because you said the focus of this question was about built-in browser support, but I think charlietfl's answer is the right solution for the problem given how browsers work.
Upvotes: 1
Reputation: 171679
Use promises and do all the dom manipulation after all promises have resolved. Note that $.ajax
returns a promise and you can chain multiple ajax calls by returning each in a then()
and then finally return what is needed to do the dom manipulation once all of the request promises have resolved
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())
})
Upvotes: 1
Reputation: 563
I believe this is the idea of ReactJS. ReactJS has something call virtual DOM (Javascript object) which manages to minimize HTML DOM manipulation.
Learn more about ReactJS https://reactjs.org/
Upvotes: 0