In the realm of software development, speed is a critical factor. Whether you're engaged in intricate data analysis, rendering graphics in a video game, or simply waiting for a webpage to load, sluggish performance can be a major source of frustration. This challenge was no stranger to us when we embarked on the optimization journey for a program similar to Uber, in collaboration with one of our partners. Their request was clear: identify bottlenecks and elevate the overall performance.
Our goal was not just to shave off a few seconds but to metamorphose this slowpoke into a high-speed performer, seamlessly aligning with our needs and expectations. The journey began by implementing monitoring and metrics solutions, introducing load testing, and constructing extensive end-to-end tests to meticulously track application performance and troubleshoot issues.
Upon analyzing the results, we uncovered significant performance killers and identified various suboptimal practices. Here are some key findings:
- The backend's use of a state, especially during driver searches, necessitated frequent interactions with the database for data integrity.
- Implementation of power-hungry scheduled services, impacting overall efficiency.
- Lack of caching for frequently accessed parameters and complex calculations, leading to unnecessary computation.
- Use of lock mechanisms in the backend, causing bottlenecks.
- Heavy use of non-ES6 modules resulting in a large bundle.
- Synchronized checks on startup leading to performance issues.
- Inefficient data handling during large data calls, causing system slowdowns.
Steps Taken for Optimization:
- Utilized Redis to manage the queue efficiently, triggering the next offer if the current one was declined.
- Employed sampling instead of sockets, enhancing data communication with push tokens for client updates.
AWS Lambda Integration:
- Developed AWS Lambda functions for non-core functionalities, leveraging the benefits of AWS Lambda.
- Implemented a more generalized approach for calculations, stored in cache to optimize drive searches.
- Introduced a Redis database for drivers, shifting from global locks to driver-specific locks.
- Implemented a CDN and used Signed URLs for secure and efficient image updating and display.
- Redesigned Data Transfer Objects (DTOs) to cater specifically to frontend requirements, reducing response payload.
- Transitioned to more efficient libraries, such as date-fns, to improve overall performance.
- Consolidated necessary calls and optimized asynchronous operations to enhance overall efficiency.
Frontend Performance Enhancement:
- Implemented dynamic paging with FlatList, getItemLayout, and onEndReached, optimizing data retrieval and display.
These strategic interventions have not only addressed the identified challenges but have also elevated the program's performance, aligning it seamlessly with user needs and expectations. The journey towards optimization is an ongoing one, but these steps mark significant progress in the pursuit of a faster, more efficient software experience.