Upgrade to Pro — share decks privately, control downloads, hide ads and more …

基于 Turbolinks 的跨平台开发

5aec84cd0b5479a0d1d89b6ffa2a9a20?s=47 Rei
September 25, 2016
550

基于 Turbolinks 的跨平台开发

RubyConf China 2016 演讲

5aec84cd0b5479a0d1d89b6ffa2a9a20?s=128

Rei

September 25, 2016
Tweet

Transcript

  1. 基于 TURBOLINKS 的跨 平台开发 黄增光(@chloerei) <chloerei@gmail.com>

  2. “生生不息,繁荣昌盛。”(Live long and prosper)

  3. 关于我 Ruby China 社区创始人之一(No.1 会员) 大疆 Ruby on Rails 开发

    Alipay gem 维护者
  4. Rails is Omakase

  5. None
  6. None
  7. Rails has Two Default Stacks Omakase Stack Prime stack http://words.steveklabnik.com/rails-has-two-default-stacks

  8. Prime Stack

  9. 前后端分离是未来?

  10. 前后端带来新问题 首屏加载速度 SEO 开发复杂度

  11. None
  12. 首屏加载速度 Ruby China (Turbolinks) Discourse (Ember.js)

  13. 延迟 用户感知 延迟 用户感知 0–100 ms 即时 100–300 ms 稍微延迟

    300–1000 ms 等待处理 1,000+ ms 注意力分散 10,000+ ms 终止任务 https://hpbn.co/primer-on-web-performance/#speed- performance-and-human-perception
  14. 加快首屏加载的方法 首屏插入数据,避免 API 请求。 使用服务端渲染。✨

  15. SEO < s e c t i o n i

    d = ' m a i n ' > < / s e c t i o n > < s c r i p t > A p p . i n i t ( . . . ) ; < / s c r i p t >
  16. SEO 解决办法 服务端输出专供搜索引擎的内容。 使用服务端渲染。✨

  17. 今年前端流行:Isomorphic(同构)

  18. — wikipedia 同构是在数学对象之间定义的一类映射, 它能揭示出在这些对象的属性或者操作 之间存在的关系。若两个数学结构之间 存在同构映射,那么这两个结构叫做是 同构的。一般来说,如果忽略掉同构的 对象的属性或操作的具体定义,单从结 构上讲,同构的对象是完全等价的。

  19. None
  20. — http://isomorphic.net/ 同构 JavaScript 应用是可以同时跑在客 户端和服务端的 JavaScript 应用。前端 和后端共享同样的代码。

  21. 说好的前后端分离呢?

  22. “前后端分离”有歧义 服务端和客户端分离 业务层和展示层分离

  23. 开发复杂度

  24. #JavaScriptEE

  25. 系统开发的复杂度多半是引入了系统组件之间的界限

  26. The Rails Doctrine — DHH 我们要追求的系统:包含所有功能,容 易发布,简单理解的单一整合系统。 https://github.com/ruby-china/the-rails-doctrine

  27. Turbolinks 是 Rails 最被误解的组件。

  28. None
  29. Turbolinks 是 Web 换页加速器

  30. 有多快?

  31. 0:00 / 0:05

  32. Ruby China (Turbolinks) Ruby China (No Turbolinks)

  33. Turbolinks 做了什么 捕获 < a > 点击事件。 用 xhr 请求服务端内容。

    替换当前页面的 < b o d y > ,合并 < h e a d > 。 处理浏览器历史记录等等……
  34. Turbolinks 让网站成为单页应用(SPA)

  35. 安装(Rails 默认) # = r e q u i r

    e t u r b o l i n k s 已经在使用 Turbolinks 了!
  36. 等等,我的 JavaScript 出问题了!

  37. Turbolinks 两大“坑” Turbolinks Event Turbolinks Caching

  38. Turbolinks Event 现象:我的代码不执行了! 原因:Turbolinks 开启后,D O M C o n

    t e n t L o a d e d 事件 只在首屏触发。
  39. Turbolinks Event 解决:使用 t u r b o l i

    n k s : * Event $ ( d o c u m e n t ) . o n ' t u r b o l i n k s : l o a d ' , - > # c o d e s h e r e . . . https://github.com/turbolinks/turbolinks#full-list-of-events
  40. 将事件委托到 d o c u m e n t #

    每次换页遍历绑定 # m y - e l e m e n t $ ( d o c u m e n t ) . o n ' t u r b o l i n k s : l o a d ' - > $ ( ' # m y - e l e m e n t ' ) . o n ' c l i c k ' , - > # c o d e s h e r e . . . # 只绑定一次 $ ( d o c u m e n t ) . o n ' c l i c k ' , ' # m y - e l e m e n t ' , - > # c o d e s h e r e . . .
  41. 使用 UJS 和 SJR https://signalvnoise.com/posts/3697-server-generated- javascript-responses

  42. Turbolinks Caching 现象:我的代码被重复执行了! 原因:Turbolinks 内部维护了缓存,点击浏览器前进、 后退的时候会读取缓存,此时 JavaScript 可能对同一处 元素重复处理。

  43. Turbolinks Caching 解决:让 JavaScript 操作幂等。 $ ( d o c

    u m e n t ) . o n ' t u r b o l i n k s : l o a d ' , - > i f ! $ ( ' # e l e m e n t ' ) . a t t r ( ' d a t a - i s - d o n e ' ) # d o s o m e t h i n g $ ( ' # e l e m e n t ' ) . a t t r ( ' d a t a - i s - d o n e ' , t r u e )
  44. 还有,初始化元素的时机不一定在 Turbolinks 事件内,例 如 Ajax。

  45. Custom Elements(实验性 Web 标准) # 定义 e l e m

    e n t c l a s s M y E l e m e n t e x t e n d s H T M L E l e m e n t c o n s t r u c t o r : - > # e l e m e n t 创建 c o n n e c t e d C a l l b a c k : - > # e l e m e n t 插入 D O M d i s c o n n e c t e d C a l l b a c k : - > # e l e m e n t 脱离 D O M w i n d o w . c u s t o m E l e m e n t s . d e f i n e ( ' m y - e l e m e n t ' , M y E l e m e n t ) < m y - e l e m e n t > < / m y - e l e m e n t >
  46. Trix:基于 Custom Element 的富文本编辑器 https://github.com/basecamp/trix < f o r m

    … > < i n p u t i d = " x " t y p e = " h i d d e n " n a m e = " c o n t e n t " > < t r i x - e d i t o r i n p u t = " x " > < / t r i x - e d i t o r > < / f o r m >
  47. README https://github.com/turbolinks/turbolinks

  48. 依然需要写 JavaScript。

  49. 复杂的组件可以使用前端框架,但没必要整站都用。

  50. 它要求你从全局的角度看待问题。

  51. Ruby China 一直在使用 Turbolinks。

  52. 移动应用

  53. Facebook HTML5 Mobile App

  54. 失败原因 移动设备性能不足 无法调用本地接口

  55. 时代在进步 移动设备性能更好了 混合移动应用: Native 导航, Web 内容

  56. Basecamp 3

  57. Turbolinks Android & Turbolinks iOS

  58. Ruby China 移动应用 已上架 App Store、Play Store。

  59. 0:00 / 0:41

  60. None
  61. None
  62. TurbolinksView 移动端原生组件。 多个 Activity 共享一个 WebView。 提供 WebView 和 Native

    交互的接口。
  63. 安装 r e p o s i t o r

    i e s { j c e n t e r ( ) } d e p e n d e n c i e s { c o m p i l e ' c o m . b a s e c a m p : t u r b o l i n k s : 1 . 0 . 3 ' }
  64. Layout < L i n e a r L a

    y o u t a n d r o i d : l a y o u t _ w i d t h = " m a t c h _ p a r e n t " a n d r o i d : l a y o u t _ h e i g h t = " m a t c h _ p a r e n t " a n d r o i d : o r i e n t a t i o n = " v e r t i c a l " > < c o m . b a s e c a m p . t u r b o l i n k s . T u r b o l i n k s V i e w a n d r o i d : i d = " @ + i d / t u r b o l i n k s _ v i e w " a n d r o i d : l a y o u t _ w i d t h = " m a t c h _ p a r e n t " a n d r o i d : l a y o u t _ h e i g h t = " m a t c h _ p a r e n t " / > < / L i n e a r L a y o u t >
  65. 初始化 TurbolinksSession @ O v e r r i d

    e p r o t e c t e d v o i d o n C r e a t e ( B u n d l e s a v e d I n s t a n c e S t a t e ) { t u r b o l i n k s V i e w = ( T u r b o l i n k s V i e w ) f i n d V i e w B y I d ( R . i d . t u r b o l i n k s _ v i e w ) ; T u r b o l i n k s S e s s i o n . g e t D e f a u l t ( t h i s ) . a c t i v i t y ( t h i s ) . a d a p t e r ( t h i s ) . v i e w ( t u r b o l i n k s V i e w ) . v i s i t ( " h t t p s : / / r u b y - c h i n a . o r g " ) ; }
  66. T u r b o l i n k s

    . v i s i t 回调 @ O v e r r i d e p u b l i c v o i d v i s i t P r o p o s e d T o L o c a t i o n W i t h A c t i o n ( S t r i n g l o c a t i o n , S t r i n g a c t i o n ) S t r i n g p a t h = U r i . p a r s e ( l o c a t i o n ) . g e t P a t h ( ) ; / / . . . i f ( p a t h . m a t c h e s ( " / t o p i c s / \ \ d + " ) ) { I n t e n t i n t e n t = n e w I n t e n t ( t h i s , T o p i c A c t i v i t y . c l a s s ) ; i n t e n t . p u t E x t r a ( I N T E N T _ U R L , l o c a t i o n ) ; t h i s . s t a r t A c t i v i t y ( i n t e n t ) ; } / / . . . }
  67. 再加上原生工具栏、菜单、按钮等等……

  68. 定制移动页面 Responsive web design Action Pack Variants

  69. 用 Java 操作 WebVIew p r i v a t

    e v o i d t o p i c C r e a t e ( ) { T u r b o l i n k s S e s s i o n . g e t D e f a u l t ( t h i s ) . g e t W e b V i e w ( ) . e v a l u a t e J a v a s c r i p t ( " $ ( ' f o r m [ t b = \ " e d i t - t o p i c \ " ] ' ) . s u b m i t ( ) ; " , n u l l ) ; }
  70. 从 WebView 调用 Java T u r b o l

    i n k s S e s s i o n . g e t D e f a u l t ( ) . a d d J a v a s c r i p t I n t e r f a c e ( t h i s , " M y C u s t o m J a v a s c r i p t I n t e r f a c e " ) ;
  71. 快速开发

  72. 通过 Native 渐进增强

  73. 依然需要 Android & iOS 开发人员。

  74. 劣势 缺少开源代码参考。 跟团队已有的技术栈不符。 不适合交互复杂的移动应用。

  75. Turbolinks Mobile 提供了一个选择。

  76. 开源 https://github.com/ruby-china/ruby-china-android https://github.com/ruby-china/ruby-china-ios

  77. 多谢