How Shopify Improved its App Performance and More
🎬 S2:E03 Speed, Security and Systems
"Talk is cheap. Show me the code." - Linus Torvalds.
Hey, TechFlixers!
Did you know? The concept of Lazy Loading dates back to principles used in early computing to optimize resource usage. This week, we dive into how modern applications like Shopify leverage such time-honored techniques to boost performance, all while navigating the bustling streets of today's tech advancements.
🔦 Spotlight
📢 How Shopify Improved Its App Performance
When Shopify migrated its app to React Native, they noticed some performance drops.
Here are the key issues noticed and how they fixed them:
Showing more information than required on the initial page load. Items outside of the viewport need not be shown immediately.
To solve this, they implemented the LazyScrollView, which renders only what’s visible on the screen. It reduced the load times by 50%.
Waiting for all queries to finish to render the home screen.
To optimize this, they simply excluded waiting for any queries that fetched data that need not be shown in the first paint of the screen.
Inefficient list rendering wastes resources by rendering more items than are visible.
To optimize this, they used Flashlist, rendering only items visible on page load without scrolling.
They rewrote all screens as lists using ListSource tools based on FlashList, focusing on rendering only visible elements.
Doing a lot of unnecessary work that could have been avoided, like:
Some screens were getting updated for no reason during navigation. To solve this, they implemented logic to freeze everything in the background.
They used Restyle to manage themes, which created more unnecessary objects. This was optimized accordingly.
Wrote custom code to enable “Batched state updates.” to streamline state management better.
Not using the cache properly. To optimize further, they implemented the following:
Shopify App identified that only 50% of users benefited from cached data, particularly on essential screens like the home page. By addressing a flaw in their GraphQL cache system, they successfully increased cache hits by 20%, significantly enhancing user experience by ensuring faster data retrieval.
They also implemented a pre-warming strategy (Proactively loading data likely to be requested based on user behavior and common usage patterns into the cache), targeting critical screens. This approach led to 90% of users accessing data from the cache first, notably reducing network-induced lag and improving load times.
The end result: Reduced app launch time by 44% and screen load times by 59%.
Other interesting reads
☕️ Tea Time
News you might have missed
Starcoder 2, a model specialized for coding tasks, is out.
Who’s Hiring?
Flipkart and Microsoft have recently opened a bunch of positions in India. Check out these LinkedIn posts to directly connect with these firms' hiring managers or employees.
Flipkart
At the time of writing this, 20 technology openings are listed for their Bangalore office.
Microsoft
There are over 400+ openings listed on their careers page for software engineers in India.
A good strategy would be to identify the hiring team and manager from the JD of a relevant role and contact them on LinkedIn for a referral.
🚀 Power Up
Let’s explore two concepts that come up in almost all system designs. Let’s build INTUITION on how to think and navigate through various approaches.
Load Balancing
In simple terms, load balancing is all about spreading incoming requests across multiple servers. This helps with:
Avoiding Overload: Prevents any one server from getting too many requests, which could slow down or crash the system.
Staying Up and Running: If one server fails, others can take over, keeping the service available without interruption.
Handling More Users: This makes adding more servers to support more users or heavy traffic times easier.
Using Resources Wisely: Ensures all servers are used efficiently, avoiding situations where some servers are idle while others are overworked.
Popular algorithms and use cases.
Round Robin: Good for when all servers are equal in power. It simply rotates through the servers, sending one request to each in turn.
Least Connections: Picks the server with the fewest current tasks. Great for when tasks vary a lot in how long they take.
IP Hash: Uses the user's IP address to pick a server, keeping a user consistently connected to the same server. Useful for maintaining user session data.
Weighted Algorithms: Assigns more tasks to stronger servers. It is ideal when servers vary in processing power.
Least Response Time: Choose the server that responds the fastest and has the least ongoing tasks. Perfect for high-performance needs where quick responses are crucial.
Forget about software and tech for a moment. Imagine that you have a lot of luggage. You have a limited number of bags. How can you come up with a way to pack your bags efficiently? If you figure that out, you will easily figure out load balancing, even without any prior context, with just the first principles and fundamental thinking.
Caching
Basically, it is a process of using temporary storage to keep the most frequently used data for easy access. You put the files that you access more frequently on your desktop. You put your most frequently used clothes separately in your wardrobe compared to the rarely used ones. Many things you do in your everyday life already follow a principle similar to caching.
Speeding Up Response Times: Data fetched from a cache is much faster than data retrieved from the primary storage location, such as a database or an external API.
Reducing Load on Resources: By serving repeated requests from the cache, it reduces the load on databases or external services, helping to prevent overloading and downtime.
Improving User Experience: Faster data retrieval leads to quicker response times for users.
Cost Efficiency: Reducing the number of calls to external APIs or databases can lower operational costs, especially where these resources have rate limits or associated costs per query.
Popular caching strategies and use cases.
Least Recently Used (LRU): The stuff the system rarely access is thrown out. Suitable for applications where recent data is accessed more frequently. For example, you can put the posts made by people today on a social media platform into a cache and remove all the posts from weeks ago.
Most Recently Used (MRU): Throws out the most recently used data in favor of old data. Think of a streaming platform like Netflix, for example. If you watched a movie today, it is unlikely that you will watch it repeatedly in quick succession. It can be thrown out of the cache in favor of some older or different content you might watch.
Time To Live (TTL): Data is stored for a predetermined period. After the TTL expires, the data is removed or refreshed. Ideal for data that changes at known intervals, such as weather information.
When thinking about using a cache in a system design, here are the questions to ponder:
What data is accessed frequently and needs to be cached?
What rule should you follow for removing data from a cache to make space for new data?
How do we ensure the cache data is efficiently consistent with the source data? If the source DB is updated, the cache must also be updated.
Think of your own memory. How do you ensure that you remember the important stuff? You probably make notes and keep them easily accessible. You might come up with some creative ways, like using sticky notes. You might have a WhatsApp group where you dump all the important links, files, and information. How do you optimize things for your own memory? You are already using caches in your everyday life. Start from there and think through the fundamentals of applying it to a computer system and the data it processes.
📨 Post Credits
Fin.





