Turbolinks 是个好东西,但是目前只能搭配 Rails 框架使用。在这里分析一下它的后端处理逻辑,其他框架的开发者有兴趣可以实现自己的后端模块,将 Turbolinks 移植到自己的框架。
http://chloerei.com/2013/06/30/turbolinks-backend/
Turbolinks 并不糟糕
http://chloerei.com/2013/06/30/turbolinks-is-not-bad/
Turbolinks 向导
更新 Note 地址:http://saito.im/note/Turbolinks-sucks/
唱个反调:Turbolinks 并不好。
Turbolinks 的出现是为了解决什么问题?
解决的同时送给你了什么新的礼物?
潜在的内存泄露 ( Chrome 的 DOM 与 JS Object 之间很容易泄露内存,变相提高了程序员素质。
额外的适配原有后端逻辑的代码。( 例如 适配 redirect_to 301, 在 turbolinks 代码内部。cache 以及 cookie
前端代码的 ready 事件改写。( page:load 可以用 jquery.turbolinks 继续监听 $.ready
前端监听事件的复杂化,本来就一个 DOM ready, 现在变成了 5 个事件。你可以小心翼翼的来处理这 5 个事件,来保证程序的正常运行。
$(document).on
以及老版本 jQuery 的 $(".class").live
要特别小心。尽量使用 BackBone 之类的框架,不要面向 DOM 编程。因为事件绑定之类的会随着 View 对象的消失而被清理,不然需要处理很多 on
, off
, 以及潜在的多次事件绑定。
怎么样的 Turbolinks 才是对的?
Turbolinks 站在 Server Render 跟 Client Render 的十字路口,决定适配这个世界。我不认为这是未来的开发方向..
Turbolinks 里面有用的功能,不用几行就实现了,而多余的很多行以及后端的代码,都是为了适配写的,解决了一些纯前端框架根本不会遇到的问题。而且顺利的提高了使用 Turbolinks 的学习曲线。
我个人很喜欢 yehuda 的 Ember.js 的宣传语,Ambitious Web Applications. 我觉得未来的体验需要有野心的前端框架来解决。而不是 Turbolinks.
推荐 Web Languages and VMs: Fast Code is Always in Fashion. (V8, Dart) - Google I/O 2013 可以了解很多 V8 内部,以及 Dart 已经何等出色了..
我同意对方辩友的观点。Turbolinks 只是一个加速器,不能取代客户端框架。如果一个页面页内逻辑特别复杂,自然要用上客户端框架。但是对于已有的 Rails 应用,引入 Turbolniks 比用客户端重写要容易多了。
Turbolinks 的出现是为了给 Rails Asset Pipeline 擦屁股,Asset Pipeline 解决了前端相关的大部分问题(减少 http 请求,压缩/混淆,缓存失效),但是引人的问题是增加了 js 和 css 的渲染时间(Assets Pipline 的最佳实践是所有静态文件打一个包)。Tubolinks 的描述是Turbolinks makes following links in your web application faster (use with Rails Asset Pipeline)
Turbolinks 把客户端 JS 改造成像 Ruby 这种常驻进程方式执行,解决了 Asset Pipeline 带来的增加了渲染时间的问题。同时带来的新问题是内存泄漏、学习曲线增高、隐藏太多复杂性、事件绑定方式变化。Tubolinks 282 行代码却开了 245 个 issue ,这些 issue 大部分是解决 turbolinks 和其他插件适配的。我觉得如果不是 DHH 发起的,这项目早就挂了..
#10 楼 @hooopo 我正想接着吐槽 Sprockets.
Sprockets 的出现是为了解决什么问题?
前端开发到底需要的是什么?
难道真的需要一个打包工具?据我所知,在荒蛮的开发大地上,我们的前端朋友们用 Ant 也打了不少年的包了,这东西真不稀奇,打包不是他们的痛点。
前端开发的痛点是组织代码,怎么写都不爽才是问题。因为没有标准的模块化。所以大家折腾各种 CMD/AMD 的标准。这下写的爽了.. 也没 Sprockets 什么事了。因为 module 天然有 require 的属性,所以必然是通过 module 来判断哪些文件被引用了,然后一起打包。Sprockets 帮不上什么忙。
而 SASS 则更是没 Sprockets 什么事,因为 SASS 天然的支持 partials, 默认就是这样 build 在一起的。
所以 Sprockets 在现在的开发模式下,有用的功能几乎为 0 . ( 不过在当时这些 模块定义 AMD/CMD 还没有被大家广泛接受的时候是有用的,不过仅限于 Javascript.
Sprockets 希望你将 Javascript lib 打包成 Gem 来做管理,本来就是一个 Anti Pattern. 因为这与开发阶段完全脱离,非常依赖第三方人员升级 Gem. lib 与 作者结合的发布方式才是对的。例如 bower ( 方向对了,但是实现的不好。
#17 楼 @Rei Sprockets 在 2.6.0 的时候就支持 bower 了,不过副作用很大。这个是跟我之前说的 bower 实现的不好有关。
很多的 Javascript 库都加入了 bower 的支持,但是 component.json/bower.json 写的都不对,要不然不支持 semver, 要不然就是没写 ignore 的文件列表 要不然就是没有 main. 而 bower 每次都要 clone 整个 git 的 repo 下来然后 checkout 到某一个 tag 也是实现上的大问题。导致 components/ 文件夹里面内容很多,间接就导致了 Sprockets build 变的很慢。
Sprockets 2.6.0 开始支持的 bower 也依赖于 bower.json 的 main 这个配置项,如果没写就会导致 http://ruby-china.org/topics/12020 第三个管太多的问题。
bower 如果以后可以跟 github 的新的 release workflow 结合的话会非常好。这个还是要整个社区推动才行。
#20 楼 @Saito 我目前没有 gem 包或者 star 人数少的就直接下载放到 vendor 了。感觉很多包管理器都可以迁到 github release 了。马上有人提了 https://github.com/bower/bower/issues/584
其实,我感觉对于 rails 的使用,没有必要紧跟最新的版本,作为一种开源项,完全可以按照自己的喜好或需求进行修改,甚至修改里面的原代码,所以 Turbolinks 的好与坏,因人而异吧
#25 楼 @fresh_fish 我有几个站都在跑着,木问题啊 我的跟该页面/view 有关的 ready 代码都是写在 view 里
<script type="text/javascript">
$(document).ready(function(){
console.log('xxx');
});
</script>
#32 楼 @Rei 仔细读了您的日志,感谢你写的这么全面细致。让后来者减少了很多踩坑的机会。但似乎在文章里面你没有提到 coffee script 如何专为 turbolinks 绑定事件的写法。下面有一个我在书里看到的例子,可以更新在你的文章里面么?
$(document).on "ready page:change", ->
$('.store .entry > img').click ->
$(this).parent().find(':submit').click()
书中的原话是
The function with two events: ready and page:change. ready is the event that fires if people navigate to your page from outside of your site, and page:change is the event that Turbolinks4 fires if people navigate to your page from within your site. Associating the script to both makes sure that you are covered either way.
绑定 page:change 应该能解决不少上面回复中提到的所谓坑。
#7 楼 @Saito 没搞懂 Turbolinks 的学习瓶颈在哪里?当黑盒使用的话,似乎没有学习成本。比 assets precompile 的坑少多了。不需要的话,直接注释掉就了事。
至于有没有必要用,还是得看应用类型的。最典型的如 Github 上浏览代码,此时使用 turbolinks 获取的收益是很大的。如果应用本身就是 js 重度应用,那当然也不需要这玩意。而类似 ruby-china 这样的应用,打不打开区别就不太大了。
未来的发展方向是事在人为的。而且如 DHH 所说,宣称会作为一种趋势杀死 server、html 的工具曾经有很多,Java applet、Flash、Flex 等等,但近二十年下来,Web 的主体依然是 HTML。
Turbolinks 向导
http://blog.chloerei.com/articles/48-turbolinks-guide
这是总集篇,包含了之前的所有实践总结,估计我近期不需要再写 Turbolinks 了。
链接已经变化了,从 google 进来的,比如第三篇链接应该是 http://chloerei.com/2013/07/14/turbolinks-guide/