Progressive webapp with shell cached still not behaving as desired? - reactjs

I have used Sw-precache in my React app to pre-cache my built assets(i.e vendor.js, app.js and, icons). however, the result is less than desirable. On page reload my app assets are all fetched again(from service worker), but never the less everything disappears (page goes blank) for a moment and assets appear.
Screen capture of my app on page reload. In comparison, here is an app the Session from a list from https://pwa.rocks/. That truly has a offline cached that even on reload does not re-fetch the static assets. Here is also a screen capture of the session app on page reload. I'm positive there is something I am Not doing. What am i missing?

It could simple be that your HTML is returning and empty page and it takes time for the Javascript to run and populate the DOM with content, where as The Session is returning the HTML populated from the service worker.

Related

What is the point of single page large applications if you have to split your code to improve performance?

I've been reading about lazily loading code in react.
With lazy loading, only the needed code will be loaded and doing so,
your initial loading will be faster (because you will load much less
code) and your overall speed will be much faster being on demand.
This is what I've understood.
In a single page application, the entire page is loaded onto the browser initially. We use module bundlers like webpack to bundle the application into a single page. Everything's great.
Now, if the application size is large, the load time would increase. To improve performance, we can divide the bundle into separate chunks that will be loaded only when needed.
My question is, if we have to divide our page into chunks, is it still a single page application because the browser will have to request the server for these chunks whenever they are needed? I feel like there's a gap in my knowledge and I don't know what's missing.
The traditional web applications used to work with postbacks to the server to fetch HTML to render a new page. Then AJAX came into the picture and applications were able to render data asynchronously thereby making sure that the user doesn't need to wait the time when the browser would refresh on postback to render the new page.
Modern Javascript libraries like angular, react etc. bring single-page application (SPA) model which runs inside a single page without requiring the browser to reload as the user navigates the site (ie. with only a single container page for entire application,like index.html). Even with code splitting and lazy loading of chunks, the application developer can ensure that user gets a pleasant experience like displaying a progress bar or loading spinner instead ( using React Suspense ). This is much better than the frustrating experience of waiting for a page reloading everytime. Webpack ensures the chunkhash changes only for chunks which have changes in source code from previous build. This helps to take advantage of browser caching so that the request for chunks don't need to go to server everytime. Hope this was helpful !

When exactly is Next.js “build-time” happening?

I'm reading Next.js fetching data part of the documentation and one question came to my mind.
Next.js can fetch data with getStaticProps, getStaticPaths, getInitialProps and getServerSideProps, right?
But some happens on Build-time as I quote:
getStaticProps (Static Generation): Fetch data at build-time
When is this Build-time happening?
Is it when we run npm run build? (To build the production build)
Or when the user accesses our Next.js app? (On each request)
Build time happens when you're building the app for production (next build). Runtime happens when the app is running in production (next start).
getInitialProps (gIP) runs on both the client and the server during runtime for every page request. Most common use case is retrieving some sort of shared data (like a session that lets the client and server know if a user is navigating to a specific page) before the requested page loads. This always runs before getServerSideProps. While its usage is technically discouraged, sometimes it absolutely necessary to do some logic on both the client and server.
getServerSideProps (gSSP) only runs on the server during runtime for every page request. Most common use case would be to retrieve up-to-date, page-specific data (like a product's pricing and displaying how much of it is in stock) from a database before a page loads. This is important when you want a page to be search engine optimized (SEO), where the search engine indexes the most up-to-date site data (we wouldn't want our product to show "In stock - 100 units," when it's actually a discontinued product!).
getStaticProps (gSProps) only runs during build-time (sort of). It's great for sites whose data and pages don't update that often. The advantage of this approach is the page is statically generated, so if a user requests the page, they'll download an optimized page where the dynamic data is already baked into it. Most common use case would be a blog or some sort of large shopping catalog of products that may not change that often.
getStaticPaths (gSPaths) only runs during build-time (sort of). It's great for pre-rendering similar paths (like a /blog/:id) that require dynamic data to be used at build-time. When used in conjunction with gSProps, it generates the dynamic pages from a database/flat file/some sort of data structure, which Next can then statically serve. An example use case would be a blog that has many blog posts which share the same page layout and similar page URL structure, but require the content to be dynamically baked into the page when the app is being built.
Why are gSProps and gSPaths sort of ran during build-time? Well, Next introduced revalidate with fallback options that allows these two Nextjs functions to be ran during runtime after a timeout in seconds. This is useful if you want your page to be statically regenerated, but it should only be regenerated every n amount of seconds. The upside is that the page doesn't need to request dynamic data when navigated to, but the downside is that the page may initially show stale data. A page won't be regenerated until a user visits it (to trigger the revalidation), and then the same user (or another user) visits the same page to see the most up-to-date version of it. This has the unavoidable consequence of User A seeing stale data while user B sees accurate data. For some apps, this is no big deal, for others it's unacceptable(†).
† If you're using a version of Next v12.2.0+, you can use On-demand Revalidation to mitigate a stale static page from being shown to users if/when its data has been updated.
And lastly, there's client-side rendering (CSR) which are assets requested at run-time on the client (the browser) which aren't vital for SEO or can't be run on the server-side (like attaching an Event Listener to the document; this can't be done because server's don't have DOMs). Most common use case would be a user-specific dashboard page that is only relevant to that user and therefore doesn't need to be indexed by a search engine or some sort of JavaScript that manipulates the DOM and therefore can't be run on the server.
Other things of note: gIP and gSSP are render blocking. Meaning, the page won't load until their code resolves/returns props. This has the unavoidable consequence of showing a blank page before the page loads. This also means slower page response times where: Page is requested, gIP/gSSP runs code that blocks page from loading, gIP/gSSP code resolves, assets are then downloaded, page begins to load the JavaScript on the client while the HTML is being loaded into the DOM, JavaScript is done running, page is then rehydrated and then it becomes interactive. In summation, this results in a slower TTI.

