Improving Full Page Reload of the Layout


#1

This is part of my journey on understanding performance,

Behaviour right now ( CPU throttled X4 ) Screenshots are from Chrome’s Performance Tab
After 4.7 sec, The first glimpse of the layout if rendered:

As you can see Some of the icons are missing, the Top bar is white because the background asset didn’t arive yet, and its basically a mess.
I looked in navigation.scss over this line

background: image-url('navbar.png');

And I changed it to

background: #01749d url('navbar.png');

Now the background has a default color before the img asset arrives, but still 4.7s is a lot. What more can be done in the client side? So i tried react-loadable which dynamically loads a component, while rendering a loading component in the mean time.

I wrote this helper file that can help us:

Now exporting components dynamically is easy.
index.js of the Layout looks like this:


Behaviour with the Changes (Still X4 Throttle)
After 4.00 sec we see the loading layout:

Thats an improvement of 700ms!
After this we see the rendered Component without assets but with a Topbar at least thanks to the CSS change

And finally the Full layout renders as we all know it.
I think these changes open up doors for react-loadble resulting in a much more pleasant way of full page reloading . I’m still learning and trying to understand how to fetch the assets faster from the server side but this is a good start. Thoughts?

branch: https://github.com/glekner/foreman/tree/loadable-poc


#2

Looking at the results, we still get a very partial page load until the assets arrive. I’m not sure why you decided to do the timing with 4x throttling, but iiuc, the improvement is under 200ms to the initial draw that still isn’t useable (and followed by another redraw to add the actual menus, i’m not sure when that occurs). While a 200ms improvement to final render is good, my understanding is that we still get the same time (or worse?) to the final render, while adding additional complexity to the code.

The bigger issue from my understanding is that the fetching doesn’t start until all of the webpack code is executed, which is the ~1sec delay we are seeing (or 4 seconds in your case). Before the assets arrive (or the server returns 304), the render can’t complete. A different approach might be to load the assets we need prior to executing all of the webpack code, so they are available when react looks for them. It may still take a second for react to actually render everything, which is a different problem we should look into, but at least we will know that it isn’t the assets that are blocking us but rather something else.


#3

Yes, the final render happens at the same time, but I dont think the two approaches contradict each other, The approach I wrote gives the user a feeling the page loads faster and more pleasantly. The next step is as you say, fetch the assets more efficiently, ill be glad to hear tips on this.

Here is a FPR demonstrating ( No Throttle )

before

after


#4

Thanks for bringing it up @gilad215.

Setting a bg color and putting the layout in a loader makes the feeling it works faster even tho it gives the same total loading time.

Because our vendor.js is so big, it takes long time to load and parse it. I see the loadable components mostly beneficial for loading 3rd party big components when they are not necessary for the main pages.
Things like brace, password-strength, and co…


#5

I tried removing some packages from our vendor and importing their components dynamically.

removed:

react-diff-view
react-boostrap
react-password-strength
brace - # all of it

Vendor is now 17.4MB ( Was 27MB )

Network screenshots:

Before

After

Is this the impact we are looking for @sharvit ?
There still is the delay of en.js from react-intl. I think thats a better problem to solve


#6

This is all on the dev server. I’d be very interested in a production build. There we should also apply HTTP caching so there’s the first page load and later pages. Since the bundle has a unique file name and we should be sending an infinite expiration date I’m much less worried about it. Dev builds are also much larger than production builds.


#7

While I was testing nightlies I can confirm this is a huge issue there as well. On every single page you notice it badly. Since the bundle is correctly cached there it’s not the download time. I suspect Javascript rendering is just massively slower than pure HTML/CSS.


#8

What about #6392. does it improve anything?


#9

It’s unrelated. In production we don’t have the devserver running and it’s all static files that are cached by the client.