Why is my page taking 30 seconds to load? (common interview question)
Tags: programming, beginners, webdev, tutorial
Published: 2023-12-12 06:36:50

You log into your CRM dashboard or application backend, and all other pages load quickly within 1-4 seconds, however for some bizarre reason the dashboard page takes 30 seconds to load.

_Why?, How do I solve this problem?_

In this guide, we will go over a little thought experiment to solve one of the most common issues you will find in a real-world scenario.

## The stack

The techniques in this article will work with any stack, however, let's assume you have a React frontend that communicates with a Laravel Backend.

Requests are sent to a load balancer, which then round-robin distributes the request to 5 application servers.

Each app server is running PHP 8, with Laravel 10, and uses both Redis and MySQL as db backends. Redis - is used for caching and MySQL to persist the application data.

## What has changed?

This should always be the starting point if the issue occurred recently, especially after any merges or deploys - no matter how big or small the change is, and even if it doesn't seem related.

It's generally a good idea to just spend a few minutes reading through the changes to be 100% sure.

## Check your network requests

Usually - if you are loading some data when the component mounts in React, it could be that the API is taking too long to respond or you are making too many requests when the component is mounted.

If you notice a slow endpoint - then it's a backend issue.

If there are no slow endpoints but several API calls are firing too early and holding up the page load, then your issue is probably that you need to load just the essential data upfront and defer the rest until you need to load that data or consider a single endpoint that returns all the data needed if it's not too much information to process in one endpoint.

Lastly, if it's neither of the above. Perhaps an infinite loop or some buggy code holding up the page.

In this instance - just step through your code line by line from the component mount, through the render up until the page finishes loading. Usually, a step-through debugger works great for this problem, or a simple "_console.log_".

## Health Check

A couple of questions to ask?

1. Are all servers responding with the same or similar response time?
`if not - then this could indicate that one node has some hardware issue or is under more load than others. Check your load balancing, remove this server from the load balancer, and see if there's any difference. Ideally, you should have some sort of monitoring tool in place such as New Relic or Data Dog, etc... to pick up on anomalies.`

2. Is the issue intermittent - i.e. only occurs at certain times of the day?  
`Then it could be some background job that's putting pressure on your server at these times, thus making requests slower because it's either locking the DB or using too many resources.`

## Not a frontend issue and all servers are healthy, what now?

So you have established it's a slow endpoint and all servers are running fine.

When solving backend problems, especially relating to the sluggishness of API endpoints - this is usually an indicator that there is a DB query misbehaving.

Find the model that's generating the data and extract the SQL queries. Individually run these queries on your DB server and check the response time.

If one of the queries is taking too long, then you probably need to add indexes or rewrite the query.

Another issue that could be a problem, is if you are running a query in a loop.

If your loop has a thousand iterations, just a random thumbsuck number - can be 50, 100, or whatever - if it's a large enough amount, collectively even if a query on its own took 200ms - it all adds up to one blob of processing time that your API is sitting on for a few seconds thus slowing down everything else.

Even if you use async & await to parallel process these queries, you sending a ton of queries to the DB server(s), which can impact response times.

To solve this issue - you can use a JOIN or subquery instead or maybe have a background job run on a schedule to do these queries and cache them in Redis or a tmp cache table. 

Thereafter your API endpoint is just making one query to the DB instead of a thousand queries.

If all else fails, similar to the frontend approach - you should step through the code line by line and test at each stage until you find the line that's causing the sluggishness.

## Conclusion

The question at hand is broad, depending on the stack, what has changed, and various other factors - the route you take can vary.

There is no silver bullet, however the key to solving problems like this - is to systematically follow the flow of data backwards, and create a mental checklist of all the possible things that can go wrong.

Tick off possible breaking points one by one as you move through the stack, and eventually, you will find the problem.

Ultimately the key to problem-solving boils down to:

1. Knowledge - you need to invest as much time as possible to understand your stack as best you can, ask a lot of questions, read PRs and constantly upgrade your skill set.

2. Disaster recovery simulation. You may not be able to simulate most scenarios that can go wrong in production, however, you should write down a bunch of "What if?" questions and think about the possible disaster recovery plan you need to execute or where to look in your codebase. Furthermore, think about the debugging steps you need to follow.

3. Confidence - do you give up at the first sign of difficulty? you need to develop a strong "I can fix this" mentality. Even when you spend hours with no result, keep pushing through. It's okay to also ask for help but give yourself the chance to at least give it a good go.

4. Be systematic - break down and follow the trail of the data flow. You have to be methodical in your approach, going through each checkpoint step by step and analyzing one thing at a time.