Render Engine

Published: September 03, 2019
Edited: September 03, 2019

The most important component Lightning is the WebGL 2d render engine. Its goal is to convert the defined and changed render tree to a series of WebGL commands. It attempts to do this as fast as possible.

Lightning subscribes to requestAnimationFrame to draw the render tree frame. It consists out of 3 steps:

  1. Calculate render coordinates
  2. Fill coordinate buffers
  3. Issue WebGL commands

Calculate render coordinates

Since last frame, things may have been changed to the render tree. Properties could have been changed or children could have been added or removed. Immediately after these changes are performed, the changed branches are tagged as hasUpdates.

When a frame is drawn, first the branches are traversed that contain updates. For these branches the render coordinates will be recalculated. All branches that don't have updates can be skipped. This makes it possible to create large applications with many sections without it becoming slow.

Lightning has many other tricks up his sleeve to save performance, such as not having to render invisible parts (alpha:0 or visible:false) and detecting when branches are guaranteed to be out of screen. Especially the latter feature makes it possible to create (near) infinite scrolling list with good performance.

Lightning is even smart enough to detect when there are no changes at all. In such a situation it will not re-render which almost nullifies resource and power consumption. Yes, Lightning even helps to prevent global warming!

Fill coordinate buffers

The second step is to traverse all visible and on screen branches and gather the textures to be drawn, along with their coordinates. These are finally uploaded to the GPU in a memory buffer.

Issue WebGL commands

Finally, these textures are drawn using WebGL commands. The result is an updated canvas filled with the current state of your render tree.