Home / News / Enhancing Myntra App performance: Transitioning from GIFs to Videos

Enhancing Myntra App performance: Transitioning from GIFs to Videos

Here’s the sarcastic modified version of the provided text:

Introduction

In the fast-paced world of e-commerce, every millisecond counts. At Myntra, where visual content drives discovery and engagement, we embarked on a critical mission: to revolutionize how animations are delivered in our Android and iOS apps. This journey led us from the ubiquitous GIF format to a more efficient video format, unlocking significant performance gains and a superior user experience.

Background on GIFs

The Graphics Interchange Format (GIF) has been a widely-used format for looping animations since its introduction in 1987. Its simplicity and broad compatibility made it a go-to choice in mobile apps. However, despite its ubiquity, GIFs come with several drawbacks that can negatively impact app performance and user experience.

Challenges with GIFs in Myntra App

At Myntra, we used GIFs extensively for animations in our home and brand page’s widgets. Our existing Image components provided easy GIF playback, but GIFs came with some serious drawbacks in native mobile environments:

  • High Memory Usage

    Introduction

    In the fast-paced world of e-commerce, every millisecond and every pixel counts. At Myntra, where visual content drives discovery and engagement, we embarked on a critical mission: to revolutionise how animations are delivered in our Android and iOS apps. This journey led us to transition from the ubiquitous GIF format to more efficient video formats, unlocking significant performance gains and a superior user experience.

    Background on GIFs

    The Graphics Interchange Format (GIF) has been a widely-used format for looping animations since its introduction in 1987. Its simplicity and broad compatibility made it a go-to choice in mobile apps. However, despite its ubiquity, GIFs come with several drawbacks that can negatively impact app performance and user experience.

    Challenges with GIFs in Myntra App

    At Myntra, we used GIFs extensively for animations in our home and brand page’s widgets. Our existing Image components provided easy GIF playback.

    However, GIFs came with some serious drawbacks in native mobile environments:

    • High Memory Usage: GIFs often lead to Out of Memory (OOM) errors, especially on low-end devices.
    • Low Quality: Limited frame rates and poor bitmap quality degraded the visual experience.
    • Large File Sizes: GIF assets were large, increasing network load and loading times.

    To mitigate these issues temporarily, we implemented several workarounds. These included optimising GIF assets and imposing restrictions on the file size of GIFs during the ingestion process. However, these were interim solutions and the move to an alternate was necessary for a more permanent and effective fix.

    Exploring Alternatives

    Before settling on a solution, we explored several alternatives to GIFs:

    • WebP: This format offers better compression and quality than GIFs. It has broad web support and is native on Android, but is only supported natively on iOS versions 14 and above.
    • APNG (Animated PNG): APNG provides excellent image quality and strong web browser support. However, while it is native on iOS, Android does not natively support APNG animations, requiring a third-party library to work. This adds complexity and APNG in general can also lead to larger file sizes.
    • H.264/HLS (Video): This format provides excellent compression and quality, is widely supported on all platforms, and is ideal for longer animated content or video playback. However, it requires a video player and involves more complex implementation compared to image-based animation formats.

    To make an informed decision, we compared these formats across several key metrics:

    As the above table shows, using H.264 (HLS) for video resulted in the best quality with the smallest file size[1], consuming fewer resources and improving battery efficiency.

    Fun fact: A modern device like the Google Pixel 9, can handle up to ~15.2 hours of continuous video playback on a full charge.[2]

    Our Solution: Embracing Video

    We decided to use video playback as a replacement for GIF assets, opting for H.264 (AVC or Advanced Video Coding) for encoding. This widely used standard leverages advanced compression for high efficiency and quality, suitable for various applications from low-bandwidth streaming to high-definition video storage.

    A fundamental approach to converting GIFs to an efficient video format involves a few key steps:

    • Media Ingestion: Receive and store the GIF asset in a scalable storage system (e.g., S3 / Google Cloud Storage / Azure Blob Storage).
    • Transcoding: Utilise a powerful open-source tool like FFmpeg to convert the GIF into a more efficient video format, such as H.264. For streaming, this can be further processed into a format like HTTP Live Streaming (HLS), which breaks the video into smaller chunks.
    • Content Delivery: The transcoded video chunks are then distributed via a Content Delivery Network (CDN) to ensure low-latency delivery to users (e.g., Akamai / Cloudflare).
    • Client-Side Playback: A robust video player (e.g., ExoPlayer on Android, AVPlayer on iOS) is used to play the HLS video seamlessly.

    Implementation in the Myntra App

    To seamlessly transition from GIFs to videos, we leveraged our existing infrastructure while making key enhancements to support this new format.

    In-house Video Platform

    In Myntra, we already have our in-house video platform[3]. This already served videos for influencer content on our platform and provided robust capabilities, including:

    • End-to-end video hosting and live-streaming solutions.
    • Tools for uploading and managing video content.
    • Our in-house Video Player SDK, a client-facing solution for rendering static videos and HLS streams with adaptive bitrate support in our mobile apps.

    Operations Self-Serve Portal Enhancement

    To facilitate the switch from GIFs to videos, we expanded our internal video upload portal to include GIF uploads. Our existing video transcoding system, which uses FFmpeg, was updated with a new profile to support both GIF and video assets. This profile converts GIFs or static video assets into HLS-based videos with 2-second chunks. This tool was also integrated with Layout Orchestrator Layer, our page layout and widget configurator, simplifying the replacement of GIFs with video assets in widget configurations for the operations team.

    Video Player Integration in App widgets

    The transcoded videos are displayed in the app using our in-house VideoPlayer SDK. We also developed a new component called MediaView in our React Native codebase, which seamlessly integrated our Player SDK’s VideoView for video playback.

    Fallback Handling

    The MediaView component also uses React Native’s Image for backward compatibility with GIFs. This is crucial for older app pages still configured for GIFs, allowing them to render correctly without disruption, even in newer app versions. We also continue to use GIFs for specific scenarios, such as for animated icons and other small widgets, where their short, looping animation is more efficient than video. This dual-support approach offers flexibility, facilitating a smooth transition to video while maintaining a reliable user interface across all versions and use cases.

    High level overview of how our systems work:

    Implementation Challenges

    Optimising Parallel Video Playback

    Displaying multiple widgets with videos introduced performance challenges, particularly when a user scrolls through a page with multiple video widgets. Naively loading and playing every video in parallel would quickly consume massive amounts of system resources, leading to a sluggish UI, increased battery drain, and even OOM crashes on lower-end devices. We solved this using:

    • Pooling Queue: We implemented a FIFO-based pooling mechanism in our Video Player SDK to limit the number of active video player instances. When the pool limit is reached, the oldest player instance is removed and the new instance is added to the queue. This kept memory usage under control.
    • Viewport-Based Playback: Videos are played only when visible in the viewport and paused when out of viewport, reducing unnecessary CPU usage when the widget is not visible to the user. This not only saved battery life but also ensured that app resources were dedicated only to what the user was actively viewing.

    This combination ensured efficient memory utilisation and smoother performance, even with multiple video-enabled widgets on our app pages.

    High level overview of viewport based playback and video instance pooling queue

    Adding caching support

    Our Image components already perform LRU caching of image assets, including GIFs. Transitioning to videos, we wanted the same caching capabilities, so we implemented caching support for both ExoPlayer and AVPlayer. This optimisation was essential to minimise redundant network calls for the same assets on every app launch.

    • Caching support in Exoplayer: Caching in Exoplayer is pretty straightforward and they support it out of the box. We configured the LRU cache using Exoplayer’s CacheDataSource API which caches all assets served through Exoplayer(static or HLS based).
    • Caching support in AVPlayer: Even though AVPlayer supports downloading of static assets, there is no straightforward API to cache HLS assets. For this, we used a proxy server which acted as a cache layer. Any url that comes via this proxy server first checks if there is any local cache file associated with it and returns it directly to the client otherwise it allows HTTP passthrough and then caches and returns the file to the client. We used this reference code to setup proxy layer in our SDK: https://github.com/StyleShare/HLSCachingReverseProxyServer

    Benchmarking

    Switching from GIFs to videos significantly improved app performance. Based on our internal benchmarks, on Android, memory usage dropped by about 54%, and on iOS, it decreased by around 29%.

    Additionally, video files were, on average, 50% smaller than GIFs, resulting in around 2x faster loading times over the same network.

    Here’s a side-by-side comparison of GIF vs video in Myntra app:

    As we can see from the above observation, the HLS video playback started in about 6.5 seconds, while the GIF took approximately 24 seconds to start playback. The GIF was 4.77 MB compared to the 2.30 MB HLS video (chunked into five 2-second segments of roughly 400KB each + 100KB for thumbnail image), and the GIF also had lower bitmap quality. Both tests were conducted on a Google Pixel 3 device, simulating real-world conditions with a throttled 4G network via Charles Proxy.

    Conclusion

    The shift from GIFs to videos in the Myntra app significantly boosted performance, leading to reduced memory and optimised CPU and battery usage. By leveraging our in-house Myntra Video Platform and Video Player SDK, we were able to streamline video rendering while maintaining backward compatibility with GIFs. This shift not only improved user experience but also allowed for more efficient resource management, even when multiple videos are rendered in parallel. This ultimately translates to a more fluid, responsive, and enjoyable shopping journey for millions of Myntra users.

    Our experience replacing GIFs underscored the importance of a carefully phased migration for large-scale technical transitions. By developing a backward-compatible system, we successfully upgraded app widgets incrementally to support video rendering without disrupting the user experience. As we continue to roll out this optimisation across more sections of the app, we anticipate even greater enhancements in overall app stability and responsiveness.

    [1] For example, when converting a 4.77 MB GIF using FFmpeg, the results varied significantly by format. Converting it to H.264 (HLS) video dramatically reduced the file size to 2.20 MB, a 53.9% reduction. However, converting the same GIF to APNG increased its size to 6.70 MB, and to WebP, it grew to 9.70 MB. These increases often occur when lossless settings are prioritised, favoring perfect image quality over a smaller file size. Ultimately, the H.264 (HLS) video proved to be 67.2% smaller than the APNG and 77.3% smaller than the WebP version, all while maintaining high quality, making it the ideal choice for our requirements.

    [2] https://www.gsmarena.com/google_pixel_9-review-2739p3.php

    [3] For a deeper dive into the Myntra Video Platform and its role in static video and livestream hosting, check out this detailed blog series: https://medium.com/myntra-engineering/building-myntras-video-platform-part-1-792c3423bc65

    Other references:

    https://medium.com/pinterest-engineering/improving-gif-performance-on-pinterest-8dad74bf92f1


    Enhancing Myntra App performance: Transitioning from GIFs to Videos was originally published in Myntra Engineering on Medium, where people are continuing the conversation by highlighting and responding to this story.

Tagged:

Leave a Reply

Your email address will not be published. Required fields are marked *