Rails Turbolinks 后端逻辑分析 (更新总集篇)

Rei · 发布于 2013年07月03日 · 最后由 rei 回复于 2015年10月14日 · 9376 次阅读
1
本帖已被设为精华帖!

Turbolinks 是个好东西,但是目前只能搭配 Rails 框架使用。在这里分析一下它的后端处理逻辑,其他框架的开发者有兴趣可以实现自己的后端模块,将 Turbolinks 移植到自己的框架。

http://chloerei.com/2013/06/30/turbolinks-backend/


Turbolinks 并不糟糕

http://chloerei.com/2013/06/30/turbolinks-is-not-bad/


Turbolinks 向导

http://chloerei.com/2013/07/14/turbolinks-guide/

共收到 44 条回复
4584

先收藏,准备学习,谢谢Rei

243

推荐 Web Languages and VMs: Fast Code is Always in Fashion. (V8, Dart) - Google I/O 2013 可以了解很多 V8 内部, 以及 Dart 已经何等出色了..

1

我同意对方辩友的观点。Turbolinks 只是一个加速器,不能取代客户端框架。如果一个页面页内逻辑特别复杂,自然要用上客户端框架。但是对于已有的 Rails 应用,引入 Turbolniks 比用客户端重写要容易多了。

8

#7楼 @Saito total agree.

  • 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发起的,这项目早就挂了..

96

分久必合,合久必分啊

1

#10楼 @hooopo 内存泄漏、学习曲线增高、隐藏太多复杂性、事件绑定,这些是单页应用都有的。框架声称能处理,是因为开发的时候需要按照框架的规范来写,这跟用 Turbolinks 的情况一样,不能用以前假设每个页面只执行一次的思路来写 js。

8

#12楼 @Rei 这个要结合Rails默认开启Turbolinks来理解.. 并不是每个项目都是单页应用。

243

#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 ( 方向对了, 但是实现的不好.

1

#13楼 @hooopo Rails 喜欢给开发者“吃我XX啦”,然后再提供方法删掉,传统来了,以前 coffee 也是这样,结果写了半年 js 发现 coffee 还真好。要删掉 Turbolinks 只要删两行。

8

#14楼 @Saito Sprockets有点用的,话说,我第一份工作就是写过发布之前打包+压缩静态文件的脚本。Rails框架提供了这个功能,一夜之间Rails项目都是压缩合并的了,想起以前一些搞PHP的同事为怎么打包JS和CSS还争论了半天觉得好笑(最后项目css和js是否打包就不清楚了..)。

你的并不好都是针对专业前端框架来说的,但Rails是后端方案或者是一站式方案,也不能苛求太多。

1

#14楼 @Saito js 可以用 git submodule 放到 vendor/assets 下面,不过这有点像以前的 plugin 管理,最终会废弃。如果 js 有统一的包管理器,以后也能为 Sprockets 所用。

243

#16楼 @hooopo 我们现在使用的还是 Sprockets 做前端的开发, 只不过越来越觉得没用. 现在它的处境很尴尬..

我在 Sprockets 上做了很多扩展, 他现在对于我来说有用的是 preprocess Coffee SASS 跟 压缩. 其他都没用. 编译是 sass 跟 node coffee 做的, 压缩是 uglify 跟 yui 做的. 它提供了很方便的接口.. 不然我要自己去适配这些东西. 想自己写, 又觉得烦... 现在是这种状态.

8

#18楼 @Saito sass和coffee也算是解决了一些问题,然后带来一些新问题的东西..

243

#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 结合的话会非常好. 这个还是要整个社区推动才行.

1

#20楼 @Saito 我目前没有 gem 包或者 star 人数少的就直接下载放到 vendor 了。感觉很多包管理器都可以迁到 github release 了。马上有人提了 https://github.com/bower/bower/issues/584

243

#21楼 @Rei 嗯, 新的回复里面提出类似 npm publish 之类的, 这种最好了, release workflow 也可以是一个备选.

96

其实,我感觉对于rails的使用,没有必要紧跟最新的版本,作为一种开源项,完全可以按照自己的喜好或需求进行修改,甚至修改里面的原代码,所以Turbolinks的好与坏,因人而异吧

15

我用 rails 3.2.13 用了turbolinks 没加入 jquery.turbolinks 可jquery的 ready 是能工作的。

395

#24楼 @huobazi 你可以试试通过 turbolink 加载的页面或者 dom, jQuery.ready 绑定的事件是无效的 哦 我说的是 Rails 4,Rails 3没验证过

96

反正我用Python,不用关心这些问题

2408

#14楼 @Saito

前端开发的痛点是组织代码, 怎么写都不爽才是问题.

说的好!

15

#25楼 @fresh_fish 我有几个站都在跑着,木问题啊 我的跟该页面/view有关的ready代码都是写在view里


<script type="text/javascript">
$(document).ready(function(){
  console.log('xxx');
});
</script>
1

#28楼 @huobazi 点到别的页面,ready 里面的代码就不会执行了。

15

#29楼 @Rei 别的页面为什么要执行不属于自己页面该执行的 ready 代码。

1

#31楼 @huobazi 意思是 ready 在 Turbolinks.visit 的时候是不触发的,如果另一个页面的逻辑是写在 ready 里面,那么不会执行。如果能执行,可能 Turbolinks 没起作用。能把网站发我看看吗?

15

#32楼 @Rei 发你邮箱了

1249

我是不会用什么 Turbolinks的。不解释,简直就是鸡肋。

2880

#26楼 @bhuztez 如果还没遇到浏览器成为性能瓶颈的情况, 就没必要关心这个...

96

#35楼 @luikore 越来越不容易成为瓶颈了...

449

#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 应该能解决不少上面回复中提到的所谓坑。

3253

#7楼 @Saito 同样很喜欢 Ember JS 的鹿过。

3253

#37楼 @Victor 书是最新版的 Agile Web development with Ruby on Rails 4

6224

#7楼 @Saito 没搞懂Turbolinks的学习瓶颈在哪里?当黑盒使用的话,似乎没有学习成本。比assets precompile的坑少多了。不需要的话,直接注释掉就了事。

至于有没有必要用,还是得看应用类型的。最典型的如Github上浏览代码,此时使用turbolinks获取的收益是很大的。如果应用本身就是js重度应用,那当然也不需要这玩意。而类似ruby-china这样的应用,打不打开区别就不太大了。

未来的发展方向是事在人为的。而且如DHH所说,宣称会作为一种趋势杀死server、html的工具曾经有很多,Java applet、Flash、Flex等等,但近二十年下来,Web的主体依然是HTML。

1

Turbolinks 向导

http://blog.chloerei.com/articles/48-turbolinks-guide

这是总集篇,包含了之前的所有实践总结,估计我近期不需要再写 Turbolinks 了。

11314

链接已经变化了,从google进来的,比如第三篇链接应该是 http://chloerei.com/2013/07/14/turbolinks-guide/

1

#43楼 @zoker 好,都修复了。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册