Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The learnings from the app-shell and page-shell structure #1

Open
ritz078 opened this issue Jan 30, 2017 · 3 comments
Open

The learnings from the app-shell and page-shell structure #1

ritz078 opened this issue Jan 30, 2017 · 3 comments

Comments

@ritz078
Copy link

ritz078 commented Jan 30, 2017

Hi,

We have experimented with app-shell and are using page-shell currently (with a slight modification - loading the whole view in advance).

App Shell
It gave us better time to first paint but the time to first meaningful paint was delayed. Here's what we found in our experiment.

cxabh40uuaamded

As a user you get a faster first paint but the time to first meaningful content is what we are looking to optimize so we tried to fix that.

Solution
We got rid of app shell and implemented SSR with HTML streaming in combination with preload. And the result was :

201 1 - how we built it - part 1 housing

This way we were able to improve the time to first meaningful paint which made more sense than just improving the time to first paint.

Page Shell
Since we had implemented SSR and the idea of page-shell is same as that of app-shell, we used the idea rather than the implementation.

Case 1: Implement page-shell -> First meaningful paint still suffers. 2 JS files to load and when you navigate from another URL, loading multiple files (we also have separate CSS to prevent FOUC) didn't seem to be a good idea.

Case 2: Implement SSR -> Let the view have 2 files (JS and CSS). When the user lands directly on the page you don't need any shell due to SSR. When you are on a different page and the next intent of the user is to come on that page, load the view of current page in the idle time of previous page.

Implementing these we were able to solve for :

  • too many files
  • better time to first meaningful paint
  • faster route navigation

All of these were more about the implementation rather than webpack bundling.

webpack was mainly optimized to implement long term caching, manifest and chunking.

Intent based chunks
We implement route based chunks but we often ignore this. This is one important implementation that can reduce the size of a view bundle. There are certain parts of a view that are not always needed like a modal or anything that doesn't show up everytime. That can be made into a different chunk and loaded on demand. For example:

201 1 - how we built it - part 1 housing

The size in the above image is non-gzipped (around 9KB gzipped).

We are using 2 types of intent based chunks which are loaded in idle time or as per need.

Type 1 :
Those which have a chance of being visible but not immediately. They are loaded in idle time like some frequently visited modals. (driven by analytics)

Type 2:
Those which have less chance of being visible or once in many sessions. Load when actually required. Most of the times its not needed. (as per our analytics data)

We have to take care of bandwidth consumption of the user. Loading lot of chunks in idle time also may not be a good idea for people with slow internet connection.

I hope these are useful for developers who are trying to make a PWA.
So in both cases out time to first paint was around 2.2-2.3s so it was better that we implement the 2nd solution.

Its not always necessary that these will work for you so experiment and then implement.

Edit : Added clarity about intent based chunks.

@kurtextrem
Copy link

Intent based chunks: When the mobile connection is slow, doesn't it take a while to load 32 KB? Why not speculatively preload chunks that are somewhat likely to get clicked?

@ritz078
Copy link
Author

ritz078 commented Jan 30, 2017

Why not speculatively preload chunks that are somewhat likely to get clicked ?

@kurtextrem Good point that you raised. We are using 2 types of intent based chunks. the size of the file showed is non-gzipped. its actually around 9KB gzipped.

Type 1 :
Those which have a chance of being visible but not immediately. They are loaded in idle time like some frequently visited modals. (driven by analytics)

Type 2:
Those which have less chance of being visible or once in many sessions. Load when actually required. Most of the times its not needed. (as per our analytics data)

We have to take care of bandwidth consumption of the user. Loading lot of chunks in idle time also may not be a good idea for people with slow internet connection.

I am adding this in the main issue also.

@wub
Copy link

wub commented Apr 13, 2017

We have users all around the world, but only one server (in the USA). At first thought, would it be faster for us to host our app shells on a CDN, rather than doing SSR?

*Considering the ~500ms latency impact of doing SSR on a mobile network from the other side of the world, rather than loading something from a CDN POP nearby.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants