programming problem

Featured image for the post the power of refactoring

The Power of Refactoring: Transforming a Dashboard for Improved Load Time

In this post I am going to share an experience about refactoring a project that decreased the load time of a website.

Brief History

A few years ago, I was working on a project where I was tasked to improve the performance of a certain dashboard. Before I tell you the problem with the dashboard, let me tell you what it looked like. Mainly it was a mash-up of multiple charts to show some data points. When the page loaded, it used to show a loading screen and in the background, it used to make one single request to fetch those data. The backend would then query the database couple of times to generate around seven different data points (yes, because that’s how many charts were there). Once all the querying is completed it would return back the results to the front. It used to take around 10-12 seconds before we could see anything on the website. To put the cherry on top, it was the first page for an admin after the login. So even if the user wants to go to a different page for different work they had to wait before the entire page loads.

Although I am using the word frontend, it is not like a detached frontend. It’s a legacy application where each page was served by the server. However, in a few parts, the project was using JQuery to fetch a few data from API. (I did not know why some parts of the application use APIs and on the other hand some serve HTTP pages… I was not there when they made this decision).

Do we make it look faster or actually faster?

People used to complain about this dashboard a lot especially the slowness of that specific page and something had to be done. Eventually, we reached a conclusion to make that part faster!! Now here is the thing, you can either make things faster or you can make people feel that the site is getting faster. And we needed both. This requires a lot of refactoring.

A frontend framework for the reactive dashboard

To further improve the performance of the dashboard, we decided to use Vue.js to render the dashboard. Using Vue.js, we can take advantage of its reactive components to render the page quickly and provide an improved user experience. Additionally, Vue.js allows us to use virtual DOM, which helps to reduce the time taken to render the page. This allows us to update the page faster, providing users with a more responsive experience. Furthermore, Vue.js provides a number of features that can be used to further improve the performance of the dashboard, such as server-side rendering and code-splitting.

By using Vue.js to render the dashboard, we can ensure that the page is rendered quickly and efficiently, giving users a better experience. Now a lot of you might say, we could’ve used React or even Svelt instead of VueJS, but at that time, some of our devs knew vueJS a little bit more than any other frameworks. Which is why we choose that. Plus their way of making any page a vue app just by adding the CDN link was extra beneficial. That’s why we choose that.

Image about the power of refactoring for faster dashboard

the power of refactoring for faster dashboard

Splitting APIs

To further enhance the performance of the dashboard, we have employed a strategy of splitting the data into multiple APIs as opposed to serving it all together. This approach has allowed us to retrieve only the data that is necessary for the user, thus reducing the load time of the page. Moreover, the division of the data into multiple APIs has enabled us to reduce the processing time of the data, again leading to improved performance of the page. At the same time, we have been able to take advantage of caching, which allows us to store the data and serve it quickly, thereby reducing the time taken to render the page. In this way, we are able to ensure that users have access to the data in a rapid and efficient manner.

Change in UI to make it faster

The first approach was to serve an empty dashboard page when the user was logged into the site. We decided to use vueJS to fetch the data. Since we implemented 7 new API endpoints to get seven different data points, we made 7 parallel API requests. While waiting for a response, we only rendered 7 boxes with loading indicators. Whenever one of the data is returned through the API, the vueJS would update the graph and show it in the dashboard. Using this approach may have increased the number of network calls but we did not have to wait for the whole data to be fetched from the backend.

Since the empty dashboard was loaded at first, if the user wants to go to a different page they can go to that page from the navbar. These changes made the UI a little more responsive than before. Once that is done we moved to the next stage, which is using caching to serve data faster.

Implement caching to make response faster

Another strategy we have adopted to further improve the performance of the dashboard is to use Redis to cache the results. This means that the data is stored in Redis, which is a fast and lightweight database so that it can be retrieved quickly. Since Redis is in-memory data storage, it is able to store a large amount of data without consuming too much time, thus making it ideal for this purpose. Furthermore, since Redis is highly scalable, it is able to handle large volumes of data, making it an ideal solution for caching search results.

Redis is an open-source, in-memory data structure store that is used to cache data for faster retrieval. It helps to reduce the load time of search results by storing the result in memory, allowing users to access the data quickly. We decided to use Redis to cache the search results in order to improve the performance and reduce the time it took to query the database. Using Redis helped us to reduce the load on the database, saving time and resources.

In our case, the data in the dashboard did not have to be real-time updated. Instead, the requirement was like, as long as the data in the dashboard does not show any data that is more than 30 minutes old, they are ok with it. This made our work a little bit easier. We configured the redis in such a way so that the data expires within 30 minutes.

Here is an example code snippet using Node.js to set a value in Redis with an expiry of 30 minutes:

const redis = require('redis');
const client = redis.createClient();

client.set('myKey', 'myValue', 'EX', 1800, (err, reply) => {
  if (err) throw err;
  console.log(reply);
});

client.quit();

In this example, myKey is the key that we want to set in Redis and myValue is the value that we want to associate with the key. The third argument 'EX' indicates that we want to set an expiry time for the key, and the fourth argument 1800 sets the expiry time to 30 minutes (since the expiry time is measured in seconds).

