Prevent Redux actions performance on client side - javascript

I have a React/Redux/SSR app. Right now my app works as follows:
A user visits some url, browser sends request to Frontend server (Node.js)
Frontend server gets all necessary data for this url from Backend server (Ruby) and build html then responds to user's browser with filled window._PRELOADED_STATE_ with appropriated Redux store's state
User's browser renders received html and runs bundle.js script which is React app. It uses filled before window._PRELOADED_STATE_ to initialize app (at this time actions run again)
I want to prevent Redux actions performance on the first rendering on client because all is done on the server already.
What I have tried: on client after the first rendering I delete window._PRELOADED_STATE_ and run actions if window._PRELOADED_STATE_ exists only. But deleting of window._PRELOADED_STATE_ performs before app initialization so actions run anyway.
How can I get desired behaviour? Any ideas are appreciated.

Do you have the opportunity to use React in dev mode?
In dev mode React will complain if it's not able to match the SSR code with the front-end code. It looks to me that you can have a similar situation.
If that's not the case, which are the actions that run at the beginning?

Related

Server side rendering with next.js vs traditional SSR

I am very used to the approach where SSR meant that the page got a full refresh and received a full HTML from the server, where it gets rendered with razor/pub/other depending on the backend stack. So every time the user would click on the navigation links, it would just send a request to the server and the whole page would refresh, receiving a new HTML. That is the traditional SSR which I understand.
With SPA however, we have for example react or angular, where we receive almost empty HTML on the beginning and then the JS so that the whole app gets initialized on the client side. We can then have some REST API to get json data and render views on the frontend (client side routing and rendering) without any page refresh. We don't even need any server really.
Now, what I have a problem understanding is how SSR (such as next.js) works with react.
From what I am reading, the first request returns full HTML+CSS (which helps with SEO etc - I get that), but what happens later? What happens after that first/initial request? Does the whole react app initialize in the browser and then it just behaves EXACTLY as if it was a normal SPA (meaning we have client side routing and rendering from now on, without any need to make requests to that server)? In other words, does next.js still make any server requests after the initial one, or does it act like a typical SPA with CRA from now on?
I spent lots of time reading but all the articles mainly focus on the initial request and SEO and time to first byte, paint etc. and I am simply trying to understand why its called SSR since it seems to work different than the traditional SSR which I described on the beginning.
does next.js still make any server requests after the initial one, or does it act like a typical SPA with CRA from now on?
You got it right. The first (initial) request is handled by the server and after that the frontend handles the routing (at least in the case of Next.js).
If you want to see an example OpenCollective is built with Next.js. Try playing around with it and see the Network tab in the DevTools.
I am simply trying to understand why its called SSR since it seems to work different than the traditional SSR which I described on the beginning.
It is called SSR because the app is effectively being rendered on the server. The fact that frontend routing takes over after the initial render doesn't remove the fact that the server did the work of rendering the app as oppose to the user machine.
That's Not all the things that happen with Next.js, In Next.js You can build something called Hybrid apps.
In traditional SSR, all of your client requests get handled by the server. Every request goes to the server and gets responses.
In classic CSR with something like React, as you said, all the things happens in the browser via the client-side javascript.
But, in Next.js you can define three different approaches (mainly two according to the docs) for pages to get delivered.
based on the app needs and requirements, you can serve a couple of pages in pure traditional SSR mode, a couple of them in classic CSR mode, and a couple of in SSR mode via dynamic data that get fetched and rendered into the pages on the fly.
these features bring lots of flexibility to design a web-app that behaves perfectly in every different scenario that is needed.

How to fetch data only once in a Next.js app and make it accesible to all the app, both in server and client

