Performance Optimization for Layout Runs
If an Ext JS application starts to show performance issues, there are always a few usual suspects that developers should focus their investigation on. In broad categories, they are network limitations (bandwidth and latency), device memory/storage limitations, and layout / rendering issues. This article will focus only on optimizing the layout and rendering process of Ext JS Classic Toolkit applications, known as a Layout Run. Layout and rendering issues typically occur when an application grows to include dozens of components in a single container view, which triggers unnecessary layout runs.
Understanding a Layout Run
When an Ext JS container class is initialized, it begins a process to initialize and wire together all the components that are a part of the container view. To optimize rendering and layout performance of the container and its components, the goal is to avoid recomputing CSS / style and rendering calculations which occur by adding, subtracting, or modifying elements on the DOM. The browser caches these style calculations, but the style values will likely need to be recomputed each time a new component is added, subtracted, or modified in its container. This is why Ext JS 6 renders components in bulk, instead of rendering each component separately. Bulk rendering creates an entire component tree as HTML, and then writes it to the DOM with one stroke. After rendering, Ext JS begins a process known as a Layout Run, which computes the size and position of unknown layout and style values for some components on the viewport. Layout / Style values for components that use auto, flex, or other dynamic values are unknown and may need to be computed based on values from other components. To improve performance, developers should try to minimize unnecessary layout runs, which leads to re-computations and sluggishness.
Detecting a Layout Run
To remove unnecessary layout runs, you first need to find them. There are two easy ways to detect a layout run. First, Sencha Inspector has the ability to watch for it. The third tab in the Sencha Inspector header is dedicated to helping developers watch for layout runs. To start watching, simply click on the Watch button. After a new layout run is triggered, it will appear in the list with the list of components that were affected.
The second way to detect a layout run is to copy and paste the following line of code into Google Chrome Console:
Ext.Function.interceptBefore(Ext.layout.Context.prototype, 'run', function () { console.log('Layout run'); debugger; })
This line of code intercepts each call to a layout run, and triggers a breakpoint with a call to a debugger keyword. Because the debugger keyword is equivalent to setting a breakpoint, the code execution is halted; this enables the developer to check the Call Stack and determine which methods triggered the layout run. Figure 2 contains an example where the line of code to intercept the layout run is placed into the debugger. After a new tab in a tab panel is activated, the console log outputs “Layout Run” and a breakpoint is triggered. The Call Stack can be traced to find the event that triggered the layout run. In this case, there was only one layout run triggered for a tab panel active event, which is great!
Optimizing Layout Performance
If you detect that a single action or event is triggering several layout runs, it’s likely that there’s an opportunity to optimize. Quite often, this occurs when you add multiple components individually after the container view is already rendered. Adding each new component to a container view triggers a new layout run. If multiple components need to be added, you can suspend a layout run by calling the Ext.suspendLayouts() method. Once all the desired components are added or modified in container view, you should then resume the layout run via Ext.resumeLayouts(true) method.
If an event does trigger a new layout run, you can further manage performance impacts by setting the size (width and height) of the modified component’s container to a static value. This can reduce the impact because the layout run no longer has to consider how modifying the component will affect adjacent containers and their size and layout.
Sencha Inspector is available to try for free as a part of the Ext JS trial. You can learn more about Sencha Inspector.
Try out these performance improvements and share your experience in the comments below.
I will be at JSConf Belgium and other upcoming Sencha events. Come by and we can talk about the performance of your Ext JS apps.
We’re excited to announce the official release of Rapid Ext JS 1.0, a revolutionary low-code…
The Sencha team is pleased to announce the availability of Sencha Architect version 4.3.6. Building…
Sencha, a leader in JavaScript developer tools for building cross-platform and enterprise web applications, is…