Server-side rendering with ReactDOM.hydrate - node.js

hydrate has landed to React 16, but its use isn't documented yet.
This article suggests that it is is supposed to be used with renderToNodeStream but doesn't give much details.
What is the expected usage of hydrate?
renderToString is synchronous. It also cannot handle re-rendered components, i.e. when synchronous (i.e. same tick) changes happen in component state during initial rendering and are supposed to trigger additional render calls. The example is Helmet that requires a workaround in order to propagate changes from nested Helmet back to top-level component on server side.
Can hydrate and renderToNodeStream help to avoid renderToString limitations and render asynchronous and/or re-rendered components on server side?

hydrate's usage is not limited to renderToNodeStream - you can (actually should) also use it with the classical renderToString. renderToNodeStream is essentially the same as renderToString with exception that it produces an http stream instead of a string. This means that you can send the rendered html to the client byte by byte during rendering, contrary to the standard renderToString, when you have to wait for the whole html string to be rendered first, and only after can you send it to the client.
ReactDOM.hydrate is a replacement for standard ReactDOM.render. The basic (and only?) difference is that, contrary to ReactDOM.render, it doesn't throw away all the DOM if React's checksum on the client doesn't match the one calculated on the server. It tries to attach React client app to the server-rendered DOM even if there are some subtle differences, by patching just the differing parts.
Due to the streaming nature of renderToNodeStream, Helmet's server-side usage is practically impossible in the current state of the library - the head part of the DOM is sent to the server by the time React get's to compute the DOM including Helmet's components. The stream can't just revert and append Helmet's changes to head.
So to sum, answering your question - renderToNodeStream solves the problem of synchronous rendering to string by sending stream, but it introduces new problem of not being able to patch the pushed content if some further part of the React App requires it. It doesn't add anything in terms of state changing and rerendering on the server side. On the other hand, hydrate doesn't introduce anything new in this topic - it's just a tuned up, more forgiving version of the old render.
The official docs explain a lot! https://reactjs.org/docs/react-dom.html

Related

What is the difference between server side rendering (Next.js) and Static Site rendering (Gatsby.js)?

I'm looking to create a website that does not rely on client-side JavaScript, however, I still want to use SPA features like client-side routing etc, so I am looking at using a framework that does not render on the client-side. These 2 seem to be the top options for this type of thing, however, I'm unsure as to the differences between the 2 different types of server processing.
Server side rendering is where a request is made from the client/browser to the server, and then at that point the HTML is generated on-the-fly run-time and sent back to the browser to be rendered.
Static site rendering is very similar, however the parsing is carried out during the build time instead. Therefore when a request is made the HTML is stored statically and can be sent straight back to the client.
They both have their pros and cons:
Although static sites will be faster at run-time as no server-side processing is required, it does mean that any changes to data require a full rebuild over the application server side.
Alternatively, with the server side approach, putting any caching aside, the data is processed on-the-fly and sent straight to the client.
Often the decision is best made depending on how dynamic and real-time your content must be vs how performant the application needs to be.
For example, Stackoverflow most likely uses a server-side rendering approach. There are far two many questions for it to rebuild static versions of every question page each time a new post is submitted. The data also needs to be very real-time with users being able to see posts submitted only seconds ago.
However, a blog site, or promo site, which hardly has any content changes, would benefit much more from a static site setup. The response time would be much greater and the server costs would be much lower.

Does one-way binding imply there are no watchers using a setTimeout function?

From what I am reading, two-way binding means there are "watchers" that implement a setTimeout in JavaScript every so many milliseconds to keep the model and view inline with each other.
In one-way binding, once the view is populated, are the events that are assigned to an element what triggers syncing between model and view, thus no "watchers"? My reason for asking is I do not believe using "watchers" is wise, but this will help me verify. The browsers JS event loop seems to be sufficient for events.
(Please assume Angular, React, and Vue, if it is necessary to answer the question.)
I have read this,
One-Way or One-Time binding in Angular and Watchers

Which method is faster, express : Server-side rendering vs client-side rendering