The set method also takes a callback function that is executed when the operation is complete. If an error occurs, the error is thrown; otherwise, the reply from Redis is logged into the console.

Finally, we close the Redis client connection using client.quit().

So every time the frontend calls the APIs, we would check if the redis has any data about that, if there is we would just return that data otherwise, we would query the database and once we get the data, we would save the data in the redis with 30 min expiry and return that data as API response.

Conclusion

It’s not that hard to make the service faster, it was just a lot of rewrites. That is why I always tell people to think, is there a better way to complete a feature, before jumping into implementing a feature? Even if it may take more time right now to make it right, if we do not fix that, it will only consume more time to fix that later on.

Thank you for reading! What topic would you like me to write about next? Let me know and I’ll do my best to create a helpful blog post for you.

The Power of Refactoring: Transforming a Dashboard for Improved Load Time Read More »

Featured Image

Valid Parentheses | TypeScript Solution

In this post, I am going to talk about the Valid Parentheses problem, which you can find in Leetcode. For this problem I have used TypeScript to solve but you can use any language to solve this problem. It is fairly easy to solve. To solve this problem we need to use Stack. You can learn more about the stack data structure from here.

Full Solution for the Valid Parentheses problem

Valid Parenthesis problem solution

Check out my other solutions two sumValid Anagram and many more.

Valid Parentheses | TypeScript Solution Read More »

Feature image

Best Time to Buy and Sell Stock | Typescript Solution

In this post I am going to share how I solved the leetcode problem called Best Time To Buy and Sell Stock. Although this problem is marked as easy but if you do not understand how the sliding window works than it may seems a little bit tough.

What is Sliding Window

Let’s say you have an array or a list and your task is to find a suitable sub section of that array that satisfies a specific condition. For example, we can think that we have an array [1,2,3,4,5,6,7]. We need to find a subset (a portion of an array) where the addition of all the item is 7. In this scenario, let’s say the subset should contain only 2 items. Whenever we say a subset, most of the times it means those values should be together, side by side. That’s how I determine if I can solve a problem using Sliding window. You can take any two of them that are side by side and check if there sum is 7 or not. Here is a representation below for better understanding.

In here we follow this steps:

  1. Take index 0 and 1, Is there sum equals 7?
  2. If no, take index 1 and 2 and check again
  3. if no, take index 2 and 3 and check again,

We continue to do it until we reach the end of the array or whenever we the condition is satisfied

Ok got it. Now how can we solve the best time to buy and sell stock problem?

Now, In our case, we are supposed to do the same thing to solve this problem. We need to find out a sub array where the max amount of profit can be made. Or in other words, find a sub set of array elements that produces the highest number of value but adding them together.

So we at first set the left index as 0 and the right index as 1. We also assume that the max is 0. The left index is yesterday and the right index is today. Notice that we can not go to the previous day in stock price calculation. So whenever we see that the price of today is lower than whatever value we have in the left index, it means we are making a loss. If we are making a loss that we do not need to check any further. We point the left index value to the right index and start continuing from there again. And we continue to increase the window size. But if we see that we are making profit, we check if it the the max so far or not and store it based on that result.

Once we go through all the value we will have the max profit we can have. I have added a nice little animation to show how it works in action.

Animation of using sliding window to solve the problem

Full solution

Solution for Best time to buy and sell stock
Solution for the problem Best time to buy and sell stock

Check out my other solutions two sum, Valid Anagram and many more.

Best Time to Buy and Sell Stock | Typescript Solution Read More »

Feature image

Valid Palindrome – Leetcode | TypeScript Solution

In my previous post where I discussed about the two sum problem, I told that the solution for the Valid Palindrome and anagram are somewhat similar. However, the palindrome is much more easier than anagram. In this problem, we have to know if a phrase is a palindrome or not. For those who do not know what is Palindrome, “A phrase is a palindrome if  it reads the same forward and backward, after removing all the spaces and non-alphanumeric characters and it shouldn’t be case sensitive. “

From the definition, we can understand couple of things

  1. We have to transform the given text to either lowercase or uppercase
  2. We have to remove all the spaces
  3. We only need to get the words no extra non alpha characters


So we will first transformed all the characters to lowercase by using a lodash function called lowerCase. Once that is done, we will remove all the spaces by writing the below code

 const removedSpaces = lowerCase.split(' ').join('');

Once that is done now we have to remove all the extra non-alphanumeric characters. I was looking at the lodash library with does have a very good function called words. I really liked the functionality so I used that one. Now that I have removed all the clutter, all I have to do is to reverse the original string and check if the original and the reversed string are same. I have wrote the whole code in TypeScript and added it below.

Solution

Solution for the Valid Palindrome
Solution for the valid palindrome

Hello readers, If you are like me who wants to get better at coding, please check out my other blog posts where I solve other leetcode problems.

In the next post, I am going to solve 3Sum problem. You can also check out my other blog post as well.

Valid Palindrome – Leetcode | TypeScript Solution Read More »

Feature image

