I'm developing a very dynamic web application via ember.js. The client-side communicates with a server-side JSON API. A user can make various choices and see diced & filtered data from all kinds of perspectives, where all of this data is brought from said API.
Thing is, I also need to generate static pages (that Google can understand) from the same data. These static pages represent pre-defined views and don't allow much interaction; they are meant to serve as landing pages for users arriving from search engines.
Naturally, I'd like to reuse as much as I can from my dynamic web application to generate these static pages, so the natural direction I thought of going for is implementing a server-side module to render these pages which would reuse as much as possible of my Ember.js views & code.
However - I can't find any material on that. Ember's docs say "Although it is possible to use Ember.js on the server side, that is beyond the scope of this guide."
Can anyone point out what would be possible to reuse on the server-end, and best practices for designing the app in a way to enable maximal such reuse?
Of course, if you think my thinking here doesn't make sense, I'd be glad to hear this (and why) too :-)
Thanks!
C.
Handlebars - Ember's templating engine - does run on the server (at least under Node.js). I've used it in my own projects.
When serving an HTTP request for a page, you could quite possibly use your existing templates: pull the relevant data from the DB, massage it into a JSON object, feed it to handlebars along with the right template, then send the result to the client.
Have a look at http://phantomjs.org/
You could use it to render the pages on the server and return a plain html version.
You have to make it follow googles ajax crawling guides: https://developers.google.com/webmasters/ajax-crawling/docs/getting-started
Related
I would like to serve a react project from the nodejs server. I encountered the two ways of doing it:
The first way is to use express to serve just the build folder for whatever the req made:
const express = require('express')
const app = express()
const path = require('path')
app.use(express.static(path.join(__dirname,'build')))
app.get('*',function(req,res){
res.sendFile(path.join(__dirname,'build','index.html'))
})
module.exports = app;
The second way is one using ReactDOM.hydrate and ReactDOMServer.renderToString to serve the app. It is described here.
What is best way to achieve the good SEO from the above mentioned ways and when to choose one over other?
Thank you!!!
CSR
The first approach, where you just serve the build folder and direct all the requests to index.html is a default way of how single-page applications (SPA) work. This approach is called Client Side Rendering (CSR), meaning that client (browser) will be responsible for preparing all the content of your website via executing javascript code of your application, then fetch all the data from API (news, posts, profile, etc.) and, finally, build the page layout and display everything on the screen.
SSR
In turn, with the second approach you mentioned, server prepares (renders) the whole document (HTML) with content and sends it to the client which only needs to display it. This is called Server Side Rendering (SSR) and in your case the ReactDOMServer is responsible for that. However, since you want your application to be interactive, you need to "revive" it with javascript (in our case with React) and that is what ReactDOM.hydrate actually does. It appends all the necessary event listeners to existing markup and makes page to behave in the way it would behave if it was fully rendered on the client (default CSR).
SEO
There is a general opinion that using CSR has a bad impact on SEO because bots crawling the site need to perform additional steps (execute javascript) and it slows down the process and make it less efficient, moreover, not all the bots can run javascript at all.
However, nowadays, modern crawlers (e.g. Google) can cope with SPA quite good, but the end results might be not as good as with SSR.
If you are at the beginning of project development and SEO is really a very high priority for you, then you should choose SSR.
However, instead of implementing everything yourself with ReactDOMServer and hydrate, I'd recommend you to take a look at the Next.js - it is powerful and easy to learn React framework.
P.S.
SSG
You also should be aware of the Static Site Generation (SSG) approach, where every single page of your application gets prerendered at the build stage, producing bunch of HTML files and other assets of your site. Then, all those static files are served from a simple hosting and/or CDN. The main benefits of such approach are: very high speed of page loading, great SEO and usually very low cost for maintenance.
However, this approach suits only sites where content changes very rarely and pages are not interactive. Of course, you may combine it with hydration, but it often leads to quite tricky and buggy solutions in the end.
You can read more details about all three approaches here.
React renders on the client side by default. Most search engine bots however, cannot read JavaScript. Therefore, using server-side rendering is better for SEO, because it generates a static HTML file on the server, which is then served to the client.
Another difference is that client-side rendering will take longer to load the first time, but all consecutive times it will render faster (if the client didn't disable cache). A server-side rendered website has to render the page everytime it loads on the server. Making it slightly slower on average, but will provide consistent loading speeds and a faster first-time loading speed which is important for business landing pages as an example.
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.
My issue: For my thesis I am creating an auction site. I have an admin panel in which I would like to have some configurations so that an admin can specify that if there are 10 days before the end of an auction some components should be displayed in different ways, some should be not visible at all etc. That’s what I call dynamic presentation.
My question: Right now I am working on architecture and wondering if SSR can be helpful in any way? I am already aware that it can shorten download time of some collections from my database even by half, but I am wondering if there is any way how it can be helpful with dynamic presentation itself?
What I already know: I have read all about advantages and disadvantages of ssr or universal rendering in react. Now I am only wondering if it can be in any way helpful with dynamic presentation or it won't matter if I choose SSR or CSR.
Small side question: I don’t have the whole architecture ready yet. What I know is that I would like to have a database, one separate app for an admin, backend and frontend (either ssr or csr). My first thought on how to manage this dynamic presentation was to store some rules in the database. Then the rules could be configured in admin app should an admin want to change anything. The rules should be send to backend and calculated with some additional data from frontend. Then backend could send some flag to frontend indicating which components to display etc. In theory I could move calculating to e.g. NodeJs server should I go with SSR. What I'm wondering about is; can you think of any better way to handle dynamic presentation? What I am most afraid of is numerous ifs in the fronetend. I would like to have some more elegant solution but I have no other idea so far. For some time I thought about a scoring system but I believe it would be too complicated (instead of sending a flag, send a score and frontend will display correct things based on the score). Also it wouldn’t solve the issue of ifs on the frontend.
I am aware that on StackOverflow questions which can be answered rather than discussed are preferred but I am really stuck and would appreciate help.
Basically SSR can provide some speed on your page because all of your data will not be trying to be fetched when the react script will end with an API call. Data are fetched from database when page is requested and be passed to the component to render with the script.
Also another very basic advantage and the reason why everyone are going the SSR way is SEO. You cannot achieve SEO page with react CSR. This is because google bot etc will try and crawl your page without even render it. Is like trying to "view source" of a page. When you are in CSR the page has no content only the initial react divs empty. You need SSR to have data on the first request of the user.
SSR brings the data on the first request of the user until a reload. In the meantime react router fetches data from the api.
Let me know if that help you.
PS: also a helpful link https://medium.com/walmartlabs/the-benefits-of-server-side-rendering-over-client-side-rendering-5d07ff2cefe8
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.
I already asked a similar question but this one is a bit different/specific:
I'm about to start development of a social community site (for a local user group) with features like timeline, IM/chat, forums, ...
Node.js and socket.io (or now.js) on the backend. jQuery (and maybe backbone.js or similar) on the front end. Content is loaded via socket.io or ajax and navigation via url hash.
There are 2 things where I just can't decide which way to go. I hope here are some people who can provide some good or bad experience.
Templating on server or in browser? I'm not sure if it's better to load a complete html site + live updates (also in html) for timeline, forum posts, IM/chat, ... or use something like a REST api via ajax or socket.io and do the templating on the client site. I've never done that before. You need to download the templates, etc, etc. Has anyone experience in this? There are also 2 ways to implement a rest-like api: E.g. request a forum post, then request the user associated to that post and so on (just like server side MVC) - or - request a forum post and the server answers with all needed information.
Load content via ajax or socket.io? I'm definitively using socket.io or now.js for real-time communication (IM, chat) and pubsub (on mainpage -> subscribe to new timeline updates, on a forum topic -> subscribe to new posts). But should I also load HTML (or provide a REST-like API, see question 1) through the socket? When people open forum posts in tabs (which I usually do a lot) that would mean a lot of socket connections. And I'm not sure how long it takes for a websocket to establish connection.
So there a 4 ways to do this:
HTML via AJAX - probably the most stable way that doesn't need a lot javascript to do the templating - Browser can use open HTTP connections to request stuff.
HTML via socket.io - The websocket must be established to load content (may be slower)
API via AJAX - as it probably needs more requests as HTML via AJAX there might be some HTTP header overhead + you need to authentication in each request- I'm not a friend of too many ajax requests.
API via socket.io - Socket must only be authenticated only once and you can request API objects on the fly. However I would still load templates and js via HTTP for browser caching.
I know this is a huge post but I'm debating for many days now and just can't decide as it would be a lot of work to switch the system once started developing. This is not a public project, it's limited to ~10k-15k local people and thus must not be that perfect, a good opportunity to learn new things in my opinion (I'm completely new to node, classic PHP MVC + jquery dev here).
I think you should use a RESTful api on the backend, let the templating occur just on the frontend (maybe with Backbone) and only use Socket.IO for real realtime stuff (such as chat). It doesn't make any sense to use websockets for something like loading HTML, because it most likely never changes.
So my vote is:
1) HTML via AJAX
2) API via AJAX
3) Realtime communication, such as chat messaging (or other stuff that constantly changes) via Socket.IO
Though there really isn't a definitive answer, as it depends.
If you need to be search engine crawlable, you can NOT rely only on client-side processing. If your individual views are light, and/or you need to support mobile, you should have initial rendering server-side.
Currently, I would suggest using an API that both your client application and server-side can use. If you use node for the server-side rendering you can re-use a lot of the same logic, including the API client.
Going a few steps farther, if you look starting with the Yahoo flux examples project on github, you can use the same logic both client and server-side including rendering with React views. This is not an easy solution, and will take some work.
For interactive elements, server-side rendering can be minimal with your stores pushing an event wiring up via sockjs/socket.io when the client starts for your chat/im bits.
You will have scalability issues when it comes to running across multiple processes and will likely need a pub/sub chain backed by a db for longer re-connect cycles or missed IM messages. There isn't a magic bullet.
Right now, I like flux+react... When Angular2 comes out, it may have a better story for server-side rendering.