stratiformltd / react-loadable-visibility

A wrapper around react-loadable and @loadable/component to load elements once they are visible on the page.
BSD 3-Clause "New" or "Revised" License
1.01k stars 31 forks source link

not working - file is fetched on page load #15

Closed BernardA closed 5 years ago

BernardA commented 5 years ago

This may be related to this issue.

To answer to what was asked on above and to clarify the usage: I am building a PWA. Of course the intention is to be able, as much as possible to work offline.

So, it's great that react-loadable and visibility only fetch the resources when needed.

It would be even better that the fetching happens from the cache built by the service worker or just from the cache, full stop. It does not matter how the cache came about.

Neither is working in the case of react-loadable-visibility. Files are being built separately, but fetching occurs on page load. This is specifically the case of the Footer component on app below.

For react-loadable the first part ( fetched when needed does work ).

I tested on Firefox and Chrome.

Concerning fetching from cache which is, of course, a separate issue, I just mean to respond to the comment on issue above:

it would be impossible for this library to influence caching as there is nothing related to caching or service workers in it.

Somehow the browser is being told to ignore cache, which is perfectly possible. May be its not an issue with the plugin, but somewhere there's an issue.

Here's some code:

App.js

  import React from 'react';
  ....
 import Loadable from 'react-loadable';
 import LoadableVisibility from 'react-loadable-visibility/react-loadable';
 import PrivateRoute from './auth/auth';
 import Header from './pages/common/header/';
 import { Loading } from './tools/functions';

 const HomePage = Loadable({
    loader: () => import('./pages/home/'),
    loading: Loading,
    delay: 100
 });
 .....

 const Footer = LoadableVisibility({
    loader: () => import('./pages/common/footer/'),
    loading: Loading,
 })

 const Root = ({ store }) => {
return(
    <Provider store={store}>
            <div className="App">
                <Router> 
                    <div>
                        <Header />
                        <Switch>
                            <Route path="/resetting/reset/:token" component={PasswordResetHandlerPage} />
                            <Route path="/registration-result/:status" component={RegistrationResultPage} />
                            <PrivateRoute path="/account" component={AccountPage} />
                            <Route path="/logout" component={Logout} />
                            <Route path="/login" render={() => <div>login route</div>} />
                            <PrivateRoute path="/admin" component={AdminPage} />
                            <Route path="/search/:root?/:category?/:subcategory?/:place?" component={SearchPage} />
                            <Route path="/adview/:ad_id" component={AdviewPage} />
                            <PrivateRoute path="/offer/:ad_id/:offer_id?" component={OfferPage}/>
                            <PrivateRoute path="/mailbox/:type?/:message_id?/:ad_id?" component={MailboxPage}/>
                            <Route path="/" component={HomePage} />
                        </Switch>
                        <Footer />
                    </div>
                </Router>
            </div>
 </Provider>
 )
}
BernardA commented 5 years ago

Clarification: To check if react-loadable-visibility is working I forced the <div> immediately above it to have a css:height of 5000px. On normal desktop mode on Firefox Dev Tools I can see the <Footer /> file being fetched on page load. On the other hand on Responsive Design Mode the expected behavior happens, ie, the file is fetched on visibility. So, it seems to work on mobile, but not on desktop even if it is not visible.

tazsingh commented 5 years ago

@BernardA Thanks for the clarification. Can you also confirm that your Dev Tools aren't ignoring the cache? I believe this is turned on by default sometimes and you have to turn it off. Also some async code loading libraries will eagerly load everything in development mode (not react-loadable at the time of writing but saying for future people reading this issue).

While I'm still unfamiliar with service workers in general, I'm a bit confused by your usage here. Can you help clarify a few things for me, not specifically related to my paragraph above but in general? My understanding is that it still needs to make a network request to get the content in the first place. That network request can use HTTP caching to keep the content in the long-term. Or are you alternatively saying that you want these additional payloads stored in the service worker, then they would be part of the initial payload anyway negating the need for code splitting them out?

BernardA commented 5 years ago

For both Firefox and Chrome dev tools one should specifically disable cache, which I haven't.

