Iron Router Mysterious Delay - meteor

Let's say there are two routes: /posts and /posts/:id. The first route has to render many (about a hundered) posts at the same time, and the second route just shows a detailed view of a post. The user will go back and forth the two routes multiple times. It would be a jarring experience if he had to wait for a long time between every navigation.
To prevent such loading problem, I am using subs-manager that preserves a subscription of data between routes. After the initial loading of the posts, all the posts are preserved, and subscription is always ready. My problem is that the even when the subscription is ready, it takes about a full second for /posts to load.
More precisely, after Route.go('/posts') is called, it takes 1 second before everything is loaded. I am using Iron Router, and considering to switch to Flow Router in the hope of solving this problem.
Question: Where does this delay come from, and how can I solve this problem?
Edit: After more investigation, the delay happens in between onCreated and onRendered.

Related

Should you use next/link (prefetched client side transitions) for pages with any dynamic content?

From: next/link
You can see that the <Link> component from next/link enables client-side transitions and link prefetching, which are great features, but maybe not for all cases.
Please see the caveat I've run into. Let's say I have the following pages:
Home - Some landing page with a nav bar
Latest - Here I can see my latest posts
Admin - Here I can add more posts
The Latest page from the example above uses getStaticProps with revalidate. Something like:
export const getStaticProps : GetStaticProps<HomeRoute> = async () => {
const preloadedState = await getPreloadedState();
return({
revalidate: 1,
props: {
preloadedState
}
});
};
In theory, after 1 second, it should send the last stale response for the next request and trigger a new static regeneration to be served for the subsequent requests. After 1 second, the process repeats and you get fresh data at least after every second, which is pretty much immediately.
Now, see the caveat I've run into with next/link:
User lands on the Home page. There is a Link on the nav bar pointing to Latest. That link will be prefetched by next/link.
In some other browser, an admin goes to the Admin page and adds one more post (which should appear on the Latest page at some point).
Now user clicks on the Latest page link. The new post is not there.
Clicks on Home again. And clicks again on Latest. New post is still not there and never will be.
The transitions in this case are blazing fast, which is nice. But from my experience so far, I think that that user is locked inside a version of my website where the new post will never be available, because that 1st prefetch happened during a time where the new post didn't exist.
The only way that user will ever see the new post is if he/she presses F5 to do a full website reload. And it might be necessary to refresh twice, because the 1st one might return the previous stale version while triggering the regeneration for the next one.
I mean, what is the workaround to this issue? Should I not use next/link for pages that contain any dynamic data? Should I just use normal <a> tags?
UPDATE
From: https://nextjs.org/docs/basic-features/data-fetching#statically-generates-both-html-and-json
From the excerpt above, we can see that indeed, client-side transitions will not trigger a page regeneration, because they'll not call getStaticProps. They only fetch the pre-built JSON object for the page to use as props.
AFAIK, it means that you'll be locked to the version of the page that existed when you first visited the website. You can go back and forth and nothing in the pages would change, because the JSON data is probably cached on client anyway.
PS: I've tested this (like I've mentioned in the question above) and this is exactly what happens.
So how to workaround that? I would like for users that keep an open tab of my website to be able to get updates for the pages when they navigate from one page to the other.
A POSSIBLE SOLUTION
Set some kind of idle time counter, and if the user gets like 10 minutes of idle time (it means that they left the tab open). Whenever he comes back and do some action, I could refresh the whole website to make sure they get the new version of the pages.
Has anyone faced that problem before?
I've posted this very same question in several forums and this is the response I've got:
It seems what you described is true. next/link caches results in the client-side and your visitor will not fetch a revalidated result out of the box unless there is a full-page reload.
Depending on the likelihood of content changes, you might want to use <a> instead or you can look at some client-side content reload strategy that kicks in after mount and query data source for updated content.
Given that fact, I'll stick to using next/link and client-side transitions. But I'll also use something like a setInterval() to do a full website reload from time to time, so I'm sure my users will keep getting revalidated pages eventually.