What I would like to know is, how do you built your web application? I'm really confuse as which method should I use for my project.
Already decided which technologies to choose.
1) Node.js and express as its Framework
2) MongoDB
3) React + Flux
But the problem right now, should I use method (A) or method (B)
Method (A) - Serverside rendering for HTML
app.get('/users/', function(request, respond) {
var user = "Jack";
respond.render("user", { user: user });
});
Method (B) - Clientside rendering for HTML
app.get('/users/', function(request, respond){
var user = "Jack";
respond.json({ user: user });
});
Method A will render the HTML from the server and as well as the data.
Method B will just respond the data that is needed for the client which is React.js, so that it could manipulate the data.
My concern, is which method should I use? most startups use which method?
Thank you.
It's not an either/or proposition.
React is a client side framework. You have to render on the client side. The question is whether to render on the server side in addition to rendering on the client side.
The answer? If you can, YES!
You will get SEO benefits and an initial performance boost by rendering on the server side. But you will still have to do the same client side rendering.
I suggestion googling "isomorphic react" and doing some reading. Here is one article on the subject.
http://www.smashingmagazine.com/2015/04/react-to-the-future-with-isomorphic-apps/
Well, it really depends on which vision you have on the modern web, and what you are willing to do.
Will you prefer to let your users wait, displaying a loader while data are loaded asynchronously, or will you prefer to keep your users busy as long as you can ?
Here are different articles that will help you clear your mind and be aware of the different advantages that you can have by doing server-side rendering, client-side rendering having multiple issues.
You can see this post from Twitter blog saying they improve their initial page load by 1/5th to what they had before, by moving the rendering to the server:
https://blog.twitter.com/2012/improving-performance-on-twittercom
An other article, this time from airbnb, describing the issues you can have with client-side rendering itself:
http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/
There is also an other interesting article talking about client-side/server-side rendering, bringing a debate on when should we use / not use server-side or client-side rendering and why:
https://ponyfoo.com/articles/stop-breaking-the-web
And to finish, I can give you two more link more focused on react, and describing in which way server-side rendering should be helpful for your case:
https://www.terlici.com/2015/03/18/fast-react-loading-server-rendering.html
http://reactjsnews.com/isomorphic-javascript-with-react-node/
Now, about what you SHOULD do, it's a matter of what you exactly need to do, to my opinion, but basically, you can do both at the same time (client-side AND server-side), to have the best user experience.
This concept is called "isomorphic javascript" and it is getting more and more popular these days.
The simplest architecture is to just do dynamic html rendering on the server, with no Ajax, and with a new HTML page requested for pretty much any client click. This is the 'traditional' approach, and has pros and cons.
The next simplest is to serve completely static html+js+css (your React app) to the client, and make XMLHttpRequest calls to webservices to fetch the required data (i.e. your method B).
The most complex but ideal approach (from a performance and SEO perspective) is to build an 'isomorphic' app that supports both approaches. The idea is that the server makes all the necessary WS calls that the client would make and renders the initial page that the user has visited (which could be a deep-linked part of the application), a bit like option A but using React to do the rendering, and then passes control to the client for future DOM updates. This then allows fast incremental updates to the page via web-service calls as the user interacts (e.g. just like B). Navigation between different 'pages' at this point involves using the History API to make it look like you're changing page, when actually you are just manipulating the current page using web-services. But you you then did a browser refresh, your server would send back the full HTML of the current page, before passing control to client-side React again. There are lots of React+Flux+Node examples of this approach available online, using the different flavours of Flux that support server-side rendering.
Whether that approach is worthwhile depends on your situation. It probably makes sense to start using approach B (you can share the your HTTP API between mobile apps and websites), but use a Flux architecture that supports server-side rendering and keep it in mind. That way, if you need to improve the performance of initial page loads, you have the means to do it.

How should one initialize a page in backbone.js, to minimize HTTP requests and latency

