Google Behavioral Question 7: Performance Improvement

🎯 Best Story: APNG Memory Optimization

Full STAR Answer (2.5 minutes)

Situation (30s)

While developing Event Effect feature (birthday celebrations) for LINE's 200M users, I found that the current APNG library used too much memory - about 500MB for full-screen animations.

The library was used for a long time in the app for important features like Sticker rendering (LINE's most popular feature). The problem wasn't found before because previous animations were small. My feature used large full-screen animations, which showed the problem.

The library was in-house, written in C++. To optimize CPU usage, it used an approach that decoded all frames upfront - multiply image size × number of frames = huge memory consumption. The animation just changed the index of the current frame and rendered the pre-decoded bitmap.

I also considered Lottie as an alternative, but profiling showed:

  • Memory: Still high (around 250MB, only 50% improvement)
  • CPU: Unacceptable - 70% initially, 20% during playback
  • This would drain battery and affect overall app performance

This memory issue would crash low-end devices serving millions of users globally.

Task (25s)

  • Optimize memory usage for my feature
  • Consider impact on other features using same library
  • Balance development time vs business impact
  • Avoid causing massive regression testing

Action (75s)

Evaluated 3 Options:

The first option was to fix our in-house library by adding Just-In-Time rendering. This would improve all current features automatically, but it had big problems. The library was used in important features like Stickers, so we'd need lots of testing. Since I didn't know C++ well, and this meant changing the whole structure (not just a few lines), this approach was too risky.

The second option was to find an existing open-source library that already used JIT rendering. This looked most promising because it would be already tested, probably well-maintained, and much faster to add. The main worry was making sure it was safe for production use, but the benefits were much bigger than this effort.

The third option was building a new decoder from scratch. This would fit our needs perfectly and look good on my resume, but it would mean I'd have to maintain it forever, take a long time to build, and need lots of testing. As an engineer, I needed to think about business value, not just personal achievement, so this became my last choice.

Detailed Investigation Process:

I started by searching GitHub for APNG libraries that used Just-In-Time rendering. When I found a good option, I didn't just look at the stars—I checked the contributors, looked at who was using it in real products, and most important, I read through the main code carefully to make sure the structure was good.

Next was the testing phase using Android Profiler. The results were amazing: memory usage went from 500MB to just 5MB—a 100x improvement! CPU usage was also good at 15% at start and 5% during playback, compared to Lottie's bad 70% and 20%. The visual quality was the same as our original library, and it used less battery.

For device testing, I tested everything carefully. I tested on different Android versions in emulators, on high-end flagship phones where it ran smoothly, and most important, on cheap entry-level devices where we saw no crashes and stable performance. I also tested on the most-used devices based on LINE's data, and everything worked well.

I also checked if the library was ready for production. I made sure it had active updates, good community support that fixed issues quickly, clear documentation, and MIT license that we could use. Finally, I made a detailed report with before/after screenshots, showing 1-2 weeks to add this versus months to build custom, and a risk report that showed low risk because we could test it separately.

Implementation:

  • Switched library for my feature
  • Created migration guide for other teams
  • Implemented Glide APNG loader to simplify adoption
  • Recommended app-wide adoption

Result (30s)

100x memory improvement - 500MB → 5MB

App-wide benefit - All APNG features improved (Stickers 80% less memory)

Adoption made easy - Migration guide + Glide loader

No crashes on low-end devices - stable experience for all users

Faster than building custom - 1-2 weeks vs months

Maintenance offloaded - OSS community handles updates

Learning: "Sometimes finding the right existing solution has more business value than building custom. Balance personal achievement with business impact."


Key Follow-Up Q&A

Q: "How did you convince other teams to adopt the new library?"

"I used several ways to help teams adopt the new library. First, I made it as easy as possible by creating a detailed guide with before/after code examples, building a Glide APNG loader that made adding it just one line of code, and offering to personally help any team who needed it.

The data was very clear and strong. I shared Android Profiler screenshots showing the amazing 100x memory improvement, showed how crash rates went down on cheap devices, and showed the better user experience with smoother animations. In our team meeting with all Android engineers, I showed a live demo of the performance difference and answered all technical questions.

My Event Effect feature was the perfect example—it was real proof that the solution worked in production. When the Stickers team saw these results, they started using it early, and their success made more teams interested.

What felt really good was that teams started contacting me on their own. Several engineers reached out for help with their specific situations, and I got thanks from colleagues who liked how thorough my research was and how the tools I made helped them. This natural interest made adoption much easier than trying to force the change.

Within 6 months, most APNG features had moved to the new library.

The principle: Change management requires reducing friction and proving value."


Q: "Why didn't you choose Lottie, which is more popular and widely adopted?"

"Although Lottie is well-known as the industry standard, the testing data clearly showed it wasn't right for our specific case. The performance problems were big: memory usage was still around 250MB, which only gave us 50% improvement when we needed much better results. Even worse was the CPU usage—70% at startup would basically freeze the app, and the 20% continuous usage during playback would drain batteries very fast.

From a business view, this was a big problem because LINE has users all over the world, many using cheap Android devices. High CPU and memory usage would give bad experiences to millions of users, maybe causing them to stop using the app because of crashes and slow performance.

The technical truth is that Lottie works great for small UI animations, but our case needed full-screen effects—basically different tools for different problems. I made a choice based on data and our specific needs, not just following popular trends.

The principle: Profile first, decide based on data. Popular doesn't always mean suitable for your specific use case."


Q: "How did you balance personal achievement vs business impact in your decision?"

"This was an important learning moment for me about choosing between personal goals and business value. The personal path was tempting—building a custom APNG decoder from scratch would have been a big technical challenge and great for my resume. I could have said 'I built a high-performance animation library,' which sounds impressive.

However, the business path meant using an existing open-source solution, which meant faster delivery, less maintenance work, and more time for actual feature development. When I compared the options, the difference was clear: two weeks versus two-plus months for development, low risk with a tested solution versus high risk with new code, community maintenance versus me maintaining it forever, and the team getting a solution much faster.

I used simple questions to decide: Will this create more value for users? Will this free up team resources for other important work? Am I solving the right problem or just showing off? The answers were clear.

Interestingly, choosing the open-source solution actually made my reputation better in the team. They saw me as someone who solves problems practically, not someone just trying to show off technical skills.

The principle: Great engineers optimize for business outcomes, not personal glory. The best solution is often the simplest one that works."


Q: "What was your risk mitigation strategy for adopting an external library?"

"I created a complete plan to reduce risks from many angles. For technical risks, I started with a test version in a separate branch, kept the original library as backup, and planned to roll out slowly with A/B testing on a small percentage of users first.

Security was very important because LINE has 200M users. After I did my own careful code review of the whole library, I asked our security team to do a formal security review. They checked the library for possible security holes, memory safety problems, and any suspicious code. Only after they approved did we move forward. We also set up a process to watch for security updates from the open-source community.

For maintenance risks, I created our own copy of the code in case the open-source project stopped being updated, read through the code carefully to understand how it worked, and wrote internal documents for future maintenance.

For production risks, I created a testing plan covering 95% of our user devices, added specific monitoring for the new library's performance, and created a rollback plan that could undo changes within hours if we found problems.

For business risks, I got agreement from stakeholders using data instead of promises, added extra time for possible problems, and clearly defined success goals including memory usage, crash rates, and performance numbers.

The plan was step by step: weeks one and two did deep testing and proof of concept, week three got team review and stakeholder approval, weeks four through six did the work with lots of testing, and week seven onward rolled out to production slowly with continuous watching.

The principle: Adopt external solutions with eyes wide open. Plan for success, but prepare for failure."


Q: "What if you couldn't find a suitable open-source alternative?"

"I was actually preparing for that scenario in parallel. I wasn't just searching blindly—I had a backup plan to build the solution myself if needed.

I started studying the structure of animated PNG and PNG files to understand how they work. I also spent time reading through our in-house library code to understand the current approach and what would need to change. This wasn't wasted effort because understanding the fundamentals helped me evaluate the open-source options better too.

Luckily, I discovered there was an iOS engineer in another team at LINE who had written an iOS library that used the JIT approach. I reached out to him and learned from his implementation. He shared insights about the challenges he faced, the trade-offs he made, and the architecture decisions that worked well. This gave me a clear roadmap for what a working solution should look like.

So if the open-source search had failed, I would have had:

  • Understanding of the PNG/APNG file format fundamentals
  • Knowledge of our current library's architecture
  • A working reference implementation from the iOS library
  • A colleague who could review my approach and help with challenges

The search succeeded, which saved us months of development time. But I was ready to build it if needed. The key lesson here is to always have a Plan B when making critical technical decisions.

The principle: Hope for the best outcome, but prepare for the harder path. Your backup plan makes you more confident in taking calculated risks."

results matching ""

    No results matching ""