I'm working on a Next.js app that needs to fetch a config file from a remote server before initializing. I want to request the config file just once per call to the server before rendering the app server side. After that, I would like to be able to get the same config in the client without having to make a second request to the remote server from the browser.
I have tried to achieve this by using getInitialProps function either in _app or _document files and then use the React's Context API to make the configuration visible to every component but unless I'm wrong, this will run the code that requests the configuration both in server (on the first call from the browser) and client (on every page navigation).
I have also tried to create a server.js file, request the configuration from there and store in a variable within a ES6 module. However, I couldn't make this approach work because apparently the Next.js React app can't access the same modules than the server.js because they are actually two different apps. Again, I could be wrong.
Basically I would like to know if Next.js offers any kind of "bootstrapping place" where I can perform app initialization tasks that generate data that can be sent to the React app Next.js will initiate.
You are correct in that anything in getInitialProps in _app.js or _document.js will be run on every server request. Once you get your config, you can pass it down to the components in pages as props. From there, I think you have two choices:
Now that the app is bootstrapped, run the rest of the app as a SPA client-side. This would prevent any future SSR from happening. Obviously, you lose the benefits of SSR and the initial page load is likely longer, but then it would be snappy afterwards.
After getting the config in _app.js, send it as a cookie (assuming it's not too big to be a cookie?). On future requests to the server, the cookie will be sent automatically and you would check the cookie first - if it doesn't exist, get the config. If it does exist, skip that more expensive bootstrapping because the app is bootstrapped.
So I think it really depends on whether you want a single page application bootstrapped on the server but then entirely client side after that (option 1) or server side rendering per page while minimizing expensive bootstrapping (option 2).
Nothing prevents you from sending multiple cookies from the server if that makes sense for your app and bootstrapping. And remember not to make it a HTTP-Only cookie because you'll want to read that cookie client side - after all, that's what you're looking for - the client side configuration generated on the server.
Despite we ended up leaving Next.js for this and other reasons that made us decide Next.js was not the best option for our use case, we kind of mitigated this problem as follows while be sticked to it, I hope it makes sense to anyone. Also, by now maybe Next.js provides a better way to do this so I would read the Next.js docs before using my approach. Final note: I don't have access to the code anymore since I change to a different company so maybe there are some points that won't be 100% as we made it.
There is goes:
We created a module that was responsible to request the config file and keep the results in a variable. At the moment of importing this module, we ensure that the variable is not already present in window.__NEXT_DATA__. If it is, we recover it, if it's not, we request it to the remote server (this will be helpful in the clint side rendering).
We created a server.js file as described by Next.js docs. In this file we make the call to get the config file and store it in memory.
In the body of the function passed to createServer we add the config file into the req object to make it accesible to the app in the getInitialProps functions server side.
We made sure that the getInitialProps using the config file returns it, so that it will be passed to the components as props and also serialized by Next.js and made available to the client in the __NEXT_DATA__ global Javascript variable.
Given that the config ended up in the __NEXT_DATA__ variable in the server, using the trick described in the step 1 makes the app not request the config for a second time.

Need advice on redux and server-side updates

I'm building an app that receives updates from an external source. (Let's say the updates are stock quotes, that come in sporadically, every 10-60 seconds.)
Each client page might display the full list of interesting stocks, or focus on a single stock. Components on any page should update as the server receives new data for stocks displayed on that page.
My questions:
Will react, react, react-redux modules handle the communication between the server-side updates and the client components in the browser out-of-the-box? (Obviously I will have to write the actions/reducers/etc.) Or will I also need to write code that communicates those updates from the server to the clients?
I envision starting up the server-side process that receives stock updates from the main server.js code that also fires off the listen(3000) call. How could that stock-update process get access to the redux store? (My confusion comes because in most of the Express examples I've read, the createStore() call is within the app.use('/', ...) so the store gets generated each time a new web request comes in.)
Any pointers to projects similar to what I want to do? Thanks.
You will have to write code that communicates updates from server to the clients. The best way to do this would be use websockets. You can use frameworks like http://socket.io/ etc.
The Express samples that you have come across that use createStore on the server side are for server side rendering. Accessing store here to push stock updates is not preferred.
In Brief, what you need to do is ,
Set up socket io or websocket server
On the client, set up a socket-io client. It waits for messages from server.
Whenever you get stock updates, send the data from server to client through socket io.
When the client receives the message, dispatch an action with the data and let redux flow handle the state/store.
nope neither react no redux handles communication between serverside and react components (clientside)
react works as an ui view
redux manages application state
communication between server and client fall into actions and action creators in this case you could make an ajax call to server (by polling) and the state could be a boolean fetching, fetched,faliure all of which need to be managed in the store together with the response object.
Regarding the issue of serverside stock-update process,it doesn't matter since only the implementors understant what the initial state is hence the question to ask is does it matter to you that the createstore() is being called and what is it's initial state of the application.
on your case the createStore could be configured in such a case that its an reducer that fetches the stock at the point in time from the main server.js
you may also want to check
relay and graphql which comes with networking layer for communication to server by default all of which try to manage application state
[Answering my own question] The responses from various contributors above are correct and quite useful, but I have been (re)learning how to structure apps with react and redux. I wanted to share my new knowledge:
Christophe Coenraets wrote a blog posting that exactly matches my use-case: Real Time Trader Desktop with React, Node.js, and Socket.io
I write a blog posting that summarizes what I have learned about getting started with React programming in mid-2016: Getting Started with React Development

How to check for Parse logged user while rendering server side?

I use Parse BaaS
I have a React based web app created by this generator (which uses the latest ES syntax and BabelJS)
I'm new to React, it took me a while to configure and get things working (on my machine and on my mind).
One of the greatest benefits of React is the semi-transparent server side rendering.
I wonder how (and if) I can check the user login status while rendering the page on the server side.
For now I'm not able to achieve it, and React is telling me that this is bad:
Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server

Rendering components on the server side with code splitting in webpack

I am trying to build a webapp using React, React Router and Webpack libraries, and taking advantage of server side rendering.
Now, I have a basic structure working - when I visit a URL, the page is rendered on the server, sent back to the client where React confirms that the output rendered on the client side matches with what's generated on the server and takes over from there.
My problem is when I try to open URLs which have to load components asynchronously.
When I visit a URL which has to load a dependency asynchronously, the server renders the output including all dependencies, but when it comes to the client, the markup which React renders does not include the asynchronously loaded components and therefore is different from server's and I get an error in the console which says
Warning: React attempted to reuse markup in a container but the checksum was invalid.
The way I see it the solution would be to either not render the asynchronously loaded components on server and lose out on the benefits of server side rendering or to somehow tell React to ignore the differences between the server and client, and not discard the server's markup, because I know that the component will eventually be loaded and markups will match.
Has anyone else come across this problem and knows what a good solution would be?
You need to also run match on the client side to load all the route components.
There's a fleshed out example available at https://github.com/rackt/example-react-router-server-rendering-lazy-routes.

Categories