Web Components
最近开发阶段当中状态挺糟的,包括空余时间也很没精神去改个人项目
算是进展的是 Google IO 关于 Polymer 的几个视频,周末总算看完了
我虽然很讨厌其语法设计,但不得不承认未来几年 Polymer 影响巨大
Backbone,Angular,相对来说小打小闹,我多半是夸张,反正就是想说很重要
我写 Backbone,但是别人写的模块我不会拿过来直接用,公司代码库也比较谨慎
而 Angular 代码我接触少,但是从 Vue 推测,我也不认为 MVVM 有多合适共用
React 里模块的观念已经很接近 Component 了,可实际编码中代码依然不常复用
(当然,我做前端实际工作一年半,我也没深入 Angular,细节事后要商榷)
而 Polymer 目标就是为 Web Components 提供兼容现有浏览器的实现
Web Components 核心是自定义标签,为元素的复用夯实基础
从这里可以看 Web Components 规范,细节和 Polymer 估计有出入
https://w3c.github.io/webcomponents/explainer/
http://www.polymer-project.org/docs/start/creatingelements.html
缺乏足够的经验,我不能确认这对于完成复杂的大量交互的应用是否足够
但是从已经演示过的 Polymer desinger tool 看来真的很强大
http://www.tudou.com/programs/view/aTCnSgdgXa4/
我不想描述 Polymer 细节如何如何有用,只想说 Web 缺这个功能太久了
回到编程语言,核心的功能是什么? 是组合数据类型,组合函数调用的能力
通过这两个功能,复杂的结构,复杂过程,都能通过代码复合来达成
然后我们通过 import 语法连接文件,通过包管理器共享代码,形成生态
界面组件大家都注重复用,往往都要造轮子,各个流行框架自己都有一套
我不知道 Web Components 算不算最终的答案,但我们等到了一个好的选项
颜色和布局
Chrome 给设计调整界面带来了巨大的方便,但项目当中未必都能用上
而且也很少人能同时具备项目的决策,设计,编码各方面的角色,未必随便用
Google 新的 UI 所以能在各种平同通用搭配,在于他们事先做的大量设计
适应不同尺寸的 Roboto,适应各种尺寸屏幕的而统一的界面风格,
通过 hero image,FAB 等等元素构建起来的统一视觉等等
这么大的架构,单纯作为个前端我表示无从下手
不少颜色跟布局的细节,是设计图或者方案中不能面面俱到的
我目前不清楚细节怎样做到的,大致的思路是:
* 颜色要有配色表,从设计图出发能根据配色表延伸出去搭配
* 布局的种类限定,界面当中普通的布局通过约定的布局快速完成
当然颜色不那么简单,除了固定的配色,还会有半透明的元素要考虑
还有边框跟阴影,在 Material Design 中还会对应 z-index 而不同
对于颜色我能认识到的,大部分还是从感觉出发进行的调整,至少不严谨
至于到 Google 那样级别的统一配色,我现在还不敢想
局部问题离开了 FlexBox 我就不敢想了,可重用的布局基本做不到
常见的前端 UI 框架会提供表格布局,但是精细程度完全不过对付 App
兼容性部分的大量 absolute 代码需要手动维护,我觉得是逃不开了
组件和业务分离
这是是周末和朋友聊的时候说到的,我回来一想发现又被他说对了
没有长时间的组件积累,业务当中的 UI 经常是随着开发直接在代码当中做的
不仅难以通过时间保证质量,就连 UI 组件模块化单独维护都很很难做到
这个问题也关联设计语言,没有稳定的设计语言,UI 组件功能也很难稳定下来
没有稳定的组件,把组件作为业务的一部分快速编码反而是最后的选择
我眼里好的开发方式,在 Polymer designer tool 里太明显了
所有组件都是定制好的,业务的开发就从这些拖拽开始,通过绑定结束
类似的方式也许在 Noflo 那些交错的线条当中也有体现出来
经过这样的模块化之后,开发的职责确实非常清晰,模块重用也得以提高
自动的视图渲染
界面自动更新是难以避免的事情,甚至其中还会伴随一些动画
对于还不会手写 Diff 的我来说这类问题实在是扎扎实实的难题
并且在业务代码当中对 DOM 坐 Diff 也必然是消磨时间的做法
在 Polymer 当中,这个功能又通过数据绑定完成了
Polymer 和 React 的不同
这个不同设置让我有点困惑,就是如何讲数据分发到不同级别的 View 当中
React 对应的是 Flux 的模型,有着近乎全局的 Store 存放数据
,然后每个 View 或者从父元素传入属性,或者更多从 Store 中直接获取数据
而 Polymer 中,数据被直接嵌入到 View 当中去了,用另一种方式保证了数据一致性
在学 React 时,我模仿的是服务端渲染页面的思路,数据库,路由,控制器
,每个页面划分为局部,这些部分用字符串拼接的方式轻松组合到一起
React 中是函数调用的嵌套,非常轻松地也将界面拆分为 Component 再一起组合
这个组合的过程中,可能有很多数据的查询和转化,这在后端渲染已经成熟了
而 Polymer 是通过 HTML 属性中形似 Angular 的语法来达成这个步骤的
同时 Component 良好的封装意味着不会存在 Flux 当中的全局 Store 可以查询
,结果是智能通过外层 Component 绑定的数据来对 View 进行更新
当然良好的封装首先带来好处,可我想不明白这同时作为限制会带来什么影响
不管怎样,Model 和 View 两者的数据一致性在两个方案里都解决掉了
或许细节上的差异可以简单通过某些巧妙的 trick 解决,等社区推举方案了
前端的数据
基于 Flux Store 我想到,从 View 的角度,若数据都在前端,开发可以大幅简化
那样的开发方式就像是有个数据库,每次渲染页面查询数据库就好了
这样就和我们目前设计的架构相似,数据的生命周期定为:
* 浏览器打开,同步所有用户数据,还有当前时段的列表形式的数据
* 本地 View 的操作,更新本地 Store,向服务器发起同步,更新回本地
* 其他客户端数据更新,自动同步到本地的 Store
* 每次 Store 更新都出发事件,View 是绑定 Store 的,因此自动更新
我印象里 Meteor 和 Derby 设计中就在解决这样的问题,强大的数据同步
在那样一个视野中,前端 View 和 Model 数据自动同步,前端和后端数据自动同步
于是,单页面开发就不像现在这样,前后端纠结一次,多个 View 和 Model 还要纠结
甚至于,经过这一步解耦,Store 同步服务器的逻辑也给抽象出来
比如 Derby 的同步引擎 Racer,抽象之后客户端 Todo 同步服务器数据极为简单
https://github.com/codeparty/racer
https://github.com/codeparty/racer-examples/blob/master/todos/client.coffee
Racer 背后的技术用了 ShareJS,算法源于 Google Wave 的 OT.. http://sharejs.org/
看到 Wave 的名号我每次都肃然起敬... 想来算法也不会简单
总体上,我认为影响效率的几个问题:
* 服务器,前端内存,View,这三组数据如何保持一致?
* 渲染界面时,怎样快速重用已有的颜色和布局,也就是怎样复用组件?
* 另外大概还有怎样避免掉前端开发的坑.. 只能凭经验?