change operations should always update the DOM synchronously

While working on a virtual scrolling component, I came across an unintended consequence of the new runloop behaviour - it's too conservative about when it flushes changes through the system. This means that changes inside (for example) an inline component's `init()` method don't result in synchronous DOM updates, which is problematic in certain cases.

The performance impact of this change *should* be negligible, as it doesn't affect how transitions are handled (which was the main benefit of implementing a global runloop).

The `runloop.js` module has grown somewhat unwieldy and could use some refactoring, but that's a separate issue.