Firefox OS/Performance/App Performance Validation: Difference between revisions

m
Lakrits moved page FirefoxOS/Performance/App Performance Validation to Firefox OS/Performance/App Performance Validation: The official spelling of "Firefox OS" leaves a space between the two parts of the name. It's easier to find a page if the...
m (Lakrits moved page FirefoxOS/Performance/App Performance Validation to Firefox OS/Performance/App Performance Validation: The official spelling of "Firefox OS" leaves a space between the two parts of the name. It's easier to find a page if the...)
 
(8 intermediate revisions by 7 users not shown)
Line 1: Line 1:
'''Note: This page has now been edited published on MDN, as part of the App Center performance section — see https://developer.mozilla.org/en-US/Apps/Build/Performance/App_performance_validation. Any further changes should be made there. Talk to Chris Mills for more details.'''
This page outlines a simple process for manually auditing and improving the performance of an app.
This page outlines a simple process for manually auditing and improving the performance of an app.


Line 21: Line 23:


Debugging:
Debugging:
* Attach with the App Manager and tweak the structure and styles of the page to trigger the desired behavior.
* Attach with the App Manager and tweak the structure and styles of the page to trigger the desired behavior. Positioning, z-index, and opacity styles are common culprits here.
* Use dump-painting: https://wiki.mozilla.org/Gecko:DisplayListBasedInvalidation#Debugging_Invalidations_Problems
* Use dump-painting: https://wiki.mozilla.org/Gecko:DisplayListBasedInvalidation#Debugging_Invalidations_Problems (Example Displaylist: https://bug979026.bugzilla.mozilla.org/attachment.cgi?id=8396816)


'''Report''':
'''Report''':
Line 77: Line 79:
The duration, in millisecond, required to load the app.  This is usually pretty difficult to measure because the definition of "load the app" varies from app to app.  Generally though, we're talking about the time between the user launching the app and the '''visible''' UI being fully drawn and responsive.  I put an emphasis on the visible UI because many apps require lots of computation and/or I/O to initialize their state enough to draw the full UI for the initial app screen.  If every app waited until it was fully initialized before drawing the UI, they would all appear to be very slow and unresponsive.
The duration, in millisecond, required to load the app.  This is usually pretty difficult to measure because the definition of "load the app" varies from app to app.  Generally though, we're talking about the time between the user launching the app and the '''visible''' UI being fully drawn and responsive.  I put an emphasis on the visible UI because many apps require lots of computation and/or I/O to initialize their state enough to draw the full UI for the initial app screen.  If every app waited until it was fully initialized before drawing the UI, they would all appear to be very slow and unresponsive.


The trick to getting a fast load time is to as little as possible before putting up the '''visible''' part of the UI.  All long term calculations and I/O should be delayed into an idle timer callback if possible.  Apps that load to list UIs (e.g. contacts, sms, email) should only load enough data to display the UI that is initially visible to the user.  The rest of the list can then be loaded in an idle timer callback.
The trick to getting a fast load time is to do as little as possible before putting up the '''visible''' part of the UI.  All long term calculations and I/O should be delayed into an idle timer callback if possible.  Apps that load to list UIs (e.g. contacts, sms, email) should only load enough data to display the UI that is initially visible to the user.  The rest of the list can then be loaded in an idle timer callback.


The real key here is to make sure that the UI is drawn as early as possible.  Preferably, show a UI that isn't going to have a lot of box size re-adjustments due to reflows.  Having a bunch of box resizes during load makes the app feel like web page rather than a native app.  The goal here is to provide a native app experience using web technologies.
The real key here is to make sure that the UI is drawn as early as possible.  Preferably, show a UI that isn't going to have a lot of box size re-adjustments due to reflows.  Having a bunch of box resizes during load makes the app feel like web page rather than a native app.  The goal here is to provide a native app experience using web technologies.
Line 98: Line 100:
'''What does it mean''':  
'''What does it mean''':  


Having a good layer tree means we can most changes without having to repaint the page. Think of a cartoons on the television like The Simpsons: Most cartoons will divide their scene into a few layer and will move the layers themselves instead of redrawing the scene for every frame of the cartoon. Using layers to perform animations means we can avoid redrawing the page every frame and can simple move these layers around.
Having a good layer tree means we can perform most changes without having to repaint the page. Think of a cartoon on the television like The Simpsons: Most cartoons will divide their scene into a few layer and will move the layers themselves instead of redrawing the scene for every frame of the cartoon. Using layers to perform animations means we can avoid redrawing the page every frame and can simple move these layers around.




Line 124: Line 126:
'''Debugging''':
'''Debugging''':
* Attach with the App Manager and tweak the structure and styles of the page to trigger the desired behavior.
* Attach with the App Manager and tweak the structure and styles of the page to trigger the desired behavior.
and
* Get a display list dump. Build b2g with 'export B2G_DUMP_PAINTING=1' in your .userconfig (note: if you have a debug build, you don't need this). Set the preference 'user_pref("layout.display-list.dump", true);'.
* Look for the display list dump for the particularly process at the moment of interest. It will contains a list of display items and their mappings between layers and their original frames.
'''Creating/Destroying layers''':
Continuously creating and destroying layers can hurt performance. Setting the pref "layers.flash-borders" when layer borders are activated will add a fading animation to layer borders when layers are created. Immediately after a layer is created, it's border is black and then it fades into it's usual color (green for most layers) during a second or two. This can highlight counter-intuitive behaviors, such as elements being already "layerized" seeing their layer being destroyed and recreated after a style change (for example, an animated element that moves around and then fades to transparent currently gets its layer recreated at the start of its opacity transition).
Beware that this triggers full-tilt compositing (The compositor will try to composite continuously at 60fps regardless of whether anything has changed on the screen). So while this can be useful to understand the layerization behavior in some cases, it should not be used while doing performance measurements.


== 6. Checkerboarding ==
== 6. Checkerboarding ==
3,860

edits