Learn how to build a robust and interactive loading progress bar that tracks images, API calls, and other assets to deliver a seamless user experience.
While developing the my platforms (my version of
linktree), I realised my initial loading mechanism, which relied on
my customised docReady, was not cutting it. It missed out
on crucial elements like external images and API calls, leading to an
inconsistent loading experience. I knew I needed a more comprehensive
solution—one that would track every resource seamlessly, ensuring users
experience a smooth, uninterrupted progress bar.
Step-by-Step Breakdown
of the Solution
1. Dynamically
Track All Resources: Images and APIs
The first thing I addressed was dynamically collecting all resources
that needed to load—images, API calls, and any external assets.
This snippet collects
all the images on the page dynamically and ensures that every image is
tracked for loading.
2. Incremental Progress
Calculation
To ensure smooth progress tracking, I calculated the progress
percentage based on the total number of resources (images + API calls).
For every loaded resource, the progress is updated.
Key Concept:
Total Resources: Total number of images + API
calls.
Loaded Items: Track loaded resources and update the
percentage accordingly.
This ensures that every
time a resource is loaded, the percentage updates progressively.
3. Smooth Progress with Delays
For a polished user experience, I added delays and smaller steps to
the progress increments. This ensures that even with a fast network, the
bar doesn't jump directly to 100%.
Key Concept: Adjust the delay based on
progress—slower increments at the start, faster towards the end, but
always smooth.
This snippet ensures
that the progress bar moves smoothly, even for faster connections.
4. Tracking API Calls
In addition to images, I also needed to track API calls. I
implemented a simple wrapper around fetch() to ensure each
call was accounted for in the progress.
This function tracks
each API call and updates the progress bar as soon as the response is
received.
5. Debugging for
Accurate Progress Tracking
Throughout the implementation, I used logging to debug issues like
overshooting the progress (going beyond 100%) or not reaching 100%.
Debugging helped fine-tune the logic for a more reliable progress
bar.
// Start tracking resources (images and API calls) conststartTrackingResources = async () => { const images = getAllImages(); // Automatically fetch all images from the DOM
log(`[DEBUG] Total initial resources to load: ${totalItems} (Images: ${images.length}, APIs: ${apiFetches.length})`);
awaitPromise.all([...imagePromises, ...fetchPromises]); updateLoadingProgress(); // Final call to ensure progress reaches 100% };
// Start tracking resources when DOM is ready document.addEventListener('DOMContentLoaded', startTrackingResources);
Preview
Final Thoughts
Creating a dynamic loading bar might seem like a small detail, but
I've found that it makes a huge difference in how
smooth and polished the overall experience feels for users. Whether it's
tracking images, API calls, or other external assets, having everything
run seamlessly creates that subtle, yet important, sense of reliability
and care.
Of course, this is just one approach, and I know it's definitely
NOT the best or only way to do it. I'm always learning,
and I'm open to feedback from anyone who's more experienced! 🙌
I'm sure there are tons of ways to make this even better, and I'd
love to hear how the pros out there tackle similar challenges.
If you've done something similar or have tips to share, feel free to
drop a comment below. Let's learn from each other and keep improving our
craft! 🤩