Update "service-worker.js" on Single Page App when changing routes

I have a create react app SPA, and I have deployed it with a registered service-worker.js (Cache-Control: max-age=0)
Everything works totally fine: When I update my code, and redeploy, navigate away from my site (or close the page), and return to my site, the service-worker.js file is downloaded again. It caches my index.html file which contains the url for my app.HASH.js file. It notifies me that new content is available, I refresh the browser page, and now I am running my latest app version.
What doesn't work is: When I navigate to different parts inside my SPA, I use react-router to change the URL. The "url-changes" don't trigger a reload of my service-worker.js file (it's cached with max-age=0 - and I have confirmed this with curl -I). Therefore a new worker is never downloaded to eventually inform me that new content is available and that I need to do a refresh.
I am not sure what the expected behaviour is supposed to be. If react-router changes the URL - should this not trigger a reload of service-woker.js when it's set to not cache itself?
In order to be able to get a new version of the SW.js file while the user is using your app, you have to manually call ServiceWorkerRegistration.update().
You could do for instance:
navigator.serviceWorker.getRegistrations()
.then(registrationsArray => {
registrationsArray[0].update();
})
This code would then be called whenever you like! This forces the browser to check for updates to the SW.js file and then handle the situation in whatever way you've configured your script to do.
This update() call should be made in any place you want to check for updates. You could call it after every URL change / new route visit or once a minute or whatever. You decide.
Checkout the MDN documentation. They also show reference code for storing a reference to the registered SW which gives you the possibility of directly calling update.
https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/update

Single Page App on React.js and ZF2. Is it possible?

I'm thinking how to implement a SPA on Zend framework 2 using Reactjs? Haven't seen any tutorial that might help me. So, I was asking if this is possible. How would zf2 will handle the routes?
The routes are handled on the client side (by pushing URLs into browser's history so you can also use browser's back button for navigation)
Simply put, changing a route will not load a whole page from the server.
The server does not even know that your JS app is changing the URL in the browser (imagine you write by hand http://example.com#test while you were already on example.com; that #test thing is a fragment URL and it will never be sent to a server)
Instead, the JS application will respond to (once again, client-side) route changes by rendering a different page or section, and making some ajax calls to the server to fetch or update data.
Now let's see what the server should do:
send the first page (the "single-page") and the assets (CSS, JS) on
the first load
respond to app-originated AJAX API calls once the page is loaded and
the JS app has been started
That's why they call them "single page apps", because they do much of the logic and the presentation in the browser (DOM rendering, routes), and the server merely acts as a data layer, or a backend if you like this word better.

why $templateCache.removeAll() not working?

I am using $templateCache.removeAll(); to remove cache on LogOut, it is working fine since when I tried $templateCache.get("abc.html") it returns undefined.
But when I again load angular app abc.html shows from cache in network of chrome development tool .
The $templateCache is an applicative cache: angular stores the template in a JavaScript object. As soon as the application restarts because, for example, you refresh the page, this cache disappears and is recreated in the new application.
The browser cache has nothing to do with $templateCache. The browser is responsible for this cache, and populates it based on cache headers sent (or not) by the server. This is what prevents the browser for completely reloading pages, images and other resources that don't change often when using the back and forward buttons, or simply when navigating between pages.
So what you're seeing is completely normal.

Resources