Next.js - static rendering icons not static - next.js

Thanks for your time.
I am working on a complicated next project for work. I understand it to be a static site generator and the assets (icons for buttons) used on the page are gathered via a pre build script and stored in the public directory of this project. This next project then generates forms, which i am observing unexpected behaviour on.
When looking at the network tab and loading one of the forms the page requests the icons and loads / renders my page, at completion of the load a GraphQl request is made for background data.
This should now be the finished state, there is no change to the page and there is no need for re-render / the components these icons sit within are not updated and a re-render does not happen, however...
A new network request is made and the assets/icons in my components flicker/reload, by what i think is by the framework - why is this new request made? Is this something that the framework is doing? Initiator looks like this - so i think so, but can't see any reason / documentation for it.
_next/static/chunks/framework-2191d16384373197bc0a.js

Finally have a answer. Bad architecture in the application.
This was not simply limited to the images. We had a stateContext which we have been dispatching to for everything, that context is what is causing the re-render, its not state so each update re-renders everything at a global level so each button press / graphql query response caused a re-render.
The re-render was not paid any attention to until we throttled and noticed the flickering of these icons.

Related

Why using <Link> is better than router.push?

I have an ecommerce application in NextJS and I have a problem with my main menu. In fact, if I use the <Link> tag of Next, with or without the "prefetch" param, I still have the links that are prefetch (either on hover or if the item is in the viewport). My pages are loaded with getStaticProps.
I would like to use <Link> to keep all of benefits of Next and SPA, but I think that prefetching all of my products page before I need them destroys the performance of the backend.
Do you think I can use router.push to do this part of my app?
By using router.push instead of Link Component, your app would lose its capabilities such as
SPA (because it would redirect to a new page) and
SEO (because it cannot be
detected by crawlers)
Ideally for an e-commerce platform, i think it would be best to utilize the Link component and not overthink about your prefetch concern because these built in Components by nextJs are already optimized by the Vercel Team.
We should also only use router.push when Link Components are not enough. A good example of this would be upon clicking a button we want to trigger other frontend/backend functions and then redirecting to another page.
function handleClick(){
randomFunction();
anotherRandomFunction()
router.push('<random_link>')
}

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.

Using Preact in Lightning Web Component

Recently installed the project noted here: https://developer.salesforce.com/blogs/2020/11/how-to-use-apex-natively-with-svelte-vue-and-preact-within-lwc.html to test a theory on using Preact in a Lightning Web Component. Observed that in the Preact component any click in the component fires the onclick function for the first element rendered in the component (with an onclick property), any additional clicks or clicking directly on other elements (with or without an onclick properties) only fire the function for the first element. This behavior tracks with a separate project I've been working on that includes Preact. Does anyone know what would cause this and/or have suggestions on ways to address?
I'm assuming this is related to the LWC wrapper and how it redirects browser events to be processed, but I'm out of my depth in terms of fully debugging that path.
I ran this by the author of the linked blog post and we confirmed this doesn't work in an actual org, though it works fine in a local dev sandbox. Likely culprit is locker service, but neither the author nor I was willing to try to verify that, and there wouldn't be a whole lot to be done about it even if it were confirmed.
Short answer, Preact doesn't work in LWC framework currently.

How to push Blazor page onto stack so it doesn't need to be refreshed on nav back

Complete nooby to web development (used C# and F# for desktop apps in the past).
I was playin around with Blazor server side (no more Javascript - yea!) and wanted to know, is there a way to save a page's DOM using Blazor, so that when you follow a link and navigate back, the DOM does not have to be reconstructed for the original page?
Currently using OnInitializedAsync in .razor page to construct original page - it gets called again when the nav back is taken.
Does this even make sense to do? It seems to me that in many web sites using different techonology, a nav back does not re-construct the page, the DOM is saved somewhere and the browser merely 're-paints' using previously constructed tree. Or is this also a complete misunderstanding?

How can I stop the Flash privacy popup from occurring twice on a page?

My web-app records users via webcam and microphone. I want to use HTML/JS for the controls and content, so I created two separate Flex modules:
* A "Webcam Setup" module that lets you choose your camera and mic input devices
* A "record" module that lets the user record and submit the recording
When I embed either of these on the page, since they access the user's Camera/Mic object, Flash shows the Privacy dialog that says "[mysite] is requesting access to your camera and microphone. If you click Allow, you may be recorded."
The problem is, if I answer Yes in the Setup module, and later add the Record module to the page using Javascript, it again shows the Privacy dialog.
Is there a way to avoid the second privacy popup?
I would think that saying "Yes" for [mysite] would store that permission for at least that session, but apparently not.
What I've tried
I tried combining them into one SWF, adding it to the page once and moving the DOM element with jQuery's append() function when needed. When I move it, however, it reloads and asks me again.
Imagine if [mysite] was, say, blogger.com or livejournal.com (or, if it were still around, geocities.com). Would you want a "yes" response on that site to be good for every page under that domain?
Rememeber, just because you promise (cross your heart & hope to die) not to abuse the security hole you request, doesn't mean they can allow you to have that security hole.
Eventually, I found a usable workaround, similar to what I originally tried (above).
I combined the setup and record modules into one SWF. I first show the setup screen. When the user hits the Continue button on my page, Javascript calls a function in the SWF to swap to the Record screen.
I then move the <div> containing the Flash object to another location on page using absolute positioning, and resize the object.
Previously, I was trying to use jQuery's append() function to move the div within the DOM, and that was causing the SWF to reload. Just changing position and size does actually work.
You could build the "record" component to simply send and receive signals using an API you've created for your "setup" component (which has already been authorized, meaning one auth & two swfs) by using the LocalConnection class:
http://livedocs.adobe.com/flex/3/langref/flash/net/LocalConnection.html
This seems far closer to best practice than the other implementations mentioned, which smell a bit hacky and would probably confuse anyone who may inherit the codebase in the future.

Resources