Recent years have seen a huge flux of SPAs — Single Page Applications. Though they enhance user experience, implementing SPAs for large-scale web applications is indeed a complex task. At eBay, we faced a similar challenge when we wanted to migrate one of our key desktop flows (search and item pages) to an app-like experience, from the current state of full page refreshes. Some of the key challenges were
- Server & client sync: Solving this challenge is super critical for e-commerce applications. Both the browser and the server should maintain the state of the app. At any point in time the URL should be portable, meaning it should render the page markup in the same state as it was previously. From an e-commerce perspective, three main circumstances make this point critical: SEO, browser refreshes (especially for items ending soon), and URL sharing.
- Performance penalty for the first hit: Most SPA frameworks out there require the initial rendering on page load to happen on the browser. This is an anti-performance pattern and has proven to be a bad way to go for many (see, for example, Twitter’s experience). In addition, with initial rendering on the browser we lose the huge benefits of the preload scanners in modern browsers. This again reiterates the point that server side rendering is not just an add-on, but a must.
- Browser Back/Forward: This may come as a surprise to many, but from what we have observed, even the slightest deviation from the default back/forward behavior of the browser has impacts on consumer behavior. Users are so accustomed to these actions (mainly in the desktop environment) that we need to make sure they work as expected. This is not much of a SPA challenge, but something to keep in mind.
Considering the above facts and still wanting to build a seamless experience, we decided to go the PJAX route. PJAX (pushState + AJAX) is a technique that delivers a fast browsing experience, without the SPA overhead. It has worked well for biggies like Twitter and GitHub. When looking to implement a PJAX library, we learned about YouTube’s SPF — Structured Page Fragments — from the 2014 Velocity conference (yes, SPF not SPA; we know it’s confusing). A quick dive into SPF indicated it was pretty much what we wanted. Moreover, the contributors to SPF responded promptly to all our queries and enhancement requests, thus enabling us to get started quickly. So what does SPF offer?
- Application code remains intact: With SPF, we don’t have to change the way we build applications. Also, no specialized client treatment is required. The only change needed was to add a conditional hook (based on a particular request URL param) in our server response pipeline to respond with HTML in JSON format, instead of with standard HTML. This benefit is huge to us, as development teams can build and maintain applications while being agnostic about how client-side navigations might happen.
- Always rendered on server: With SPF, markup is always rendered on the server. Along with the code maintenance benefit, this also removes the dependency on client hardware specifically for rendering. Although client machines are getting increasingly powerful, we still have a sizable set of our global users on the lower hardware spectrum whom we need to support. Our previous attempts at client-side rendering for these users were not fruitful. On a side note, we are very interested in trying out React for client-side rendering after initial load.
Now back to why the title “The Power of Perceived Performance.” Moving to SPF measurably increased performance on each navigation. But we had a problem: the performance gain was not visually perceptible. In an internal demo, the feedback was “yeah, it seems to be a little quicker, but nothing else is different.” We were scratching our heads about what was missing. Finally, it all came down to one thing — a progress indicator. Yes, we did not have progress indicators when users navigated pages in SPF mode.
Transitions or progress indicators mask the slowness in applications. There has been much research around this, and we actually experienced the humongous impact it has. Close observation of all major websites that use the PJAX technique reveals they use some sort of progress indicator. For instance, Twitter navigation uses a small throbber, replacing the bird icon in the static header. GitHub replaces the icon right next to a file or folder with a throbber. YouTube shows a red progress bar at the top to indicate the progress of a user’s action.
When we were considering how to implement a transition for SPF-based navigation, a lot of fancy ideas came up. From internal testing, the feedback we received was clear : more than the fancy stuff, customers just need an elegant transition. We ended up with a real-time progress bar similar to YouTube’s. With the progress indicator in place, we did another internal launch. This time, the feedback was unanimous: “Wow! The page looks fast.”
Without progress bar
With progress bar
Currently the PJAX-based navigation is enabled within the item page and is in production A/B testing. Search is next, and soon other key flows will follow. The ultimate goal is ONE eBay desktop experience.
Huge thanks to YouTube engineers Alex Nicksay, David Phillips and Marcel Duran, for their continuous support throughout the migration. Last but not least, thanks to my colleagues Karthik, Vidya, Yaniv, and Raghu for teaming up and making this is a reality.