9 ms·
Rendering React without browser JavaScript
- brudgers 11y agoRepository for modified tutorial: https://github.com/firasd/react-server-tutorial https://github.com/firasd/react-server-tutorial
- e12e 11y ago[ed: I got a bit carried away, I should've prefixed this with a big thank you for a nice and concise intro to setting up a sane reactjs environment! It's refreshing to see live reloading of comments posted from the console by w3m show up in Firefox!] Ouch, any chance that these examples could be dual-lincenced under cc0/public domain (where applicable) and something like MIT/BSD/APL in jurisdictions without public domain? Because, frankly examples that are: "The examples provided by Facebook are for non-commercial testing and evaluation purposes only. Facebook reserves all rights not expressly granted." are worse than useless. If you end up using anything from the examples in production, you're in breach of copyright!?
- deleted 11y ago[deleted]
- leetbulb 11y agofull circle?
- smadge 11y agoWas going to say the same thing. Depressing. Most js devs probably don't realize the irony.
- profeta 11y agolove how your comment was downvoted to oblivion and yet, the thread went on and on. the irony indeed.
- chrisfosterelli 11y agoHow is this full circle? Traditional server-rendered pages don't support the ability to navigate to new pages and fully interact with the application without refreshing.
- smadge 11y agoTraditional server-rendered pages would prioritize serving content first. Then they would sprinkle in some javascript to provide dynamic features(like navigating to new pages without refreshing). This is exactly what "isomorphic javascript" is providing now, in a very roundabout manner.
- chrisfosterelli 11y ago> sprinkle some javascript to provide dynamic features I've never seen any added javascript to a page that went as far as generating and rendering other pages completely, that's always been a refresh. If it's not then that's literally the same thing as a SPA, and is actually isomorphic javascript. The "sprinkled javascript" that your talking about was basically used to do some simple DOM manipulation and a few XHR requests. It is not the same as a full single page app that is bootstrapped from server-side markup.
- deleted 11y ago[deleted]
- smadge 11y ago> I've never seen any added javascript to a page that went as far as generating and rendering other pages completely, that's always been a refresh. pjax[1] does what you are describing. There are other similar libraries as well. On user navigation, it makes a XHR request to the server, and updates in place any changed DOM elements. I like this, because it progressively enhances the user experience. An application should focus on serving content quickly to the user, then improving the experience where browsers leave a gap. Notice that pjax provides the same functionality as an isomorphic javascript without inflicting upon the world server side javascript ;) [1] https://github.com/MoOx/pjax https://github.com/MoOx/pjax
- Pxtl 11y agoWe're back to aspnet web forms and the update panel, but with a less terrible API.
- matthijs_ 11y agoReminds me of Ember FastBoot. Different framework, different use case, but relatively easy to implement. https://github.com/ember-fastboot/ember-cli-fastboot https://github.com/ember-fastboot/ember-cli-fastboot
- sotojuan 11y agoNot "relatively easier"... quite literally just two commands! The people behind FastBoot are amazing.
- c0achmcguirk 11y agoI love how Ember keeps borrowing the best ideas from the other frameworks and evolves in a pretty responsible way.
- michaelchisari 11y agoI love React, but it seems like it would be easier and more productive to use a toolchain that had a much smaller payload (like Mithril, or React-lite), than engineering a solution like this. If performance and time-to-click was your concern.
- leeoniya 11y agoI'm consistently amused by the amount of learning, tooling and dependencies needed to get these things working (and not very fast at that). Accomplish the same [1] in 15.5k (min): actually fast [2] vdom view layer, router, isomorphism and observers. IE9+ with an additional 9.5k of polyfills [3]. Disclaimer: i'm the author. [1] https://github.com/leeoniya/domvm#isomorphism-html-attach https://github.com/leeoniya/domvm#isomorphism-html-attach [2] http://leeoniya.github.io/js-repaint-perfs/domvm/ http://leeoniya.github.io/js-repaint-perfs/domvm/ [3] https://github.com/leeoniya/domvm/blob/1.x-dev/dist/polyfills.min.js https://github.com/leeoniya/domvm/blob/1.x-dev/dist/polyfill...
- aaron-lebo 11y agoI love it, but what about React Native. How do you match that?
- leeoniya 11y agoIf you want React Native, then you need React :) From what i gather, React Native is good enough for simple things and is iOS-first, but quickly fails to live up to the hype for anything moderately complicated and is actually slower than apps that are native from the get-go. I'm not sure if this is still the case, but aiming for the lowest common denominator seems like a lot to give up. I would be interested to see a React Native app that truly benefits from being native, aside from the app store and distribution aspect.
- tomcampbell 11y agoLoving it, thank you. Had not run into your repo before. Feels incredibly tight, logical, and easy to learn.
- chrisfosterelli 11y agoThis is cool! It's worth pointing out that, for SEO reasons, Google now renders Javascript pages [1] without methods like this. The performance benefit is definitely still a plus though. [1] https://webmasters.googleblog.com/2014/05/understanding-web-pages-better.html https://webmasters.googleblog.com/2014/05/understanding-web-...
- firasd 11y agoGoogle has been saying that for years, but I don’t really believe it… 1) First there were the "hashbang" URLs, that Google said they'd crawl fine, but that did affect Gawker's SEO: http://www.webmonkey.com/2011/02/gawker-learns-the-hard-way-why-hash-bang-urls-are-evil/ http://www.webmonkey.com/2011/02/gawker-learns-the-hard-way-... 2) And instagram uses server rendering for SEO: https://twitter.com/cpojer/status/711729444323332096 https://twitter.com/cpojer/status/711729444323332096 (via http://jamesknelson.com/universal-react-youre-doing-it-wrong/ http://jamesknelson.com/universal-react-youre-doing-it-wrong...)
- chrisfosterelli 11y agoThey've been working on it for years, and improving it. They've only recently started claiming that their javascript rendering was ready for "prime time". The "hashbang" URLs (they call them Escaped Fragment URLs) actually required you to use server-side rendering, that had nothing to do with the spider's javascript rendering engine. I used them on a few sites and it worked pretty well, but I have heard of mixed results on sites that weren't originally on hashbang URLs who transitioned to them. They don't recommend you use these anymore.
- profeta 11y ago> "hashbang" URLs (they call them Escaped Fragment URLs) why not use the RFC terms? https://tools.ietf.org/html/rfc3986#section-3 https://tools.ietf.org/html/rfc3986#section-3 "url fragment" Also, it won't help you on server side rendering since the server will never even see it on the request.
- drcode 11y agoI was hoping this would be a story about native react-style rendering within the browser engine itself, something I've been waiting for since virtual DOMs first started becoming popular.
- dustingetz 11y agoI still remember your Conj talk in 2012 about virtual dom, 6 months before react was announced. Where did you first get the idea?
- daxfohl 11y agoI was hoping it would be a story about injecting links/buttons for each possible state transition on a page, that would cause a full browser refresh from the server.
- firasd 11y agoNot quite sure what you mean? If you turn off JavaScript in the example app you do get something like that—the links reload the browser page, and the comment form submits the comment, then renders the new state of comments (just by processing the comment on the form submit and then re-directing you back to the page.)
- daxfohl 11y agoSomething more universal (albeit less useful). i.e. something that automatically checks your rendered DOM for every possible Redux state transition, creates a callback URL for it, and sticks a link for that at the bottom of the page. Essentially, distributed redux: if redux is (state, action) -> state, then that over HTTP.
- smadge 11y agoI feel like the problem being solved by React and other virtual DOMs are only relevant because user agents never bothered to solve janky page transitions. Couldn't browsers do a minimal DOM update themselves without losing context or introducing weird flashes? Is this what you mean by "react-style rendering within the browser engine itself"
- diegorbaquero 11y agoWe need to get back to server-side cached rendering. Thinking mobile-first and lightweight websites. I feel in the last few years we've added so many things and we are no thinking on the people with slow internet. Ember FastBoot now this, Angular 2 coming with it. We are going towards hybrid awesome front-ends which load fast and deliver the best UX we've had. Thank you for the great effort.
- firasd 11y agoFor sure. I was always uncomfortable with JS frameworks that used markup with no content from the server. In my professional experience I've also found that developers underestimate how slow Ajax requests are in real world scenarios. I wrote some comments on this when I started learning React, just gonna screenshot them instead of pasting: http://i.imgur.com/XSnCqjK.png http://i.imgur.com/XSnCqjK.png Two great articles I reference in this tutorial: 1) http://tomdale.net/2015/02/youre-missing-the-point-of-server-side-rendered-javascript-apps/ http://tomdale.net/2015/02/youre-missing-the-point-of-server... 2) http://rauchg.com/2014/7-principles-of-rich-web-applications/ http://rauchg.com/2014/7-principles-of-rich-web-applications...
- awalGarg 11y agoI am curious how this would change with the multiplexed pipe of HTTP2 where doing a lot of requests is not as expensive. I did a couple little tests a while ago with nginx 1.9.1 mainline, and while the results did show a little performance improvements in figures, they weren't observable - but this could be because I didn't put in much care while doing those tests and I probably did some mistakes. Anyone else has done good benchmarks on real world single-page-apps which do a lot of back-n-forth communication with the server with http2? I don't expect things to get suddenly extremely better (specially since resource fetching is only one of the bottlenecks), but maybe it could bring a mid-way between the server vs client side rendering war.
- frandroid 11y agoHTTP2 will help, but it'll also make server-side rendered pages load even faster, before you load all of your client-side JS.
- oolongCat 11y agoEvery time I see someone mention react and other frameworks are bad for SEO, I cant help but think, shouldn't search engines have to worry about this. Google and other search engines have brilliant people working for them who can create systems which can guess what I want to search before I have entered the entire query, and you are telling me these same people can't do something about pages using the latest technology. Sigh.
- deleted 11y ago[deleted]
- firasd 11y agoGoogle has been working on this (I don't have deep knowledge of whether their solution is adequate for SEO. I just found this article that suggests it works fine: http://searchengineland.com/tested-googlebot-crawls-javascript-heres-learned-220157 http://searchengineland.com/tested-googlebot-crawls-javascri...) But I think, while we're making assumptions about the kind of technology good engineers should create, let's also ask Google-led Angular and Facebook-led React (and similar projects): if your library can manipulate HTML and the browser DOM, even while using async network requests to load data, why can't it take that same data and code to provide an HTML string upfront, as a "First Render"? This should be the standard way to do it. If React can re-render an input box every time I type a character, and not just generate HTML but also directly manipulate the DOM to reflect it, surely it can generate HTML for the input box upfront. (I don't know enough about the internals of these libraries, but maybe the fact that React is declarative makes this easier than it is for other libs.)
- neogenix 11y agoHere is another blog that tested it and concludes it works fine on Google: http://www.centrical.com/test/google-json-ld-and-javascript-crawling-and-indexing-test.html http://www.centrical.com/test/google-json-ld-and-javascript-... I don't think Bing and Yandex are supporting this yet though.
- tyingq 11y agoThere's a followup to that article where they specifically look at Ajax and conclude that there are still issues: http://searchengineland.com/can-now-trust-google-crawl-ajax-sites-235267 http://searchengineland.com/can-now-trust-google-crawl-ajax-...
- amelius 11y agoHow would you render (to a cache) server-side if the rendering depends on the display size in a complicated way (too complicated for CSS to handle)? Edit: yes, I understand that rendering means generating HTML, but sometimes the HTML depends on display size.
- imaginenore 11y agoRendering means generating HTML in this case. The HTML rendering happens in the browser.
- firasd 11y agoI suppose it depends on how complicated the logic is behind your conditional HTML. If there is an initial JS payload that checks the screen size, I might still try to get an HTML string back from the server after checking the size. But there are certainly diminishing returns to server-side rendering if you're making multiple HTTP calls anyway.
- daxfohl 11y agoGreat timing. I was just going through the referenced "Tutorial: Handcrafting an Isomorphic Redux Application (With Love)", having gone through the React tutorial the day before. When I first saw your article, I thought it was nothing more than a rehashed version of the "With Love" one. But as I got to the end of "With Love" I wondered: # "With Love" uses an external API server; how would I handle API requests on the same server? # There's no real demonstration of how to do routing beyond a single route. # "With Love" is unfinished, with no live updates etc. # How to integrate even simplistic file-based persistence? The Facebook tutorial had all that, but I wasn't sure how to integrate those features into a server-side-rendered framework. So essentially my next step would have been to figure out how to do what you just did here. The extra work of making the application functional (beyond just showing the pre-rendered screen) is icing on the cake.