Improving Web Application UI Performance

Improving performance is essentially a process that minimizes / optimizes the data that users download. Understanding how browser renders resources is a prerequisite to ensure that the code you write (and third-party code you include) runs as efficiently as possible. After improving code efficiency, you need a way to test it.

Do think about scale

Local development environment may not have realistic data. But it’s a different world in production. For example, for an app performance monitoring dashboard, these are only a few of the things that keep happening in the background at all times:

  • Agents report and rollup data and metrics.

  • Data are written into and retrieved from databases.

  • Health rules are constantly being evaluated.

  • Multiple users consume the UI which causes further load on databases.

You can imagine the workload of controller. All these will slow down the app when deployed at a large scale.

Understand the Critical Rendering Path

A helpful glance

Look for high-performant solutions within the language framework

For example, practices introduced in Speeding up AngularJS apps with simple optimizations are worth applying to the whole product and being standardized.

Render summary data first, then details

Render a sketch of the whole visualization first. Render a summary of the data and then fetch from server more detailed data for charts, health status and so on — in most cases we can make asynchronous calls for all of these. This way user doesn’t have to wait for all the data to come at once and at least they see some data flowing in. It improves the perceived performance at the very least.

On-demand controller loading & data fetching

Along similar lines, if the page has sub-views, or hides details from user and shows them only on click, you don’t need pre-fetch. In fact, complicated UI/visualization should really be a layered design as users can’t possibly consume too much information at once whatsoever. Sometimes user may be interested in only the “Top N” of things.

Always try to use batch operations

Always ask the backend team to provide batch APIs.

For example this has bad performance: entityIds.forEach(id => { getUiService().getEntityById(id); }) because getEntityById() in most likelihood will make 1 database call. Imagine how slow it is to make 1000 separate database calls. Instead there should be a batch API: getUiService().getEntitiesByIds(entityIds)

Then on the UI side, you could use queued batcher combined with buffered renderer to make batch calls for only what is in current view (calculated based on user’s scroll position for example).

There could also be improvement on the infrastructure you use to store data, which will affect the querying speed of data on the backend. For example, elastic search is generally much faster than querying a SQL table. But as a UI developer, there is probably not that much you can do on this side.

Honor view specific options on the backend

The backend should ideally have an API which will take in view (show/hide charts, for example) and filter options and query the databases with those UI-specified options. For example, there are 500 databases, out of which 100 are Oracle. If the user has persisted the filter as ‘Show only Oracle databases’, the backend ideally should get only the 100 databases and return to the UI. Getting all 500 and then filtering out the other database types on the UI side is good for the UI but not good for performance.

Performance testing

Understanding Low Bandwidth and High Latency – It’s important to understand what using your app or site feels like when connectivity is poor or unreliable, and build accordingly. A range of tools can help, see here and here.