Instagram Explains How It Improves Its Feed's Speed On The Web By 50 Percent

When the internet matures, coverage widens and speed increases, more and more people are becoming less patient.

In the modern days of the internet, people can be annoyed when the platform they're visiting delays too much. Instagram as one of the largest platforms for photo- and video-sharing, is also experiencing what all websites on the web experience: speed kills.

With about 1 billion users, Instagram grew slower as it ages.

"In recent years, instagram.com has seen a lot of changes — we’ve launched stories, filters, creation tools, notifications, and direct messaging as well as myriad other features and enhancements. However, as the product grew, one unfortunate side effect was that our web performance began to suffer."

While most of its users use its app, Instagram still has the responsibility to keep those users on Instagram.com happy.

"Over the last year, we made a conscious effort to improve this," Instagram added. "Our ongoing efforts have thus far resulted in almost 50% cumulative improvement to our feed page load time."

On its first blog post on how to make Instagram faster, Instagram Engineering, the team behind Instagram, outlines some of the work they did to improve the speed of the platform, noting that most are based on load optimizations and pre-fetching.

According to the post, these alone have reduced the time taken to load photos on instagram.com by 25%, while at the same time, also gave a 56% reduction in the amount of time users spend waiting at the end of their feed for the next page to show up.

"Correctly prioritizing resource download and execution and reducing browser downtime during the page load is one of the main levers for improving web application performance," said Instagram. "In our case, many of these types of optimizations proved to be more immediately impactful than code size reductions, which tended to be individually small and only began to add up after many incremental improvements."

The changes were also less disruptive to product development, requiring less code change and refactoring.

Going to the details:

Instagram.com - 18 July 2019

JavaScript, XHR, and image prefetching

The strategy involves Instagram is informing users' web browser as early as possible about what resources are required to load a page.

Web developers know what resources are needed for a website to load ahead of time. However, according to the post, most browsers may not be aware of those resources until late in the page loading process.

The resources in question, mainly include those that are dynamically fetched by JavaScript, such as other scripts, images, XHR requests, and so forth. The reason is because browsers may not be able to discover these kinds of resources until it has parsed and executed some other JavaScript first.

So instead of waiting for the users' browser to discover these resources themselves, Instagram.com provides a hint to the browser, notifying it to start working on fetching those resources immediately.

To do this, Instagram uses HTML preload tags for two types of resources on the critical page loading path: dynamically loaded JavaScript and preloading XHR GraphQL requests for data.

Preload HTML tag
Preload HTML tag

Benefits

Preloading resources allow users' browsers to fetch the needed resources to load a page, as soon as the page is accessed.

In addition to starting the download of resources sooner, preloads also increase the network's priority for async scripts. Usually, the priority for browsers to load async scripts is set to Low by default Using preloads, web browsers will put a higher priority on these scripts.

As a result, XHR requests and images in the viewport will have higher network priority, and images outside the viewport will also benefit from the same network priority.

Instagram.com without preloading
Instagram.com without preloading
Instagram.com with preloading
Instagram.com with preloading

Disadvantages

Preloads come with consequences.

In the post, Instagram noted that preloading resources can make critical scripts required for rendering the page to be blocked, or have to share bandwidth with other resources.

To anticipate this, Instagram suggests a careful use of preloads so websites can give an important level of control over how their developers want users' browsers to prioritize content during initial loads. But that is in cases where the developers know which resources should be prioritized.

The next problem is the extra control preloads provide.

In Instagram's example, when testing preloads in regions with very slow overall mobile and Wi-Fi networks and significant packet loss, the team noticed that preload scripts' network requests were being prioritized over the usual script tags of the JavaScript bundles at the critical page rendering path.

This resulted in an increase in overall page load time.

To mitigate the issue, "We were only putting preload hints for bundles that were going to be downloaded asynchronously as part of the current page by the client-side router," said the post.

Preloading just async route JavaScript bundles

Feed Optimization

Instagram is all about its Feed.

As the main attraction of the platform Instagram's Feed consists of an endless scrolling contents of images and videos. Instagram.com manages the process by loading an initial batch of posts, and to load more batch each time users scroll down the feed.

To improve speed, Instagram loads the next batch just and only before users hit the end of their current feed. This way, users won't have to wait for anything when they go the bottom of the feed.

Easier said than done, because this method can consume much of users' CPU.

Since users can be eager to scroll down endlessly, Instagram.com will quickly eat up users' CPU resources and bandwidth. On the other hand, if Instagram doesn't preload enough, users will frequently hit the end of their current feed.

To optimize how the Feed loads, "we display feed images using the img srcset attribute (which lets the browser decide which image resolution to use based on the users screen size). This means it's not easy to determine which image resolution we should preload & risks preloading images the browser will never use."

This approach was previously meant to prioritize task abstraction that handles queueing of asynchronous work. But in this case, it also works on Feed and how Instagram.com prefetches the next batch of feed posts.

"This prefetch task is initially queued at an idle priority (using requestIdleCallback), so it won’t begin unless the browser is not doing any other important work. However if the user scrolls close enough to the end of the current feed, we increase the priority of this prefetch task to ‘high’ by cancelling the pending idle callback and thus firing off the prefetch immediately."

Published: 
06/08/2019