Need a crash course on Bitcoin layers?
→ READ OUR FREE GUIDE
Need a crash course on Bitcoin layers?
→ READ OUR FREE GUIDE
Need a crash course on Bitcoin layers?
→ READ OUR FREE GUIDE
Need a crash course on Bitcoin layers?
→ READ OUR FREE GUIDE
Need a crash course on Bitcoin layers?
→ READ OUR FREE GUIDE

New Performance Improvements in the Stacks Explorer

We made the Stacks Explorer a lot faster and reduced the time users have to wait before interacting with pages by ~50%. In this post, we’ll talk about what performance optimizations we made.

Type
Product update
Topic(s)
Product
Published
July 3, 2024
Author(s)
Sr. Software Engineer
Contents

Better performance translates to a better user experience, and even milliseconds can make a big difference, particularly when we talk about milliseconds saved for a lot users. So far this year, more than 250,000 people have used the Stacks Explorer. 

If we can improve performance just a little bit, across that many users, we are putting a significant amount of time back in the hands of the Stacks community.

Diagnosing the Problem

When we decided to focus on performance improvements, we first had to identify what pain points existed. In particular, our goal was to optimize JavaScript bundles and reduce the initial JavaScript load time.

To find areas for improvement, we began by analyzing the initial JavaScript load for each page. Below you can see the benchmarks from that test:

As you can see from the data above, we discovered that some pages have a significantly higher JavaScript size compared to others. This insight allowed us to narrow our focus.

We then examined the dependency tree for each page to identify which packages contributed to the large bundle size. This process uncovered a few issues that needed to be addressed.

An Icon-ic Issue

We had been using multiple icon libraries, which negatively impacted both performance and UI consistency. Multiple icon libraries inflated the bundle size by including redundant code and assets. Additionally, it resulted in inconsistent UI, as they have varying styles and sizes. Here’s a couple of examples:

An example of a single page that uses Material Design, Lucide and Remix Icons
Another example for a page that uses multiple icon libraries including two instances of Material Design

To address this icon issue, we consulted with our design team and consolidated our icons to use a single library. We then replaced all instances of icons to ensure they pointed to our chosen library.

Redundant Libraries

Not all third-party dependencies are created equal. Some libraries, while convenient, may not serve a significant role in an application and can be easily replaced with a core library or native code.

An example of a page that has a dependency on the Bitcoin.js library, which was previously used to achieve a trivial functionality.

To solve this issue of dependency, we removed third-party dependencies whose functionality did not justify their overhead in terms of bundle size. Here’s how the dependency tree looks after eliminating these unnecessary bundles (both icons and third-party dependencies):

The Pitfalls of Excessive Code Splitting

Code splitting is the go-to strategy for developers aiming to enhance page performance by loading only the necessary code at the right time. However, this method had been overused in the Stacks Explorer.

There were so many tiny packages that were dependent on each other that it created a number of issues, including:

  • Overhead costs: Each chunk required an additional network request, which added overhead and increased latency, especially on slower networks.
  • Chunk duplication: Shared dependencies sometimes ended up being duplicated across multiple chunks, leading to an increased overall bundle size.
  • Runtime overhead: Each code split point introduced some runtime overhead to handle the dynamic imports.
  • User experience: Excessive code splitting sometimes led to poor user experience with too many small chunks being loaded sequentially, causing delays in rendering the page.
An example that demonstrates the cascading requests effect that happens due to excessive code splitting

To counter this problem, we strategically eliminated some of that code splitting in order to bundle these small packages together, resulting in fewer network round trips and a smoother user experience.

We also did a bunch of work with the API team on improving image delivery via new CDN caching (more on that in a different blog coming soon).

The Performance Improvements

These changes have led to significant improvements in the Stacks Explorer. To quantify the improvement, we benchmarked performance on two of the most popular pages: the home page and transaction pages.

The letter grade blends how fast a page performs (in terms of loading, interactivity, and visual stability) with how well it’s built for optimal performance. This grade reflects overall webpage experience as it accounts for both your front-end as well as the actual performance experienced by the user.

Total blocking time refers to how much time is blocked by scripts during the page loading process.

Explore the Stacks Blockchain

Try these improvements out for yourself on the Stacks Explorer! If you have any feedback, reach out to us on the #stacks-explorer channel on Discord under the Hiro Developer Tools dropdown.

Product updates & dev resources straight to your inbox
Your Email is in an invalid format
Checkbox is required.
Thanks for
subscribing.
Oops! Something went wrong while submitting the form.
Copy link
Mailbox
Hiro news & product updates straight to your inbox
Only relevant communications. We promise we won’t spam.

Related stories