Showing elements to infinity — and beyond!

Kfir Zuberi
WalkMe Engineering
8 min readMay 27, 2018

--

In a previous article, we talked about how we can improve performance by using debounce and throttle techniques. In that case, these techniques solved a performance bottle neck arising from including small data sets in our app. In this article, I’ll show you how we tackled a performance issue that arose from including a large dataset in our app. How large? I’m glad you asked! Infinitely large. Along the way, I’ll provide examples of techniques I used to improve performance in the process.

Although by using debounce we can reduce the amount of rendering and scripting, the debounced function will still be called once. When it comes to rendering big datasets, this function call might be heavy... Especially on IE.

So how do we handle rendering a large number of elements? The answer is pretty simple: don’t! That is, don’t process all the elements until you need to.

When you handle big data sets, it is mostly useless — or even impossible — to put all the data in the user’s viewport at one time. So why process the parts that the user can’t view? (This is rhetorical… we shouldn’t!) Let’s just process them on demand. While we could use pagination to achieve this, today we will talk about a different solution: scrolling.

A scrollbar is an interaction technique or widget in which continuous text, pictures, or any other content can be scrolled in a predetermined direction (up, down, left, or right) on a computer display, window, or viewport so that all of the content can be viewed, even if only a fraction of the content can be seen on a device’s screen at one time (Wikipedia).

Scrollbars generally come in three varieties: regular scrollbar, infinite scrollbar (also known as endless scrollbar) and virtual scrollbar. each one has unique features that we should consider before choosing which type to use in our application.

To begin, I’ll briefly discuss the scrollbar type present in most web browsers by default: the regular scrollbar.

The regular scrollbar

This is the default scrollbar that comes in most web browsers. With the regular scrollbar, we can call scrolling functions such as handle page and content scrolling, get scrollbar position and bind-to-scrollbar events.

The regular scrollbar has both UX and performance benefits: UX-wise, it allows us to present a lot of data inside a set-height, set-width element (e.g., large lists). Performance-wise, because some elements are hidden from view, it reduces the time needed for the Paint and Composite phases of the Critical Rendering Pipeline (albethey the the less heavy parts in the pipeline).

The Critical Rendering Pipeline. We shorten the last two phases with the regular scrollbar
Regular scrollbar demonstration. Note that all elements exist in the DOM when the page loads

Basic usage

The CSS property overflow controls the regular scrollbar’s visibility:

/* css overflow */
/* overflow can be visible | hidden | scroll | auto */
body {
overflow: scroll;
}
div {
overflow-x: hidden; /* Hide horizontal scrollbar */
overflow-y: scroll; /* Add vertical scrollbar */
}

The regular scrollbar has a JavaScript API that allows us to scroll to any position…:

// scroll to specific position
window.scrollTo(500, 0); // (x, y)
// scroll from the current position the given offset
window.scrollBy(100, 0); // (x, y)
// the jQuery style:
$(body).scrollTop(300);

…and to listen to scroll events:

window.addEventListener('scroll', onScrollHandler);function onScrollHandler() {
console.log('scroll position ' + document.body.scrollTop);
}
// the jQuery style:
$(window).scroll(function() {
console.log('scroll position ' + $(body).scrollTop());
});

There are many libraries that implement the regular scrollbar functionally, and some give us alternative scrollbars such as the perfect-scrollbar, SimpleBar and gemini-scrollbar.

A suggestion: before picking a library, read the implementation and check if it fits your application. some libraries may tax you with performance issues.

It seems like regular scrollbar gives us everything we need to use and control scrolling. Perfect! So why do we need different types of scrollbars?

Although we cut corners on the Paint and Composite phases, the more costly parts of the Critical Rendering Pipeline are JavaScript and Layout — and the regular scrollbar does not help us with these. When using the regular scrollbar, all elements are appended to the DOM, including elements that are outside of the user’s viewport. This means that the browser is managing all events, rendering and styles, even those of DOM elements the are not in the viewport!

The following scrollbars solve the scripting and rendering issues, and each has its own use cases.

The infinite scrollbar

The infinite scrollbar enables Infinite scrolling. Infinite scrolling, also known as endless scrolling, or unpagination, is a technique where additional content (e.g., additional data that comes in with AJAX calls) is appended dynamically to the bottom of the page or to the container as the user approaches the end of the content. You may have seen this technique on the Facebook timeline or on Pinterest’s homepage.

