Translated from: http://blog.jobbole.com/51786/
At Airbnb, we've learned a lot about building rich applications over the years, and since 2011 we've been working on Single-page applications, especially after we officially launch wish lists and our redesigned search page. Most of them are large JavaScript projects, which means that most of the code is run in a browser, which is also to accommodate a more modern interactive experience.
In the present, this approach is very common, and now some well-known frameworks (Backbone.js, ember.js, angular.js) make it easy for developers to build some rich applications. We've found that in any case, there are some limitations to these applications, and to find out why, let's take a look at the history of Web apps.
JavaScript Group up
From the beginning of the web, the browser works like this: The browser will request a specific page (for example: request http://www.geocities.com) to cause the server to respond and generate an HTML page and send it back over the Internet. This kind of work is already very good at that time because the browser is not very powerful at that time, most of the HTML pages are independent and static files. The advent of JavaScript can make Web pages dynamic, not just to implement picture slideshows and date controls. In the rapid development of personal computers today, some of the cow B programmers have been freed from the limitations of the Web, the browser is also evolving. Now that the Web is a mature and powerful application platform, JS executes faster and HTML5 standards enable developers to create rich applications that could have been built on-premises!
The Single-page App
Soon, with these new features developers start using JavaScript to build the entire site, and these classic single-page apps like Gmail can respond quickly to user behavior rather than just going to the server to render the page.
Some mature frameworks such as Backbone.js, Ember.js, angular.js are often also discussed in the framework of the MVC or MVVM pattern, and this classic MVC pattern looks like this:
Most of the logic is in the client, (view, template, control, data processing, internationalization, etc.) to provide processing interface for the data, the server can be written in any language, such as Ruby, Python, Java, it is to provide an empty HTML page, Once the JavaScript files are downloaded, they are executed and initialized on the client, fetching data from them and rendering the HTML page directly.
This is good for the user experience, because once the app is initialized and loaded, it can support a quick switch between pages and pages rather than refreshing the page, and, as it goes, it can even be done offline.
This is also good for developers, because it can clearly demarcate the "client"/"service", thus facilitating the entire development process, effectively preventing the logical duplication of the two languages, since the front and back ends are usually developed in different languages.
Trouble in Paradise
In fact, it is flawed in any case, but we can use some cases to avoid it correctly.
Seo
If an application only runs on the client, it cannot be "crawler" through HTML, so it is not SEO by default (search engine optimization), normal our crawler is to create a request to the server and then parse the results, but if the server returned empty pages, it is meaningless. But it is not a solution.
Performance
Similarly, if the server does not render the entire HTML page directly, but instead uses JavaScript to do so, the user will see a few seconds of empty pages before loading the entire page or load the control all the time. Many studies have shown that users respond very strongly to slow site visits. Amazon claims Amazon claims that "every 100ms page load speed will increase revenue by 1%" Twtter 40 engineers spent 1 years refactoring, their site (rendering the page on the server side, not the client) claimed to have increased the load time by 5 times times.
Maintainability
Ideally we are going to create a hierarchical, well-defined, low-coupling application to avoid a small amount of application logic code being duplicated at the front and back (usually in a different language for the front and back end). Common examples are date/currency formatting, form validation, and process logic. Maintainability has always been a necessary and difficult part of the design process, especially for complex applications.
Some developers, including ourselves, have been plagued by these problems-usually only if we really work on single-page applications to see where their flaws are.
A Hybrid Approach
In the end, we want a comprehensive solution: we want to get the entire HTML from the server (high-performance, SEO-enabled) but we also want to make the client code run quickly and with flexibility.
To do this, we've tried to build on Airbnb using "isomorphic JavaScript". This is a JavaScript app that can run both on the client and on the server. A "isomorphic" app looks like this, called "Client-server MVC."
In this world, your application and view layer logic can be run on both front and back, which in turn solves all of these problems-performance optimization, good maintainability, SEO, more stateful Web applications.
With node. js, a fast, stable JavaScript running on the server side, now we can dream it. By creating the appropriate abstraction, we can run our logic code on both the server side and the client-this is the definition of "isomorphic JavaScript".
Isomorphic JavaScript in the Wild
This is not a new idea, as early as 2011 Nodejitsu already had a good description of isomorphic JavaScript-but now it is adopted. There are a lot of isomorphic JavaScript frames today.
Mojito is the first open source isomorphic JavaScript framework that you can get by any means. It is completely written in the framework of node. js. But since they were open source in April 2012, the main reason for not being widely popular in the JavaScript community is that it relies on the special model of YUI and Yahoo.
Meteor may be the best isomorphic project in the modern age. Meteor native support for real-time applications, the team is building a complete system around this package manager and development tools.
Like Mojito, it is a large, native node. JS framework that works well in the JavaScript community, and the 1.0 release release is also going to be released. Meteor as a project has been closely watched-it has an All-Star team and received $11.2M funds at the Anderson Foundation – never heard of a company that is so concerned about an open source product.
Asana, is a task management application it is interesting that it was created by Dustin Moskovitz, one of the founders of Fackbook. Moskovitz ' status is the world's youngest billionaire, Asana spent years developing their closed-source project Luna, one of the most famous examples of isomorphic JavaScript. Luna, before it was built on v8cgi, without node. js, it allows for each individual user session to copy a full application to the server side of the run. It creates a separate process for each user, and the server-side code that runs on the client, enabling advanced optimizations for the entire class, such as offline support for immediate updates.
Earlier we launched a homogeneous library called the Rendr Library, which allows you to use Backbone.js + handlebars.js to build a single-page application that can be fully rendered on the server side. Rendr is the product we created to make the AIRBNB mobile web more responsive. It is particularly important for users to have high-availability response times. Rendr strives to be a library rather than a framework, so it solves problems relatively little compared to Mojito or metetor, but it is easy to modify and extend.
Abstraction, abstraction, abstraction
This is often difficult for some large projects, the client and server side is completely different from the operating environment, so we want to create a series of abstractions to decouple the application logic from the bottom out, so we can like developers exposed some separate API.
Routing
We want to get a separate set of routes from the URI pattern routing processor, our route processing requires access to HTTP headers, cookies, URI information, and special redirects (not via window.location or node. js req res).
Fetching and persisting data
We want to describe a resource that needs to render a specified page, or by grabbing the form of a component. This resource descriptor can be a simple URI to point to a JSON data, or to a larger application, through a model, a collection, a specified model class, or a primary key is useful for encapsulating resources, usually in a way that is parsed into a URI.
View rendering
Whether we choose to manipulate the DOM directly, use an HTML template, or manipulate a drawing UI component that encapsulates the DOM to generate an HTML tag, we can also render any page in front and back, which depends on whether your application needs it.
Building and Packaging
So far it's only half way, tools like Grunt and browserify are indispensable in starting and running the application workflow. Here are a few steps to build: Compile the template, including some client dependencies, application obfuscation, compression, and so on. This simple example is to combine all the application code, views and templates bundled together, but for large applications there will be hundreds of KB downloads. One of the best ways to do this is to create a dynamic bundle and take a lazy load, no matter how complex it is. Static statistics tools like Esprima can enable some self-motivated program personnel to try out another step of optimization and use metaprogramming (meta-programs) to reduce code.
Composing Together Small Modules
Isomorphic framework to go into the market means that you have to solve all the problems immediately, but this will lead to a big bulky framework that will be difficult to generalize and difficult to integrate into existing applications. Now that there are a lot of developers who have solved this problem, we will build a lightweight-reusable-inheritable isomorphic program.
It turns out that most JavaScript modules can be isomorphic without modification, for example: Popular libraries like underscore, backbone.js, handlebars.js, and now even jquery can be used on the server side.
To prove this, I have built a simple application "isomorphic-tutorial" You can go to GitHub to download. By combining several modules, each of which is isomorphic, it is easy to create a simple isomorphic application using the Diretor for server-side and browser-based routing with just hundreds of lines of code. Superagent provides HTTP requests and uses Handlebars.js to do page templates, all of which are built based on the Express.js framework, which is, of course, complex to assemble as an application, and must introduce more layers of abstraction, but we want more developers to try it out There will be a new library and a new standard born.
The View from here
More organizations are already using node. js in their products, and it's inevitable that more applications will begin to share code at the front and back. The most important thing to remember is that "homogeneous JavaScript" is a scope-it begins to share only templates, then manages the view layer of the entire project, to the business logic layer of most applications. The fact that the JavaScript code is shared on the front and back ends depends on your programming and its unique constraints.
Nicholas C. Zakas has a good article on "How to get the UI layer from the client to the server" to improve performance and maintainability. An app doesn't need to use node. js to replace the entire backend, which is like "to pour out the child while pouring the bath water", instead to create a good API and a restful resources (here is a Nanyi article to briefly describe what a restful Resource) program, the traditional backstage can be combined with node. js to build.
At the Airbnb website, we have started to refactor our clients using some of the basic tools Libraries of node. js Grunt and Browerify. Our core rails applications may never be replaced with node. js, but we can easily make JavaScript share the same environment with the template.
If you want to be here for the first time, in a few years some advanced Web applications will run JavaScript on the server side.
Learn More
If this idea excites you, then you can come to our isomorphic JavaScript studio to see if, in San Francisco November 12 Wednesday or November 21 Thursday, I will teach you isomorphic JavaScript on devbeat How easy it is to assemble and tell you how to write an isomorphic program.
Please continue to follow me @spikebrehm and our technical team @airbnbnerds. Focus on the evolution of the AIRBNB Web App.
The future of Javascript:web application of "turn" shape