Building Myntra Zero — A High Performance Progressive Web App

Harshdeep Sinha
Myntra Engineering
Published in
3 min readDec 13, 2017

Internet penetration in India is pretty interesting. Only ~6% of all users across the country have a fixed broadband connection, for the rest 94% a mobile wireless connection is the primary way of accessing the internet

Also, with the exception of large (Tier I) cities, most users use a low end Android smartphone. Hence, it is imperative to build a rich yet lightweight and performant Mobile Web user experience.

So, without further ado, this is how we built Myntra Zero:

Our Stack

Myntra Zero utilizes plain vanilla React (Preact to be precise). We don’t use Redux or other libraries for data flow. Code is written mostly in ES2015 with a few Stage-3 goodies.

Webpack with Hot Module Replacement is used for development and bundle creation. webpack-bundle-analyzer is an important part of our build pipeline. Bundle snapshots are compared to check for bloat or duplicate modules.

Inclusive

A sizeable chunk of our users are on older/legacy browsers. This brings in additional challenges. We need to balance usage of bleeding edge APIs vs the size overhead to polyfill them.

IntersectionObserver, URLSearchParams were the major features that we had to polyfill. After that, it was just a matter of configuring babel-preset-env with the correct settings. Currently, Myntra Zero is fully compatible even with UC Browser !

Small Size

Our main bundle weighs in at 65kb while individual component bundles don’t exceed 20kb. We use React for our dev builds, but swap it out with Preact on production. Bundle splitting at component level is achieved with Webpack and the excellent react-loadable library.

Native fonts are used instead of custom fonts. We found Lodash to be a major contributor to bundle size, so we aggressively control its usage by babel-plugin-lodash and lodash-webpack-plugin.

High Performance

Most of our Components utilize React.PureComponent. It contains a simple implementation of shouldComponentUpdate to prevent unnecessary renders.

HTTP/2 is used for all requests. JPEG images are swapped out for webp on compatible browsers. Image quality is dynamic and based on results from Network Quality Estimator API

Caching

Service workers cache url requests (among other things). We use amp-install-serviceworker to pre-cache most of Myntra Zero’s static assets in the background while user is browsing the AMP page

All api calls are also cached in IndexedDB using a combination of superagent-cache and idb-keyval. This gives a performant experience on browsers which don’t support ServiceWorkers

Immersive

Using a combination of Push notifications, Add to Homescreen and a Single Page Application (for critical flows) we’re able to give an native-app like experience to the user minus the overhead of a App/Play Store download.

We also utiltize the Credential Management API to autofill passwords and autologin users to Myntra Zero.

Myntra Zero

To Do

  • Enable brotli compression for static assets and APIs
  • Server Side rendering
  • Move other bits of the older mobile web into Zero

PS: Myntra Zero is currently in an A/B test with our old Mobile Web. So, there’s a chance you might land up on the older site.

Originally published at medium.com on December 13, 2017.

--

--