Redux randomly resets a reducer's state

I've run into a problem and I need a hand.
This is more of a theoretical approach rather than practical.
My problem is:
I am making an app in my spare time, which is rather complex - it's supposed to resemble a social network of sorts to an extent.
I have 10 reducers in my combineReducers function and a crapload of actions fire up when a user either goes to their dashboard or the start/home page - to fetch the user's uploaded images, videos, their profile picture, posts of their friends, posts directed to them, all of their posts together regardless of whether they are images, videos, audio posts or textual and groups they're a part of.
However, some of the reducers affect others, and simply reset them, but they were supposed to act independently of one another.
In the images below, you can clearly see that some textual posts were loaded in one of the dispatched actions, only to be completely reset by another action from a completely different reducer with a different type constant when loading videos.
In case it matters, some of my separate reducer objects share the property loading, initially set to null or false.
The maintainer on GitHub might have also been stumped, as they recommended that I ask my question here.
The reducer loads
Different reducer randomly resets another one

A action is seemingly overwriting another unrelated slice

I'm not quite sure how to explain this, but here is a picture that could help explain the issue that I seem to be facing.
As you can see, I have a SharedNotificationsModule and a SharedConversationsModule, these are totally separate to one another and each contain their own state files.
I am importing the SharedNotificationsModule into my SharedHeaderModule as this is where the majority of notification related content will be.
However, if I navigate to the ConversationsPage and the LOAD_CONVERSATIONS_SUCCESS is triggered my previous notifications slice is being overwritten.
This isn't only happening on the LOAD_CONVERSATIONS_SUCCESS action, this happens on other pages but some times the action that get's the user or the action that get's a users profile (when navigating to the users profile page).
I'm not sure what/if any code you would like to see, but just let me know what you want.
I finally figured this out now, turns out that I had forgotten to add a default to the switch in my notificationsReducer. The default now just returns the existing state.
default:
return state;

quick demo for dashboard ticking over

I have to mock up a ticking dashboard which is part of a proposal. I am looking for ideas other than the HTTP Refresh option that I am thinking of. The objective is to quickly mock up a look and feel and a working dashboard that ticks over. It only had to provide new content every five seconds. EG there are a bunch of KPI's and their outputs which are percentages have to be updated..
A simple bunch of HTML pages using HTTP Refresh is on my mind. Is there a better option anyoine can think of. EG can HTML5 do this better? Is CSS an option? Thank you in advance for any ideas
I would be going for an ajax call back to the server to get the latest update and then embed that wherever it needs to go - you could set the ajax function on a timer to run every 5 seconds or 1 second or whatever. This way your entire page is not being refreshed, and additionally you can be calling back to the server for a new update even while the previous on is still being rendered.
Downside is that you won't have a page history (i.e. the users will not be able to navigate 'back' to previous ajax updates) unless you explicitly create one; I can't see that being necessary though.
Please post a comment if you need more info about ajax.

How can the delay before displaying meteor collections be best addressed?

Before displaying the items from a collection, meteor seems to do some processing that leaves the client window without updates. You can see this live if you surf to http://madewith.meteor.com on a reasonable machine. My 2.6GHz 4GB RAM laptop takes about 5 seconds to render the items in the list, during which there is no indication of progress and a new user in a hurry could reasonably believe the page has finished loading.
Is there a way to incrementally display items from a collection, such that the server pushes to the client the first items of data on the wire, and the browser renders them, while new items are received? Akin to HTTP's chunked transfer.
Or is the only solution to display a spinner graphic while loading the collection, similar to what https://atmosphere.meteor.com/ does (the "doing something smart" message)?
If you examine the xhr of the madewith app, you'll see that all (87 at this moment) apps load in the same request. So I don't think 'incrementally' displaying data is going to help in this case.
The issue is just that meteor apps take a while to initialise. I'm not sure if this can be improved in the future, but for now, yes, I think displaying a spinner is the best solution.
Regarding how to know when the data is ready, you can use the onReady callback on a collection, or see this PR for a better solution coming soon.

Resources