Problem is the DOM API can't solve this - not in the general case. Or rather, they're already solving it as well as they can. Modern browsers don't cause a reflow when you set a property: they invalidate the DOM so that it reflows at the end of the script block. However, they also have to reflow whenever you get a DOM property, because the value of that property might have changed based on the DOM manipulations you performed earlier. The full list of getters that trigger layout is here:
This library gets around it by assuming you have no data dependencies between your modifications and subsequent queries of the DOM. That's a dangerous assumption to make in a large JS app. Oftentimes you want a data dependency, eg. you're introducing new content into an element and want to measure how high it'll be so you can add a transition. (BTW, a common hack to measure elements without actually rendering them is to stick them in a hidden iframe.)
I think the right solution is for application developers to carefully consider layout and architect their apps appropriately. Usually you need a separate "measure" pass and "modify" pass. In the former, read out all the DOM properties you need and attach them to the element (if you're using JQuery, $.data works great here, otherwise you can use data attributes). In the latter, read out the properties you measured earlier, perform any computation, and then set the final state of the DOM and kick off any transitions needed to get there. You may need to interleave multiple measure and modify phases, but at least then you know which phases will trigger a layout.
nostradaemons, thanks for great comments in this thread.
We have been recently doing HTML5 app for iPad and noticed you really have to be careful with layouts and recalculate styles to get a smooth performance. We also built a rudimentary tool to run automatic layout performance tests on a real device, because the layout problems easily creep in if you don't constantly keep eye on them.
http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-...
This library gets around it by assuming you have no data dependencies between your modifications and subsequent queries of the DOM. That's a dangerous assumption to make in a large JS app. Oftentimes you want a data dependency, eg. you're introducing new content into an element and want to measure how high it'll be so you can add a transition. (BTW, a common hack to measure elements without actually rendering them is to stick them in a hidden iframe.)
I think the right solution is for application developers to carefully consider layout and architect their apps appropriately. Usually you need a separate "measure" pass and "modify" pass. In the former, read out all the DOM properties you need and attach them to the element (if you're using JQuery, $.data works great here, otherwise you can use data attributes). In the latter, read out the properties you measured earlier, perform any computation, and then set the final state of the DOM and kick off any transitions needed to get there. You may need to interleave multiple measure and modify phases, but at least then you know which phases will trigger a layout.