Two Sum – Leetcode Solution using JavaScript

Hello everyone. In this post, I am going to solve Two Sum problem from leetcode. This problem is related to arrays and hashing.

In this problem, given a target value, we have to find out the indices of the two numbers such that they add up to target. So for example if the array is [2,7,11,15] and the target is 9, then we have to return the index value [0,1]. Because the index value of 0 and 1 is 2 and 7. the addition of 2 and 7 is 9.

I solved the problem using JavaScript and I went with the straight forward way to solve it. It passed the submission! That’s why I did not think about any optimization or any other solution.

To solve this problem, I created a loop and inside that loop I created an inner loop. Basically checking every combination until I get a match. I do not think I need to explain any thing for this code. Please take a look at it and if you have any problem understanding please comment on the post. I will try my best to explain.

Solution

Two Sum Solution using JavaScript
Two Sum Solution

Hello readers, If you are like me who wants to get better at coding, please check out my other blog posts where I solve other leetcode problems.

In the next post, I am going to solve Valid palindrome. Although It is similar to Valid Anagram, if you face trouble check out my solution. There are a few slight changes in the condition.

If you like my solution, please check out my other post about various leetcode solutions. If you want me to solve any other leetcode problem, feel free to comment it below.

Two Sum – Leetcode Solution using JavaScript Read More »

Valid Anagram Feature Image

Valid Anagram Solution | Typescript | Leetcode problem

In this post, I am going to solve the Leetcode problem called Valid Anagram and provide solution using TypeScript. In this problem, given that we have 2 strings, we have to tell whether they are Anagram or not. For those who don’t know, An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Though process for the valid anagram problem

Before trying to solve we can find a few clues about anagrams.

  1. As I stated earlier, both of the string will have same amount of letter.
  2. The number of letter occurrences will be same.

To solve a problem, I always check for the simple conditional part. That way, I can take out the obvious test cases which would fail. In this case, I need to check both of the strings are of same length. If not, then they are not anagram. Plain and simple. Which is why I wrote this line in the beginning of the code.

if(s.length !== t.length) return false;

For the second point, we need to check how many times a character/letter used. So I wrote a simple for loop that basically checks every character one by one and they it checks in it’s own dictionary to see if that was used before or not. If yes, I increase the value by one. If not, I add a new property in that dictionary. (Note: In JS/TS there is no direct way to use dictionary like python/C#, so we have to create an object and use it like a dictionary). Here is the code for that.

for(let i = 0; i<text.length; i++){
        const ch = text.charAt(i);

        if (ch in dict) {
            dict[ch] += 1;
        } else {
            dict[ch] = 1
        }
    }

I encapsulated the dictionary creation part into a nice little function so that it is easier to read the code. Once I am able to create the dictionary for both the original and the test string, I called a lodash function called isEqual. It performs a deep comparison between two objects. Here is the full code for the valid anagram solution.

Full Valid Anagram Solution

function isAnagram(s: string, t: string): boolean {
    if(s.length !== t.length) return false;
    
    const input = getDictionary(s);
    const testInput = getDictionary(t);
    
    return _.isEqual(input, testInput);
};

function getDictionary(text: string) {
    let dict: { [letter: string]: number } = {};
    
    for(let i = 0; i<text.length; i++){
        const ch = text.charAt(i);

        if (ch in dict) {
            dict[ch] += 1;
        } else {
            dict[ch] = 1
        }
    }
    
    return dict;
}

Hello readers, If you are like me who wants to get better at coding, please check out my other blog posts where I solve other leetcode problems.

In the next post, I am going to solve Two Sum problem. In the meantime, you can checkout the post I have written on another problem called Contains Duplicate

Valid Anagram Solution | Typescript | Leetcode problem Read More »

Contains Duplicate solution using JavaScript

Contains Duplicate | Leetcode problem

In this post, I would like to talk about one of the most easiest problem you can see in the leetcode. In this problem, we have to tell whether an array contains duplicate value or not. The link to this question is here. Note that, the given array is all integer. Below I will give a short explanation of the leetcode problem solution.

Thought process to solve the problem

Whenever, I face a situation where I have to find if there is any duplicate or not (we are not finding out which one is the duplicate one, just if there is any identical value or not), all I do is to check the length of the array at first. Then I convert the array to a set. Note that a set can not contain any repeating values. Once it is converted to a set, I just check if the length of the set is same as the array or not. if yes, then there is no duplicate, if no, that means there is some duplicated value.

I have added the the JavaScript version of my solution.

Full Contains Duplicate Solution

var containsDuplicate = function(nums) {
    const uniqueSet = new Set(nums);
    
    if(uniqueSet.size === nums.length) {
        return false;
    }
    return true;
};

Obviously there are a lot of ways to solve the “Contains duplicate” problem. Like maybe you can use a loop (like, for, while etc) to check if there is any repeating values. But it will not be efficient. As for this kind of problem we should focus on finding the best solution.

Thanks again. In the next post, I will talk about another leetcode problem solution called Valid Anagram using JavaScript. Stay tuned.

Contains Duplicate | Leetcode problem Read More »