The advantages are very clear: The elements’s rendering and appending will be handled only if and when the user needs it. If the user doesn’t reach the end of the viewport, data that is not in the viewport won’t be loaded and handled.

Many libraries implement the infinite scrollbar. This is an example of my implementation:

Infinite scroller implementation

And here’s one way to use the infinite scrollbar:

Example of how to use the infinite scrollbar

Here are some popular libraries with the infinite scrollbar:

For jQuery frameworks — infinite-scroll

$('.container').infiniteScroll({
// options
path: '.pagination__next',
append: '.post',
history: false,
});

For Angular framework — ngInfiniteScroll

<div infinite-scroll="myPagingFunction()" infinite-scroll-distance="3"></div>

For React framework — react-infinite-scroll

<InfiniteScroll>
pageStart=0 loadMore={loadFunc} hasMore={true || false}
loader={<div className="loader">Loading ...</div>}>
{items} // <-- This is the "stuff" you want to load
</InfiniteScroll>

So, we reduce the DOM element count, and we save time and memory in the browser’s element handling. What’s the problem?

The two main issues here are largely UX-based:

The first — the scrollbar is often used to provide a sense of how many objects remain in a list and your current position in the list. This is lost with the infinite scrollbar, since the scrollbar always shows the position relative only to the elements processed thus far.

The second issue is that appending the elements to the end of the viewport causes a lurching effect that negatively impacts the UX (see example below).

Example of the infinite scrollbar’s lurching effect :(

But fear not! This UX issue is solved by the final scrollbar we’ll consider: the virtual scrollbar.

The virtual scrollbar

The virtual scrollbar is similar to the infinite scrollbar with one important difference: it must contain the data set length in advance (thus, it is not infinite). The algorithm essentially calculates the height (or width, in horizontal scroll) when the data loads and then shows the scroll as if all the elements are there. This solves the aforementioned infinite scrollbar UX issues and might even improve performance a bit.

There are three flavors of virtual scrollbar implementation:

  • Object pool — based on “Object Pool” design pattern. A small subset of DOM elements are rendered and reused as the user scrolls down the page;
  • Use, drop and recreate — Recreates the DOM elements each time they are in the viewport, and releases them once they leave;
  • Just leave the elements — As in infinite scroll, creates the elements as they come into view.

Unlike with the infinite scrollbar, with the virtual scrollbar, the scroll’s size is calculated before appending the elements, and the scrollbar’s UI always represents the content’s true position on the page. The calculation: (index-1)*height is made by multiplying item-height by item-count. Each element gets an absolute position over the padding layer, and is offset from the top padding according to the element index.

As an example using the above figure, let’s say that each element’s height is 10px; the element “list item #35” will get position: absolute and top: 34*10px.

There are several libraries for virtual scrollbar, such as Angular’s virtual-scroll, Ionic’s VirtualScroll and virtual-list.

One word of caution: In order to give the true effect of scrolling using the virtual scrollbar, you must set the correct position of each element. If you have non-constant or unknown heights for the list elements, then you should either use infinite scrollbar or realize beforehand that the virtual scrollbar will come with a computational complexity performance cost.

How do we choose the scrollbar technique that best fits our needs? Here’s a real life example

After receiving negative feedback from IE users, I investigated how we could reduce layout rendering and shorten the opening time of WalkMe’s Player Menu.

I loaded 1000 records into the menu, monitored the process of opening the menu, and compared the results of the regular scrollbar with those of the infinite scrollbar. Here are the results:

Performance monitoring with regular scroll
Performance monitoring with regular infinite scroll

Instead of wasting time rendering elements that probably wouldn’t be relevant to the user, we loaded only 20 elements at first and loaded the rest as the user scrolled. By using this technique, we saved roughly 485ms of rendering time and DOM element management.

We didn’t choose the virtual scrollbar because we have elements of varying height.

Conclusion

Scrollbars are a must in most applications whose UIs include long lists. On the one hand, we have UX considerations, and, on the other hand, performance considerations.

It’s important to choose the best scrollbar for your application, and there are many factors you should consider: scrollbar styling, cross-browser appearance, whether you do or don’t know the count and height of many of your elements (if so, you can use the virtual scrollbar, and, if not, you should opt for the infinite scrollbar), and more. I hope this brief synopsis of the state of the scrollbar ecosystem helps you in your technical journeys!

--

--