Asynchronous Style Solving
Asynchronous Style Solving is Gameface’s way of offloading the cohtml::View::Advance by doing the style solving on a Style thread, rather than on the Main thread. This feature will give you an increased performance, but it comes at a cost and that is incompatibility with some of our features. A full list of those features you can find here.
How to use
- This feature is enabled by default for the best performance out of the box.
- Disabling of this feature happens internally and it is done as explained in the Incompatible features section.
- If possible you should avoid disabling this feature, because this will result in a performance drop.
- The asynchronous style solving process is done per view, which means that you can have one view with synchronous style solving and one with asynchronous style solving.
Bad use cases
In general, APIs that may trigger JavaScript execution need to block to ensure that any ongoing style resolution completes correctly. Avoid calling the following APIs immediately after cohtml::View::Advance, as they may wait a long time for style solving to finish.
View::TouchEvent
View::KeyEvent
View::GestureEvent
View::TriggerEvent
View::ExecuteScript
View::GetCacheCountStats
View::GetCacheBytesStats
View::GetUsedImagesList
View::UpdateWholeModelOfType
View::SynchronizeModels
View::RegisterModelOfType
View::LoadURL
View::LoadPageCapture
View::UnloadDocument
View::SetCustomMediaFeature
View::ResetCustomMediaFeatures
Binder::EndEvent
IInputProxy::SetText
IInputProxy::SetSelection
Example
An example for such a case might look something like this:
EventCollection - has some events
View::Advance
EventCollection::FireEvents -> waits for style solving
A better way to do it just to fire the events that have collected so far before calling the advance:
EventCollection - has some event
EventCollection::FireEvents
View::Advance - will execute the events this frame
High impact APIs to look out for
Some Library and System level APIs are also affected which can cause an even bigger wait for them, due to the fact they have to wait every view’s Style Solving to get resolved. Here is a list of the respective APIs:
Library::GetGPUMemoryStats
Library::GetUserGPUMemoryStats
System::RegisterFont
System::UnregisterFont
System::AddUserFont
System::RemoveUserFont
System::GetSystemCacheStats
In general it is a good to use those APIs before calling cohtml::View::Advance to avoid blocking!
Incompatible features
The asynchronous style solving is incompatible with the compositor and coh custom effect features. When one or both of those features gets detected in a stylesheet Gameface will revert to using synchronous style solving. This is done, because those features rely on callbacks that have to be executed on the DOM thread, but with asynchronous style solving Gameface generates them on the styling thread and has to defer them to the next frame which results in bad frames.
The other case in which you will have synchronous style solving is if you do not have a dedicated layout thread.
Even if those features are unused, but CSS declarations that refer to them exist in the active stylesheets Gameface will use the synchronous style solving.
Gameface ‘restarts’ the asynchronous flow when the blocking declarations are removed from their corresponding stylesheet. When they are removed the style solving process will again be done on a separate thread.