Browser Performance
Wix Workshop
File with own code from workshop is in folder
repo_from_presenter/
Workshop by Noam @WIX
Rendering Performance
See this google article about browser rendering.
CSS rendering Pipeline
The following happens in succession
- Request animation frame
-
Calculate Style -
recalculate style- DOM
- CSS
- State: e.g. media queries, hover state
getComputedStyle -
Layout
- Content (dynamically changing)
- Rules (CSS rules, glue dynamic content and viewport together) e.g. changing margin
- Viewport (
vw)
make every element into renderable absolute components (define the geometry of the page)
-
Composite (happens in GPU)
- Cut out part of painting into moving blocks (paper cutouts)
- Actively plan and allocate block of memory —> to avoid OUT OF MEMORY issues - much harder to deal with later. Don’t just leave everything to the garbage collector.
CSS 3D Transformas a trick to use composition
-
Paint (CPU/GPU)
Graphic elements to pixels on screen.
Rasterization: Take SVGs, Text, Images —> Transform it into pixels for LCD drivers.
- Some more to read in this article.
- An article which explains composition (GPUs job)
How does style rendering work in React Native?
React Native Animations
When trying to set useNativeDriver: true for an Animated value which is used to change a CSS layout property, React Native gives the following error:
Style property ‘width’ is not supported by native animated module
-
Why is that?
TODO: Investigate better!
The RN style engine probably works similar to how CSS is processed in a browser.
Changes in the
widthproperty trigger layout operations which are expensive, wheres atransformdoes not.transformis an example of a composite property which is computed in the GPU - at least that’s how it works in the browser - I have to read more about how it’s computed in native iOS and Android.Well, given this, I guess React Native only allows composite CSS properties to be sent to the native (iOS and Android) drivers to be performed by the GPU. I have to read up on this.
See for more information on how browsers render CSS.
Possible improvement
- Set
width: 1and use a transform (withtranslateX) to achieve the same result.
GPU (Graphic accelerator)
- OpenGL (WebGL) (Use GPU to your liking, but uses JS main thread). Use it for sofisticated animations
- Allows for concurrency
Style, Layout rendering of DOM is all in main thread.
- Layout changes are costly.
Alternatives to main thread:
- Compositing
- Worker thread
- Animations run on different thread
- Scrolling on different process on Safari mobile
IPC between web & UI/Compositor
Macbook pro is your enemy (because it’s faster than the average PC)
How to test Browser Speed?
- Testing speed: High-speed camera are only reliable thing because speed testers slow down speed themselves (used by Nokia).
- Debugging speed: Use Chrome Dev Tools Timeline
Tricks
-
Prominent Color
Show color as placeholder, i.e.
<div style={{ backgroundColor: '#12e1f4', transform: ...send to correct location }} > </div> -
Layered Viewport Management
Have several layers stacked on top of each other, they each get out of opacity whenever their content is loaded (analyze onLoad callback on
<img />). Useopacityand notwidthto show element, because that does not change display of DOM element. -
Direct Compositing
- Compositing with atomic elements, like colored rectangles (divs) with will-change (
image.style['will-change']:) - Using
will-changeon atomic components does not cost extra memory and can be used a lot here.
- Compositing with atomic elements, like colored rectangles (divs) with will-change (
-
Background image caching
- Store data in IndexedDB
-
Set the size of the page by translating the last image to bottom.
—> So that scroll bar shows real length
Tips
- Position relative/absolute: No side effect -> doesn’t effect other DOM nodes.
- Subpixel text/layout (e.g.
text-font: 10.3) - When to use layout: If inner content of element changes. Then a transform (i.e. translation) won’t help.
Rule of thumb:
- Change in unpredictable content/media (phone/browser-size): Use layouts (e.g. floats, flexbox etc.)
- Unpredictable motions/Change in UI: Use JS or transforms
- Wow effects: Canvas or WebGL
- Predictable animations (e.g. slide in menu bar): CSS animations
CSS Animations only do composition, don’t live in the main thread.
Q&A
-
So absolute positioning is best performance?
only transforms after initial render
-
How to allocate and plan memory for graphics?
compositing, in Safari see number of layers.
-
Don’t read content after layout change? Example?
some reading operations in JS e.g. reading Element.clientTop() and then setting
topand doing this often is bad for performance. - Don’t do it!
Discuss on Twitter ● Improve this article: Edit on GitHub