【转】同形的JavaScript:Web应用的未来
原文转自:http://blog.jobbole.com/51786/
在Airbnb,这几年我们已经学习了很多了关于构建富应用的经验,从2011年通过做我们的网站手机版,我们开始研究single-page应用,尤其是在我们正式推出Wish Lists和我们重新设计的search page以后。大部分都是大型JavaScript项目,这意味着大部分代码要在浏览器中运行这也是为去适应一个更现代的交互体验。
在现在,这种方法是很普遍的,现在的一些知名的框架(Backbone.js, Ember.js, Angular.js)很容易让开发者构建一些富应用程序。我们已经发现,无论怎么样,这些应用都会有一些限制,要想知道为什么,我们先来看一下Web apps 的历史。
JavaScript Group Up
自Web起初, 浏览器是这样工作的:浏览器将会请求一个特定的页面(例如:请求http://www.geocities.com)使服务器产生响应并生成HTML页面然后通过Internet发送回来, 这种工作方式在当时已经是很好的了是因为那时的浏览器不是很强大,HTML页面大多数都是独立且静态的文件。JavaScript 的来临可以使Web页面变得动态,不仅仅只是实现图片幻灯片和日期控件。在个人电脑高速发展的今天, 一些牛B的程序员已经摆脱了Web的限制,浏览器也在不断的进化。现在,Web 已经是一个成熟并具有强大功能的应用平台,JS的执行速度变快以及HTML5的标准使得开发者能够创建富应用,而这些应用之前只可能是在本地平台构建!
The Single-Page App
很快,利用这些新功能开发人员开始使用JavaScript构建整个网站,这些经典的单页面应用像 Gmail 能快速的响应用户行为, 而不是只为了渲染页面就往返服务器。
一些成熟框架例如: Backbone.js, Ember.js, Angular.js 通常也会被当做“MVC or MVVM模式”的框架而讨论, 这个经典的MVC模式看起来像这样:
大部分的逻辑都在客户端,(视图,模版,控制,数据处理,国际化等)为数据提供处理接口, 服务器端可以使用任意一种语言编写, 如 Ruby、Python、Java,它最多的也就是提供一个空的HTML页面, 一旦JavaScript文件被下载,它们将被执行以及在客户端初始化, 从中获取数据并直接渲染HTML页面。
这对于用户体验来说是很好的, 因为一旦应用初始化并加载,它是可以支持页面与页面之间快速切换而不是通过刷新页面, 在往好了说,它甚至可以实现离线操作功能。
这对开发人员也是很好, 因为它可以明确的为 “client”/”service”分出界线, 从而促进整个开发流程, 可以有效的防止两种语言这间的实现逻辑重复, 因为前后端通常是使用不同语言开发的。
Trouble in Paradise
实际上, 无论如何它都是有缺陷的, 不过我们可以通过一些案例来正确的避免。
SEO
如果一个应用只运行在客户端的话是不能通过HTML进行”爬虫”的,所以它默认是不可被SEO的(搜索引擎优化), 正常我们的爬虫是通过向服务器创建个请求然后解析结果;但如果服务器返回个空页面, 那就没有意义了. 但也不是没有解决的办法。
Performance
同理, 如果服务器不能直接渲染整个HTML页面,而是通过JavaScript去做这些事儿,用户将会在加载完整个页面之前看到几秒钟的空页面或者一直加载控件. 有很多研究表明用户对访问慢站点反应很强烈。Amazon claims亚马逊声称 “每提升100ms的页面加载速度将会提升1%的收入” Twtter 40个工程师花费的1年时间去重构,他们的站点(在服务器端渲染页面,而不是在客户端) 声称提高了5倍的加载时间。
Maintainability
在理想情况下我们在要创建一个分层明确低耦合的应用程序, 来避免少量的应用逻辑代码在前后端重复(通常是前后端使用不同的语言开发). 常见的例子比如 日期/货币格式化,表单验证, 流程逻辑. 可维护性一直都是设计程序必要的也是困难的,特别是对于复杂应用来说。
一些开发人员包括我们自己也被这些问题困扰着 — 通常只有真正在单页面应用下功夫, 才能清楚它的缺陷在哪里。
A hybrid Approach
到了最后,我们想要一个综合的解决方案: 我们想从服务器获取整个HTML(高必性能, 可SEO) 但我们还想使客户端代码运行快速且具有灵活性。
为此, 我们已经在Airbnb尝试使用”Isomorphic JavaScript”进行构建. 这是一个可以在客户端和服务端都运行的JavaScript应用. 一个“isomorphic”应用看起来是这样的, 这里称为“Client-server MVC”。
在这个世界里, 你的应用和视图层逻辑都可以在前后端运行, 这样就依次解决上述所有问题 — 性能优化, 好的维护性, 可以被SEO,更有状态的Web应用。
通过Node.js,一个快速的, 稳定的运行在服务器端的JavaScript, 现在我们可以梦想成真. 通过创建适当的抽象, 我们就可以在服务器端和客户端运行我们的逻辑代码 — 这就是“isomorphic JavaScript“的定义。
Isomorphic JavaScript in the Wild
这不是一个新的想法, 早在2011年 Nodejitsu 已经对 isomorphic JavaScript 有了一个很好的描述- 但现在它才被采用. 现如今已经有很多的 isomorphic JavaScript的框架了。
Mojito 是第一个开源的 isomorphic JavaScript框架, 你可以通过任意途径得到它. 它完全用Node.js写的框架. 但自从他们在2012年4月开源以来在JavaScript社区没有广泛的流行起来主要原因是它依赖于 YUI 和 雅虎特殊的模式。
Meteor 可能是现今最好的 isomorphic 项目. Meteor 原生的支持实时应用, 这个团队正在围绕这包管理器和开发工具来构建一个完整的体系。
像Mojito,它是一个大型的, 原生的Node.js框架, 它在JavaScript社区里也是工作很好的.,而且1.0 release版本也将要发布了。 Meteor做为一个项目一直被密切关注着 — 它有一个全明星团队, 并在安德森基金会获得 $11.2M 资金 – 从未听说过有公司会对一个开源产品这么关注。
Asana, 是一个任务管理应用 有意思的是它是由 Fackbook 创始人之一的 Dustin Moskovitz创建的. Moskovitz’ 地位乃是世界最年轻的亿万富翁, Asana花费了很多年在开发他们的闭源项目Luna, 这是isomorphic JavaScript最著名的例子之一。Luna, 在没有Node.js以前它是构建在v8cgi上, 它允许为每一个单独用户会话copy一个完整的应用程序到服务器端运行. 它为每个用户创建独立的进程, 运行在客户端上的也是服务器端的代码, 开启对整个类的高级优化, 比如 离线支持 即时更新。
在早些时候我们推出了一个 同构库它叫被叫做Rendr库, 它允许你使用 Backbone.js + Handlebars.js 构建单页面应用, 在服务器端也能全部被渲染。Rendr是我们在为了使 Airbnb mobile web 有更快的响应速度而创建的产品。对于用户来说高可用的响应速度是尤为重要的. Rendr力求成为一个库而不是一个框架, 所以它相比Mojito或Metetor来说, 它解决的问题相对来说是少的,但它很容易修改和扩展。
Abstraction, Abstraction, Abstraction
这往往对一些大的项目来说是很困难的, 客户端与服务器端是完全不同的运行环境,所以我们要创建一系列抽象把解藕的应用逻辑从底层抽出来, 所以我们可以像开发人员暴露一些单独的API。
Routing
我们想从URI模式路由处理器中获取单独的一组路由,我们的路由处理需要访问HTTP头, cookies, URI信息, 和特殊的重定向(不是通过window.location或者Node.js 的req res)。
Fetching and persisting data
我们想要描述一个资源就需要渲染一个指定页面,或者通过抓取组件的形式。 这个资源描述符可以是一个简单的URI去指向一个JSON数据, 或指向更大的应用程序, 通过模型、集合、指定的模型类或者是一个主键KEY对封装资源是很有用的 , 通常这些在某种程度上都被解析成一个URI。
View rendering
我们是否选择直接操作DOM, 还是使用HTML模板,或者操作一个封装DOM的抽像UI组件,来生成一个HTML标记,我们也能在前后端够渲染任何页面, 这要看你的应用是否需要了。
Building and packaging
到现在为止也只是走了一半的路程, 工具像 Grunt 和 Browserify 是在启动和运行应用程序工作流程中不可缺少的.。下面是构建的几个步骤: 编译模板 ,包括一些客户端依赖、 应用混淆、 压缩等。这个简单的例子是合并所有应用代码、视图和模板捆绑在一起, 但对于大型应用来说会有几百KB的下载。一个最好的办法是去创建一个动态捆绑和采用延迟加载, 无论怎么样它都是很复杂的。 静态统计工具像Esprima可以使一些有上进心的程序人员去尝试进行再一步的优化以及使用 metaprogramming (元程序)来减少代码.
Composing Together Small Modules
Isomorphic 框架要想走入市场意味着你要立刻解决所有的问题,但这样会导致一个大的笨重的框架, 会很难被推广和很难融入现有应用程序。现在有很多的开发人员已经解决这个问题,我们将会构建一个轻量级的-可复用的-可继承的 isomorphic 程序。
事实证明大多数的JavaScript模块不用怎么修改就可以被同构, 例如:现流行的库像 Underscore, Backbone.js, Handlebars.js, 重要的是 现在甚至jQuery也可以在服务器端使用。
为了证明这一点,我已经构建一个简单的应用 “isomorphic-tutorial”你可以去Github上去下载。通过将几个模块结合在一起, 其中每个模块都是可同构的,它 仅仅使用几百行代码就很容易创建一个简单的同构应用,它是使用Diretor为服务器端与浏览器提供路由,Superagent提供HTTP请求和使用Handlebars.js做页面模板,这些所有有构建都是基于Express.js框架,当然作为一个应用组建起来是很复杂的,必须得引入更多层次的抽象,但是我们希望会有更多的开发人员进行更多的尝试,它们将会有一个新的库和新的标准诞生。
The View From Here
更多的机构已经在他们的产品中使用Node.js了,这也就不可避免会有更多的应用开始在前后端共享代码。 最重要的是要记住 “同构JavaScript”是一个范围 — 它开始只能共享模板,之后管理整个项目的视图层,再到大多数应用的业务逻辑层。事实上JavaScript代码共享在前后端是要取决于你的程序设计,以及它的独特约束。
Nicholas C. Zakas 有一个很好的文章“如何将UI层从客户端拿到服务器端” 提高性能与可维护性。一个应用不需要用Node.js去代替整个后端,这好比 “在倒洗澡水时把小孩也给倒掉了”,反而要想去创建一个好的API和一个RESTful resources(这里推荐阮一峰的一篇文章来简单介绍什么是 RESTful resource) 的程序,传统后台是可以和Node.js结合去搭建的。
At Airbnb网站上,我们已经开始使用Node.js一些基础工具库 Grunt 和 Browerify 重构我们的客户端。我们核心的Rails应用可能永远都不会使用Node.js做替换,但能过这些工具我们很容易使JavaScript与template共享同一环境。
如果你要这里是第一次听说,在过几年 一些高级的WEB应用将运行JavaScript在服务器端。
Learn More
如果这个idea使你很兴奋,那么你可以来我们的 Isomorphic JavaScript 工作室来看看,在旧金山 11月12日 星期三 或者 11月21日 星期四,我将在DevBeat上教你们 isomorphic JavaScript 如何组装以及会告诉你们写一个同构程序是多少容易的一件事 儿。
也请继续跟着我@spikebrehm和我们的技术团队@AirbnbNerds.一起关注 Airbnb web 应用的演变。
【转】同形的JavaScript:Web应用的未来的更多相关文章
- [Javascript] Web APIs: Persisting browser data with window.localStorage
Local Storage is a native JavaScript Web API that makes it easy to store and persist data (as key-va ...
- Dynamics CRM2016 升级老版本报“JavaScript Web 资源包含对 Microsoft Dynamics CRM 4.0 (2007) Web 服务终结点的引用”问题的解决办法
今天在新的服务器上部署了CRM2016 on-premises,并将CRM2015的数据库拷贝过来准备附加后升级,但在升级过程中遇到了如下错误,向导检测到了我的JavaScript Web 资源中包含 ...
- 推荐10款优秀的JavaScript Web UI库 框架和套件
在进行Web开发时,并非所有的库都适合你的项目,但真正开发的时候,你任然需要依赖一款UI框架.特别在你时间紧迫的时候,它是你忠实的朋友. 他们都是些广泛使用包含不同语言实现的WEB UI框架.今天我就 ...
- JavaScript Web 应用最佳实践分析
[编者按]本文作者为 Mathias Schäfer,旨在回顾在客户端大量使用JavaScript 的最佳 Web应用实践.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 对笔者来说,Jav ...
- 试读《基于MVC的JavaScript Web富应用开发》— 不一样的JavaScript
前言 <基于MVC的JavaScript Web富应用开发>是ItEye在7月份发起试读的书.下载了试读的章节,发现只有全本的开始到第二章,第一章很简洁明了地讲述了JavaScript的历 ...
- 【WIP】客户端JavaScript Web Object
创建: 2017/10/11 更新: 2017/10/14 标题加上[WIP],增加[TODO] 更新: 2018/01/22 更改标题 [客户端JavaScript Web Object, UR ...
- Dynamics CRM2016 升级老版本号报“JavaScript Web 资源包括对 Microsoft Dynamics CRM 4.0 (2007) Web 服务终结点的引用”问题的解决的方法
今天在新的server上部署了CRM2016 on-premises,并将CRM2015的数据库拷贝过来准备附加后升级,但在升级过程中遇到了例如以下错误.向导检測到了我的JavaScript Web ...
- 谷歌宣称web组件才是web开发的未来
谷歌宣称web组件才是web开发的未来 虽然今年的谷歌I/O大会没有出现像去年谷歌眼镜发布时直播疯狂跳伞这样的活动,但是上周仍然有不少产品推出.谷歌宣布对谷歌地图.搜索.安卓,以及其他 很多产品做出更 ...
- Web 开发的未来:React、Falcor 和 ES6
Web 开发的未来:React.Falcor 和 ES6 Widen是一家数字资产管理解决方案提供商.目前,其技术栈还非常传统,包括服务器端的Java.浏览器端的AngularJS.提供REST AP ...
随机推荐
- 51nod 1613翻硬币
题目链接:51nod 1613 翻硬币 知乎上的理论解法http://www.zhihu.com/question/26570175/answer/33312310 本题精髓在于奇偶性讨论. 若 n ...
- 数据库索引<二> 补充前篇
你要准备的软件有: 最新版 Rsync for windows 服务端:cwRsync_Server_2.1.5_Installer.zip 客户端:cwRsync_2.1.5_Installer.z ...
- 用Google Analytics跟踪JavaScript Errors (译)
通过custom events来实施 // Track basic JavaScript errors window.addEventListener('error', function(e) { _ ...
- js——常见的小方法
1.随机得到是六位数,可以当做“密码”来使用: Math.random().toString().substr(2, 6):
- es根据磁盘使用情况来决定是否分配shard
注意两个地方说法有出入,待实测! es可以根据磁盘使用情况来决定是否继续分配shard.默认设置是开启的,也可以通过api关闭:cluster.routing.allocation.disk.thre ...
- Codeigniter 集成sphinx搜索 这里采用的是coreseek中文搜索引擎,具体安装请参考官方网站
先上效果图 加入sphinx类库(/application/libraries/sphinx_client.php) 0001 <?php 0002 0003 // 0004 // $Id: s ...
- iOS各种动画效果
ios各种动画效果 最普通动画: //开始动画 [UIView beginAnimations:nil context:nil]; //设定动画持续时间 [UIView setAnimationDu ...
- 7 libjpeg使用
一.交叉编译libjepg编译 tar xzf libjpeg-turbo-1.2.1.tar.gz ./configure –help ./configure --prefix=/work/proj ...
- Mongoose全面理解
一.创建schemas 创建schemas的方式: 1 var userSchema = new mongoose.Schema({ 2 name: String, 3 email: String, ...
- win10 ctrl + 空格 热键取消
关键:添加English,并上移到第一,即开机默认即可.Win8+不用修改注册表的,只有win7里才可能需要修改注册表. http://superuser.com/questions/327479/c ...