NUS Healthcare Informatics Research Lab (HIRL)
Unfortunately, I cannot showcase images or reveal the applications' names until they move into full production, but they are remarkable projects that I am immensely proud of, and they look amazing as well - kudos to our designers. Will definitely update this as soon as I can!
At the NUS Healthcare Informatics Research Lab (HIRL), I led a team of five engineers to design and develop cutting-edge healthcare solutions. I contributed as a technical lead to a cross-platform mobile application for childhood obesity management and worked on a diabetes patient management portal.
Childhood Obesity Management Application
Collaborated with KK Women’s and Children’s Hospital to develop a mobile application for them, aimed at improving the health of 500+ children and parents. We used React Native, TypeScript and Firebase. This application included:
- A home page summarizing user progress and activity.
- Modules such as a sleep tracker, nutrition tracker, and activity tracker (integrated with Fitbit).
- Quality of Life questionnaires, a resources page linking to articles, and a missions and rewards system.
- Weight and height logging functionality to help users track growth metrics.
Key Contributions
- Designed the frontend architecture using React Native for a cross-platform experience, opting for bare React Native over Expo due to better Fitbit integration.
-
Implemented global state management using both React’s Context API and Zustand:
- Used Context API for managing user data across the app while avoiding prop drilling.
- Adopted Zustand for activity logs to handle React Context's re-rendering issues, ensuring better performance and granular control. In Zustand, you define a store with state and actions, and components can subscribe only to the specific slices of state they need. Redux, with a central store, was a good way to manage state as well, but would have introduced a lot of boilerplate code midway through the project.
-
Replaced useEffect with useQuery for data fetching to leverage:
- Declarative data fetching with automatic caching, background refetching, and error handling.
- Significant performance improvements with a "stale-while-revalidate" strategy, avoiding showing a loading screen every time data is fetched (smoother user experience).
- useQuery only triggers a re-render when the query key is invalidated, instead of re-running on every application mount.
- Integrated Firebase for real-time database synchronization, authentication, and serverless backend services (firestore, firebase functions). Chose NoSQL for flexibility as the data structure evolved over time, based on client requirements. Adopted denormalized Firebase database structures for faster reads and simplified queries.
- Researched and implemented Cloud Scheduler with Firebase Functions to mitigate cold start delays,
improving responsiveness by 25% for critical operations.
- What are Cold Start Delays?
- When a Firebase Function is invoked after a period of inactivity, the serverless environment needs to **spin up a new instance**, causing latency. An instance refers to a running environment (a lightweight virtualized container) where a function executes.
- This delay can range from hundreds of milliseconds to several seconds, impacting time-sensitive operations.
- How Cloud Scheduler Helps:
- Cloud Scheduler **periodically triggers the function**, preventing it from going idle.
- This keeps the function warm, reducing cold start delays when real requests arrive.
- Ideal for critical operations that require low-latency responses (e.g., scheduled tasks, real-time notifications).
- What are Cold Start Delays?
- Collaborated with the team to optimize CI/CD pipelines using Jenkins, reducing build times by 30%. Jenkins automates tasks suc as building, testing and deploying code.
Technical Challenges and Solutions
- Global State Management:
- React Context's unnecessary re-renders were mitigated by using Zustand for specific modules, ensuring efficient state updates and enhanced performance.
- Avoided Redux to minimize boilerplate, given the project's scale and timeline.
- Code Splitting: Dynamically loaded large dependencies to prevent blocking the main thread.
- What it is: Breaks the app into smaller bundles, loading only what's needed at a given time instead of shipping everything at once.
- Example: Using dynamic imports in React Native:
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
- Benefit: Reduces initial app load time and improves performance.
- Pagination with React Query (Infinite Query): Implemented infinite scrolling with
useInfiniteQuery
to fetch data in chunks, reducing initial load time and improving UX.- How it works: Instead of fetching all data at once,
useInfiniteQuery
fetches data page by page. - Under the hood:
- It uses the
getNextPageParam
function to determine the next page to fetch. - Automatically caches and deduplicates data to avoid redundant requests.
- Refetches in the background when the app regains focus.
- It uses the
- How it works: Instead of fetching all data at once,
-
Used the i18n libary to set the app to the selected preference language (passed on as context). Should have text
as JSON objects in a seperate files, eg en.json, ch.json. In future, if there are a lot of languages, could store
it in AsyncStorage for example.
- Library Customization: Some third-party libraries, like graph visualization tools, were insufficient for specific requirements. Customized these libraries to better align with the application's design and functionality, improving user experience. View the customized library on GitHub: React Native Gifted Charts Sai
Technologies and Best Practices
- Employed TypeScript for safer, maintainable code, reducing bugs in critical healthcare modules.
- Followed Agile Development with iterative feedback and detailed sprint planning via Jira, ensuring efficient team collaboration.
- Implemented pair programming, sharp commit practices, and thorough code reviews to maintain high-quality code.
Diabetes Patient Management Portal
Worked on a web portal aimed at assisting healthcare professionals in managing diabetic patients. My role included:
- Debugging and resolving over 100+ issues in the frontend.
- Utilized React.js and Ant Design to deliver a responsive and intuitive user interface.
Key Takeaways
- Mastered global state management with tools like React Context and Zustand.
- Gained proficiency in React Native for cross-platform app development.
- Learned about code splitting and pagination.
- Learned how Firebase works under the hood, such as in its optimistic concurrency control.
- Enhanced my understanding of CI/CD pipelines and agile development processes.