I am learning about backbone, and from the examples and tutorials I have gotten this impression:
The initial GET / returns the skeleton page with backbone and the view templates.
Backbone uses the REST API to flesh out the page by GETting the data it needs and adding it into the DOM.
This works, but it seems wasteful in terms of additional HTTP requests, and latency from the perspective of the end user (minimum two round-trips before the page is visible. Actually three in my case, since the API must first ask which widgets are available, and then fetch the details on any available widgets....).
Is there an established, standard method for getting around this? My current candidates are:
Ignore the problem.
Embed the initialization data directly into the original page via inline javascript.
Render the page as if backbone didn't exist. When backbone finishes initializing, it will (hopefully) be in sync with the page as the user sees it. It can correct anything it needs to if things changed in the intervening couple seconds, but at least the user is not left hanging.
Another solution I haven't thought of?
Is there an established way to do this? Is it situation-specific? I am using Node / JS / Express.
Update: I think I found a solution, possibly the "accepted" solution, in Backbone's documentation:
Here's an example using reset to bootstrap a collection during initial page load, in a Rails application.
<script>
var Accounts = new Backbone.Collection;
Accounts.reset(<%= #accounts.to_json %>);
</script>
Calling collection.reset() without passing any models as arguments will empty the entire collection.

Does comet server data in the iframe just accumulate?

I push [script]dosomething()[/script] tags into the iframe for my comet server using chunked data, but script tags just continues to accumulate forever. How do I wipe it after every script tag?
Wipe script tag
P.S: When you want to wipe script tags it is probably to follow Does comet server data in the iframe just accumulate?
I believe you should close the connection after sometime(no good, see Does comet server data in the iframe just accumulate? instead) which automatically frees up the memory associated with that request. You then off course need to reconnect. This page says something else even:
"Page Streaming" means the browser
discovers server changes almost
immediately. This opens up the
possibility of real-time updates in
the browser, and allows for
bi-directional information flow.
However, it's quite a departure from
standard HTTP usage, which leads to
several problems. First, there are
unfortunate memory implications,
because the Javascript keep
accumulating, and the browser must
retain all of that in its page model.
In a rich application with lots of
updates, that model is going to grow
quickly, and at some point a page
refresh will be necessary in order to
avoid hard drive swapping, or a worse
fate.
This advices to reload the page which is also an option. But I think closing that connection(iframe) and reconnecting might also work.
Comet has a lot of problems you need to hack around:
As you can read from this WIKI page it also has problems with "reliable error handling method, and the impossibility of tracking the state of the request calling process.".
Also Internet Explorer needs to sent some junk to get the process started(see http://cometdaily.com/2007/11/05/the-forever-frame-technique/)
That's why I again recommend you to use socket.io(see below) which takes care of all this nonsense.
Socket.io
I advice you to use socket.io instead, which is very good product. It is supported by all major browsers. As you can see it support a lot of transport(XHR, Websockets, etc) and choices the best one available on your browser for the best performance.
Wipe script tag without reconneting
You can remove script tag every time that it is executed by adding some code when the server prints chunk.
<script type="text/javascript">
// Calls your message handler
app.handle("Hello World");
// Removes this script element
var scripts = document.getElementsByTagName("script"),
elem = scripts[scripts.length - 1];
elem.parentNode.removeChild(elem);
</script>
Compressed version
<script type="text/javascript">
app.handle("Hello World");
(function(){var a=document.getElementsByTagName("script"),a=a[a.length-1];a.parentNode.removeChild(a)})();
</script>
But, Hidden Iframe or Forever Iframe is too annoying to use as Alfred mentioned. Personally, I think this classical way makes Comet look graceless and charmless.
jQuery Stream
My recommendation is to use jQuery Stream, which provides the unified two-way communication interface over WebSocket and HTTP protocol. It is a light-weight client-side JavaScript Library such as jQuery.
The enhanced Iframe transport being used by jQuery Stream is different from the classical one in many ways, requries text/plain response containing only messages instead of text/html response and empties the response every time that it's handled.
According to some user's test, Internet Explorer 8 using enhanced Iframe transport has no problem with messages of several megabytes (unlike Firefox using XMLHttpRequest as transport, which is really struggling).

Resources