This small presentation tries to synthesise the behaviour of a web browser's rendering engine as simply as possible. It also proposes a few tricks we've used internally to cope with very resource-demanding webapps.
• Rich HTML5/JS Applications
expected to behave like a
• Basic access to native
• Low resources, high-end
• High expectations of UX quality
• Heavy content : lengthy videos
or images lists, overall rich UIs
• Animations and multidirectional
• Cost effectiveness.
• Most of the concepts described in this presentation
are heavily platform dependent
• Rendering engines do implement the same
specifications but in different forms, and future
evolutions may invalidate this document.
• The current (early 2013) implementations of iOS,
Android, BB10, Microsoft... devices' default web
engines all fit this document
• A Native Webview runs the HTML5 App
• Alongside are plugins : camera, sensors, etc.
• The Webview is entirely opaque to the native
o No (native) memory handling / garbage collection
No pre-rendering / dynamic loading / caching of
table cells, list views or scroll views
Sparse critical error handling
• The one Webview's engine renders the whole
o We're talking UI here, it is fairly easy to defer
big calculations to native components.
• Its size in memory and its resource consumption
• It can use the device's processor, RAM and
GPU to achieve its rendering process
• Decreasing the Webview’s (hence, the app)
resource consumption can only be done by
altering the JS / CSS / HTML code which
determines what is rendered and how.
WHAT IS IT ?
• The process of
transforming the document
into what we see on our
• Input : DOM (nodes, CSS)
• Output : Bitmaps to be
& Render Layer Tree
drawn on the browsers'
THE RENDER TREE
• Ordered tree of visual elements (“renderers”) representing the
• Enables painting the contents in their correct order
• DOM Nodes spawn one or more renderers under certain
conditions only : display mode, visibility...
• Their ordering depends on their box-model settings, sizing rules,
• Controlling the size and depth of the render tree allows control of
the rendering performances
THE RENDER TREE
Check these options in
Chrome&Co. to visualize
the content rectangles
• Each renderer has children renderers
• Each renderer draws a rectangle defined by its computed CSS
properties and its children’s ones.
• The browser then draws a
grid of rectangles.
Controlled-size layers —
hence keeping several
smaller objects in memory
The renderer's rectangles
are split among these
These rectangles are then
printed as bitmaps on the
Note : These layers or tiles are drawn by the GPU
Html content that spans on
the whole page.
Note that the grey element
is split and drawn among 4
• Initially, and whenever the drawing loop ticks :!
o The DOM nodes that have changed spawn
and modify renderers accordingly, creating or
completing the rendering tree!
o Renderers calculate their respective
Render Layer Tree (Grid
rectangles and their contents!
o These rectangles are projected onto cells of
o Each cell of the grid is drawn as a bitmap on
the screen by the GPU
• Tiling may produce weird
o They are drawn on a single
o Heavier tiles may be
drawn visually significantly
after lighter tiles
To avoid this, we grant large
elements their own "master"
This is what "accelerating" an
element refers to.
The “accelerated” node is
drawn as one solid
rectangle and is not split
• Some renderers in the render
tree can be sent "on top"
This happens when an element
undergoes one of several
transformations — such as a
rotation or the application of a
These transformations make the
target element and its children
being drawn as a solid, singular
This sample code works for
Safari IOS 5 elements.
The triggers are enginedependent.
ACCELERATE ALL THE THINGS ?
• Accelerating key elements can solve most of the
visual quirks linked to the tiling effect
• It also has significant visual drawbacks
Accelerated fonts are drawn as images and not the
product of vectorial operations, which cancels antialiasing
Most graphics suffer from the transformation that's
applied to the bitmap, resulting in general
CRASHES. CRASHES EVERYWHERE.
• Each "master layer" (i.e.
accelerated elements and grid tiles
— called "Compositing Layer")
draws resources from the GPU
Limited amount of available
Large quantity of accelerated
items tend to overflow the GPUs'
buffers, causing the device to
crash the application
Accelerating only key elements is
changes, only the
• When the DOM the modified DOM renderers
• However,their content elements tend to wholly
oThis is due to the fact that the accelerated
element ends up as a "whole" bitmap
Often-changing elements should be
accelerated with caution, they can trigger the
repainting of bigger elements that didn't
Use chrome's devtools to identify you layers'
• Ensuringtick is redraws are notofuselessly heavy
a relevant part optimisation
• Some properties are naturally GPU-heavy
box-shadow, background-size, text-shadow, reflections,
o Image shims and server preprocessing can make a
significant difference in rendering at the cost of overall
memory or network transit
Using transitions to create sliding or fading effect also
o Avoid redraws during animations
o Animate only the strict minimum visually ; hide out of
bound items, detach unimportant nodes, temporarily
disable shadows/other effects
• As usual with most things, it's all about balance
• A limited amount of elements should be accelerated to
maximise user experience improvements.
oAccurately select and accelerate elements that are
expected to be tiled or blinking.
oDetach irrelevant elements from the rendering tree ; use
visibility: hidden; to preserve the layout if needed
oDraw a background in a separate, accelerated element :
fewer redraws and no tiling on one of the visually most
important but technically lightweight element.
• If these easily applicable (though less easily identifiable)
methods fail, it's time to approach different angles.
• MostAndroidsdevices (iPhones
included) do not
provide dedicated GPU
• Unified Memory Architecture
• A pool of memory both GPU
and CPU can access
• Heavy solicitationprocessing
memory via CPU
while ( 1 )
Infinite movie posters list
(calculations, main routine) will
decrease available memory for
• ... and vice versa.
• Free up memory
Check for memory leaks (which is another
o Unload unnecessary collections / templates / etc.
o Chunks of data can be swapped with localstorage
• Flatten the DOM
Minimize pure-layout nodes
o CSS3 — when applicable — enhances pure css
layouting abilities at minimal cost
o Minimize <a>'s, use data-url="" and events instead
DETACHING DOM FRAGMENTS
• DOM subtrees can be kept in memory without being
attached to the main tree
• In this state they stay loaded in memory and parsed
but are excluded from the rendering at every step
• Detaching / Attaching subtrees to the DOM is fairly
fast, as opposed to parsing / loading
• This can be especially effective for scrollview
• Long and rich lists are often the core problem in terms
• It is often necessary to control the quantity of items
displayed at once ; the way native SDKs manage table
Progressively detach / attach elements depending on
the position in the scroll view
Preserve the height of the scrollview with a leading
<div> which can be resized
• Quite effective when lines are reasonably light
RENDERING ON CANVASES
• Dense, graphical areas can be rendered onto <canvas> elements
Reduces the number of nodes drastically
should act as a bitmap once fully drawn
Can abstract large rows/columns of images
• Loses any sense of structure ; no more DOM
Can impede basic and essential features
• Support still edgy on some devices
• Very efficient for dense graphical areas. Can become expensive
in development time.