We've Open-sourced Rendr
nerds.airbnb.comI'm not sure I fully understand this, is this just for SEO? Why not run the page in phantomJS, which is what we do at https://circleci.com, and what meteor apps do, and any others?
SEO was our first concern, but then we realized performance was the big win. Serving the user a full page of HTML rather than waiting for JS to download before rendering HTML makes a big difference, especially on high-latency or low-bandwidth connections (mobile).
EDIT: We decided against using something like PhantomJS or node-chimera because why deal with a DOM if you don't have to? DOM is complicated and slow, compared to string-based templating. Plus, it's another moving part, another process to keep up and running. The Meteor guys aren't too excited about the PhantomJS approach either, and IIRC they'd like to be able to serve HTML without firing up a DOM.
Does this mean Rendrjs applications will run in a JavaScript disabled browser? That would be a big win!
Yep! Because links use full URLs which get intercepted by JavaScript, if JS is disabled, you can still navigate around the app, getting full HTML from the server. Of course, any client-specific code wouldn't run (slideshows, etc).
So far, this is the most convincing argument I've heard for Rendr.
I'm a little confused here. Maybe I'm just not seeing it, but how does that make Rendr any different from any other server-side framework that responds with HTML?
Because you're using the same JavaScript code for rendering on either the client or the server.
How do you measure performance? I'm interested specifically in where & how you instrument, and how you collect the data.
Cool stuff, thanks for the response!
Or Zombie, which is way faster than PhantomJS: https://github.com/bfirsh/otter
Posts like this makes me think Airbnb is a awesome place to work. Sharing is caring!
I want to see them start open sourcing more of their i18n and translation tools. Most people aren't aware of this, but one of the coolest problems you can work on at AirBnB is building out tools and features that let two people, who don't speak a common language between them, transact with one another. There is no other startup I know of as vested in solving this problem.
Indeed! We've started with polyglot.js[0], an i18n helper for Node.js and client-side javascript, but there's definitely a lot going on besides this.
It's great to see AirBnb's open sourced work, and tech talks, etc. Kudos to them - I'm sure it helps a lot with recruiting. I used to work for a company in a similar space and looked to AirBnb with deep envy.
Luckily for me it has been a long time since I was in that situation. Anyone would be wise to check that page, though- fantastically designed.
My girlfriend's brother works there. Based on what I've heard from him, I'm pretty jealous, but she's worried if I worked there I'd never come home.
Fourth link on the page links to http://nerds.airbnb.com/github.com/airbnb/rendr-app-template (which obviously does not work) instead of http://github.com/airbnb/rendr-app-template
Indeed it does. Thanks for the heads up, we'll change that.
Thanks, fixed.
Previewed and discussed back in January:
http://nerds.airbnb.com/weve-launched-our-first-nodejs-app-t...
Anyone interested in something like this should also check out PJAX. Push State and AJAX. https://github.com/defunkt/jquery-pjax
This is what GitHub uses between tabs on its Pull Requests page. I love how simple the implementation is.
Your app still needs to follow the convention of having links going to different pages with URLs. I know it's not "single page" and the interaction is not that "rich." But it's nice because all your logic is still on the server, all rendering and templates are on the server and the server responds with either a full page of HTML or a partial page of HTML depending on an HTTP header you set.
Oh yeah, it also works without Javascript, crazy!
That is how Backbone and all other current frameworks work.
No it isn't.
Care to explain? They use pushState or hashes for routing, and load data via XHR. If you are using pushState it is assumed that the URL must exist on the server.
Having the URL exist on the server isn't the same as serving a rendered page from the URL, which is what most SPAs do. You could just rewrite all URLs in a website to point back to your index.html, then have the client side router initialize the app from the URL parameters. If you don't have javascript turned on (e.g. googlebot) then all you'll see is a blank page
Googlebot interprets javascript. In that case you shouldn't use pushState but fragment URLs[1].
I should have said it is assumed that the URL exists on the server and points to the same resource/content; otherwise setting URLs using pushState makes no sense. GitHub is a good example of how it should be done, not an exception.
[1] https://developers.google.com/webmasters/ajax-crawling/docs/...
Just wondering what's the difference between this post and the last one where Rendr was already open-sourced? I mean, it was already open sourced for a while. Is there a change log or an adapter to better integrate with other systems? Thanks!
At the time of the previous post, Rendr was not yet open-sourced.
The big change is that I missed the previous post, but noticed this one :)
Wow, looks very impressive from my quick look over it.
These days, there are so many JavaScript frameworks for web development, it's starting to make my head spin a little bit.
Does anyone have a link to a good rundown of where everyone stands?
What do you mean by "where everyone stands"?
I agree that there are so many JS libs/frameworks now that it is hard to keep up with! I actually started on a super simple script for myself to compare git repos general stats.
> Does anyone have a link to a good rundown of where everyone stands?
Well, even if I had one, it would be outdated in 2 weeks..
Being a JS developer must be the pits - you need to run really fast just to keep up.
...you need to run really fast just to keep up.
This is exactly the part of being a JS developer that is appealing :)
This is an awesome solution for folks using Backbone and who don't mind a tight framework coupling.
But if you're not on Backbone, or don't want to add another constraint to how your app is built, it's pretty easy to set up your own PhantomJS server; I presented on this very topic at TXJS this week[1], and created a library[2] that makes it a snap to set up.
[1] http://www.flickr.com/photos/tr4nslator/sets/721576332659462...
Are there any similar efforts to tie the server with the client, reducing duplication, for Angular?
Angular uses DOM templating instead of string-based templating (most current JS templating engines are string-based), so you would definitely need to fire up a headless browser (PhantomJS) or DOM (JSDOM) of some sort to get it working.
It would be very slow if you were doing this dynamically so you would probably want to regularly compile and cache your pages.
Some links on this topic: https://github.com/steeve/angular-seo http://www.yearofmoo.com/2012/11/angularjs-and-seo.html
Yeah this is the best way to serve rendered pages to search engines. I also found this project: https://github.com/ithkuil/angular-on-server - Which might be worth looking at too.
The first thing I thought of that is similar to Rendr is http://meteor.com/ . I'm not sure about how it works with Angular. It does describe itself as a framework where Rendr describes itself as a library, so I'd think it'd be easier to run Angular stuff on top of Rendr.
There's also hoodie + yeoman, but there aren't any adapters for angular yet. For some reason angular doesn't get official love from libraries like rendr and meteor.
so they have completely ditch Rails and Ruby?
I don't work there, but I doubt it. With rendr, both the client- and server-side portions of the Backbone stack still need to consume an upstream API. If I had to guess, I'd say that for projects they're building that use this stack, all the templating/rendering/presentation logic is in JS, but that the database interaction stuff probably isn't; they probably have Rails apps that expose a RESTful API that the rendr apps consume.
This is exactly right. We still have 5 years worth of business logic in Rails, so we just expose a RESTful API as part of the Rails app. The same API is consumed by our iOS, Android, Mobile Web, and Desktop clients.
Cool stuff, very interesting concept, would love to see an example working with a Rails RESTful API.
The app template is such an example, consuming the public GitHub API: https://github.com/airbnb/rendr-app-template
In the future, we'd like to come up with some more in-depth tutorials.
Great thanks I'll take a look at it again, I seen the "Interacting with a RESTful API" section in the wiki left blank and assumed it was in the pipeline.
IIRC, they are using node.js and rendr for their mobile site and still use Rails for the main website.
We're using Rendr in a few more apps in production, in progress. It's starting to eat away at our Rails site a bit.
Could there be a feature to run the app logic on the client when a connection is not available? Else, it can fallback to the server. This will help a lot when it comes to offline support
IS IT FASTER?
I assume Node/JavaScript will render HTML faster than ruby/rails. Do you have benchmarks?
Node/JS won't necessarily render HTML faster. There are libraries to bring DOM interaction into NodeJS, there's also PhantomJS, and previous attempts like Aptana's server. All of these have been very heavy, and didn't scale well. PhantomJS is probably the best current option, but doesn't tie directly to Node, and still not as fast as string based templating.
Regarding string based templates, they are really implementation dependant, and there are tons of options available. Right now some common ones for NodeJS are probably Bliss (Razor inspired), Nunjucks (jinja2 inspired), Mustache/Handlebars and Jade (Haml inspired), and EJS (similar to PHP, or classic ASP).
Probably the most broadly available is Mustache, which has implementations in about every language under the sun, and probably could make a decent benchmark to compare string processing in different languages.
All of the above simply bring me, to use what you feel comfortable with and what feels right.
Faster than what? V8 can be an order of magnitude faster than Ruby: http://benchmarksgame.alioth.debian.org/u32/benchmark.php?te...
Awesome. Looking forward to checking this out.