Concerning SW, the precaching, as its called, happens after initial page load, soon as the browser becomes, or would become idle. No penalty from page load perspective then. Depending upon your objectives, you can precache most of the resources or just the ones more likely to be used. In a PWA, for instance, if you plan to get to the point of emulating a native app, you would precache all of it. I understand your comment about negating code splitting, but code splitting is also about client bandwith, but mostly about performance.
There's where the combination of tools like react-loadable/visibility and precaching gets great performance.

Anyways, interesting as it is, the discussion about SW and precaching is not relevant. The fact is that the files are cached and react-loadable/visibility are fetching from the network.

Please see below screenshots of network and storage tabs. The file bundle-15.js includes the Footer component.

screen shot 2018-10-23 at 18 10 33 screen shot 2018-10-23 at 18 11 30

BernardA commented 5 years ago

I thought this could be helpful. It' the same network shot from above, but now taken using Responsive Design Mode. You can see file bundle-15.js on the last line. It was fetched after the initial load when I scrolled down the page. That's the expected behavior, though still not using the cache.

screen shot 2018-10-23 at 18 25 26

tazsingh commented 5 years ago

Awesome, thanks for the additional info 👍🏽 I’m afk for the rest of the day but will take a look tomorrow.

Sent from my iPhone

On Oct 23, 2018, at 5:34 PM, BernardA notifications@github.com wrote:

I thought this could be helpful. It' the same network shot from above, but now taken using Responsive Design Mode. You can see file bundle-15.js on the last line. It was fetched after the initial load when I scrolled down the page. That's the expected behavior, though still not using the cache.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

BernardA commented 5 years ago

Hold your horses! I believe I have some clues on what's going on on both issues. I'll get back to you tomorrow.

BernardA commented 5 years ago

Well, it did not really pan out. Concerning the fetching on page load, I tested another page and visually observed the footer component being rendered before the contents. As it happens, the footer component is quite light as it is. No more than a shell with <div>s and background-color, while the content required some heavy fetching on the network. So, React plus the browser rendered the footer while waiting for the network. Forcing a height or min-height on the contents did not have any effect on keeping the footer from being rendered. I also tried placing other components before the footer, but still the issue remains.

On the cache issue, I still have to test. It may be an issue with the service worker scope. Normally it should be fine as it is, but may be the router/components change things. will see.

tazsingh commented 5 years ago

@BernardA Would you be able to create a sample repo with this behaviour? I'm using this library without a service worker on my own site and it works as expected - https://stratiform.io/ (scroll around this page with the network browser open for example - https://stratiform.io/architecture). As such, I'm suspecting that it's the SW that's perhaps problematic and a sample repo with that acting as you've described would be helpful to debug 👍Thanks!

BernardA commented 5 years ago

Thanks @tazsingh . I've created this repository. I do not have a lot of experience with that. Hope it is fine.

tazsingh commented 5 years ago

Awesome. I took a very quick look but need to dig deeper. My schedule is quite hectic this week and then I'm away from next week Wednesday for the next month. Hope to get to it on Monday/Tuesday though. The code you have looks correct from my initial glance but haven't had a chance to dig into the service worker and start the app itself to see the effect on my machine.

BernardA commented 5 years ago

Found the issue with fetching Loadable resources from service worker. It was both related to the scope of the SW and with the routing.
PWA's require a separate routing. See workbox-webpack-plugin doc concerning the routing. I can post the scope code here in the sequence.

So, this leaves us with the issue with loadable-visibility. I still have it loading the footer on page load, regardless of the visibility.

This should not be related to SW. At that time, initial load, SW is neither installed nor activated.

tazsingh commented 5 years ago

Good to hear! Glad you got that working.

I, unfortunately, will not have time to do a deep investigation as I am flying tomorrow and will be away for a month. If you find a solution, please report back. Otherwise, I will have to continue upon my return in December.

I'm still a bit confused as to how this isn't working for you but works elsewhere. To be 100% sure, based on a cursory glance at your repo, it appears that since all routes are lazily loaded, the Footer is in fact in view initially before being pushed down once the content above is loaded. I haven't run the app itself to observe if this is the case, but if you make that Loading component for each route take up the entire screen such that the Footer is pushed down, do you observe the same behaviour? I know you mentioned you tried something like this previously but want to confirm. Thanks.

BernardA commented 5 years ago

After some of which appear to be unrelated changes this started working. Unfortunately I cannot pinpoint what the issue was. I did have some issues with the Symfony composer server. It might be related. I am closing this. Thanks for you assistance.