Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trungdq88/4fef5c6a9f90006c5a77ab6bc8ba367b to your computer and use it in GitHub Desktop.
Save trungdq88/4fef5c6a9f90006c5a77ab6bc8ba367b to your computer and use it in GitHub Desktop.
Handling Page Transitions on Single Page Web Apps

Handling Page Transitions on Single Page Web Apps

zoom

Real world application with a lot of pages (or "screens") have to deal with problem managing the pages' DOM and memory efficiently and at the same provide a nice smooth transition effect between pages. This is not a real problem when you do it in native apps since Android or iOS already handle the hard work for you, but when come to JavaScript, HTML, and CSS, running on mobile browsers, this is the real challenge.

There are 2 common approaches to solve this problem:

  • Approach 1: Keep all the pages in the DOM tree, use CSS (for example display) to transit between pages.
  • Approach 2: Only render the current page to the DOM tree, when the route changes, we render the corresponding page element to the DOM tree.

That's how we usually manage the routing and page transitions, not to mention that we still want our app to be well-structured and easy to manage the routes when we have more and more pages.

Approach 1: Keep all the pages in the DOM tree.

Pros:

  • The transition you use will be smoother because your pages' DOM are already in the DOM tree, the browser don't have to do very much work (like manipulate and render the whole page). When route changes, it just trigger some changes on CSS classes and your page will be transited nicely.

Cons:

  • When your app grows, the DOM tree will be huge. Imagine your app has 10+ pages then you have to keep all that pages in the DOM tree, the memory for those constant pages' DOM is not a small number.
  • Keeping all those DOMs in the DOM tree all the time give a high potential of memory leak and leaving the Garbage Collector to be executed continuously, this will definitely cause lag/jank to your app.

Let's take a look at one of the example app that use this approach: shop.polymer-project.org.

shop example

As seen in the profiler, we can see as the app loads up more and more pages, the memory keep increasing and remain there, when we navigate back to the visited pages, Polymer uses that chunk of memory which contains mostly DOMs and just display them.

shop example memory

Let's see the Timeline record for the page transition:

shop timeline

It takes ~17.5ms of scripting to render the new page, which is pretty good.

Approach 2: Only render the current page to the DOM tree

Pros:

  • The DOM tree only contains the current page's DOM no matter how many pages are there in the application, which is a good thing if we consider the memory problem in Approach 1.

Cons:

  • We'll have a hard time to make the transition between pages to animate smoothly. When the route changes, browser have to manipulate the new page's DOM, and render it to the DOM tree, and if the page contains a lot of child elements, that will take over the processor to execute JavaScript. If those scripts cannot be complete under 16ms limitation in order to animate at 60fps (which likely never happen), there will be frame drops and lag/jank will happen during the transition.

Let's take a look at another famous example, React HN built with ReactJS:

react hn example

In this example, I navigated to several pages and repeat it continuously, and you can see how the app manage the memory from the Profiler report. No matter how many pages are there, it's only the current displaying page get allocated in the memory.

react hn example memory

Timeline report: image

Took ~79.3ms to render the new page, this is the amount of time ReactJS need to render the new page and modifying the DOM tree. As you can see this is the trade off between memory usage and CPU processing, it uses less memory but have to work more to render the page.

Conclusion

Please aware that these are 2 different applications, built with different frameworks/libraries by different person and the applications are quite simple, so don't take the numbers too serious.

The point of this is to show that no matter what framework/library we are using, just make sure we understand the problems when dealing with multiple pages application, and how we can decide when to use what approach or what approach our favorite framework/library is using. That'll give us a better idea why our web application become "laggy" on mobiles or even on Desktop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment