You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
10 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 加餐 | 前端交互基础设施的建设
## 分享内容大纲
Vue、React等现代前端框架很好地解决了组件化和数据视图解耦问题。而对前端来说新交互永远是花费时间最多的工作新交互也是前端团队的自然价值和核心竞争力之一。
在这次话题中,我会分享在交互的基础设施的建设上的一些思考和实践,包括图形图像基础、事件机制与视图层架构模式、交互管理框架等内容。
![](https://static001.geekbang.org/resource/image/79/1c/7917180b45e4d591bf3aaaada17c911c.jpg)
首先我们要了解一下历史。在70年代大概是70年代的尾巴1979年左右有了特别有名的MVC架构。
MVC之后经过了差不多十几年的发展到了90年代准确地说应该是95年左右的时候这个有一个公司的CTO叫MikeMike在MVC的基础上提出来了MVP。
到了 2005年2005年微软的一个架构师做WPF的提出了MVVM模式。
2014年左右的时候出现了FLUX这个是Facebook为了它的JSX和React提出的一种模式。
后来隔了短短的一年2015年同样是在React社区出现了REDUX。
对于前端来说,我们为用户创造价值才是特别回答的一个问题,这么多年过去了,前端到底为用户创造了什么价值呢?
![](https://static001.geekbang.org/resource/image/b4/35/b46a898e8a5bc31280f8754cdfe1ed35.jpg)
这是70年代施乐公司做的一个软件管理的流程图软件那个时代整个的界面就是这个样子施乐已经算比较先进的了。
再到90年代当时这个画面还是很惊艳按钮键是立体的。现在来看这个东西就有不那么美观了。
2006年左右的时候Vista的界面已经开始有了一个非常大的变化了这时已经是设计师在主导这个界面的了但是性能并不佳。
再之后手机出现了比如iPhone的界面这时不但交互模式发生了巨大的改变而且屏幕也变了甚至我们熟悉的鼠标不见了变成了触屏。虽然两者之间操作上有一定的相似但是变化还是非常的。
![](https://static001.geekbang.org/resource/image/25/30/25648bd93fef8871c1eccc612f7f3530.jpg)
视图的职责也在演变70年代视图的职责是任何一个视图永远不应该知道用户的输入。
我们这个时代的视图则既负责输入也负责输出并且与Model之间有一个交互。
![](https://static001.geekbang.org/resource/image/cb/ab/cb57a540ec3779002c7c31d0960005ab.jpg)
计算机的功能也在演变。70年代计算机主要用来计算。
我们今天计算机主要用来上网基本上大家的计算机都是24小时联网的你的手机也是24小时联网的所以计算机的职责在发生变化。
这个变化对于UI有很大的影响1970年的那个MVC那篇论文里的图model很大view很小而到了2018年今天我们很多的model都是放在服务端的而今天model的大小已经不是说一台机器上能去存的你存在本地的只是视图展现一点点的model这个是很小的一部分的东西。而同时view却越来越重要了。
![](https://static001.geekbang.org/resource/image/62/0e/6287d6cb49f51c13b2ba89bd121cc30e.jpg)
我们来看一下视图的技术。
从最底层的有很多人是做显卡和drivers有这样的大佬人才。
还有现在非常流行的OpenGL等的GL层做这一层的人非常专业基本上都集中在各种大公司最近苹果和安卓还竞争推出了新一代的这个GL架构。
还有一个这个Draw层这一层的内容非常多基本上就爆发了skia是安卓的底层绘制系统graphics.h是最早的C语言带的一个图形库基本上相当于一个基础库还有很多3D引擎。
UI Framework这一层它提供了一套基本的UI结构有了绘制层 一般人都不会在绘制层直接去工作需要有些控件这层有我们比较熟悉的Dom。GJI是Windows的图形系统WPF也是Windows的图形系统。
最上面其实会有一些DSL这是描述图形的语言WPF对应的就是XAMLJSX对应的是ReactHTML大家都知道了想说这个视图技术变得越来越复杂
![](https://static001.geekbang.org/resource/image/ae/20/ae5b0f0cb1e5e42370d97fa518307a20.jpg)
那么我们的主战场是怎么样的,我们可以看一下淘宝终端技术在各层上的分布状况。
交互体系其实是这里面的一部分,但它不是这里面的全部,我觉得我们要讲这个交互呢,我们还是要做一下抽象的,我们要认识到,交互的本质是什么。
![](https://static001.geekbang.org/resource/image/7b/18/7b1cbcd358431b45ef23fc13f4732e18.jpg)
交互的本质是什么呢,我画了一个手和一个眼睛,其实无非是操作和看。
操作最常见的一个抽象的模式就是事件。这个比如说这个touch-screen事件陀螺仪事件或者是时钟芯片触发的持续事件这些作为输入。
输出一定是通过属性的形式体现的在任何一个现在的UI框架下都是通过属性的方式反映出来的。transform是变形opacity是透明度color是颜色这就是一个比较完整的抽象了。你在任意的输入和输出连成一条线后它都会产生一种效果。
![](https://static001.geekbang.org/resource/image/59/8e/597261cebd9e48d115f6c8ae2a9b098e.jpg)
不过直接把陀螺仪得到的参数输入到transform里肯定是不行的它需要有个关系我们在这里面选择了Expression。我们可以用JavaScript去做计算。我觉得这是一个完备的抽象。
![](https://static001.geekbang.org/resource/image/cb/ee/cba8a0fac235bd1186a9a470b50564ee.jpg)
不过这里还有一个坑是需要迈过去的,对计算机理解的输入跟人类理解的输入有非常大的偏差,对计算机来说呢,有多少种硬件,就有多少种输入。
我们发现输入非常复杂,在做基础设施建设的时候,我们在输入上面其实投入了很大的精力,最后出来的是一个更接近于人脑概念的一系列的输入。
![](https://static001.geekbang.org/resource/image/ff/95/ff41ffacad1377e0caf5a3890cf17f95.jpg)
比如说touch和gesture我们知道触屏其实是触屏事件触屏事件其实非常简单只有四个touch starttouch movetouch endtouch cancel则不太常用。
比如我想摁或者点一个东西它都是是touch starttouch movetouch end如果你要监听这些事件中间的判断很繁琐作为交互的基础设施我们不可能提供这些给我们的前端工程师使用我们肯定做一些操作。
比如手指移动10px我们就认为这个touch start到了pan start这个后面就是pan movepan end这样
手指很快离开那么它就会产生一个tap事件。
如果超过1.5秒那就一个press start如果手指没移呢就会产生一个press end如果手指移了它还会产生一个pan start。所以gesture已经比touch复杂了很多了。
![](https://static001.geekbang.org/resource/image/0e/f6/0edd194d6926619cf994444f9b4b54f6.jpg)
scroll就在gesture的基础上又复杂了一层它不但手指在屏幕的时候响应手指离开屏幕的时候它也响应比如说轮播它是一个变形的轮播它在轮播的过程中不但产生位移还会产生大小的变化这就让用户更舒服一些。
还有一个滚动导航一边滚动出来一个导航近年来还有一个交互设计不是滚动到某个位置导航出来而是一直再往下滚动的时候它不出来突然往上滚动一下导航就出来。这个部分还有更难的设计交互所以我们还需要在scroll的基础上再做一层。
![](https://static001.geekbang.org/resource/image/55/df/55553181bd8ff7feaebc7a5afda03cdf.jpg)
我们再来看陀螺仪它只提供了三个分量并且它是0到360度所以如果不经过任何处理前端工程师基本上是没有办法用的比如在某个角度它可能会突然从0跳变成360度这个在数据计算时候非常可怕。
所以我们建立这样一个模型,我们把手机看作这样一个立方体,去计算在空间中对立方体产生的旋转效果,我们拿着立方体上面的一个点呢,去做我们定位的一个依据。
![](https://static001.geekbang.org/resource/image/40/a6/406d0e28e45424ad7a5f7f55b0def8a6.jpg)
因为我们在用Weex所以有一个Native跟JS通讯的问题比如说从gesture事件到gesture handler这一步就会到JS去执行图中我们可以看到这个线跨过中间JS和Native的分界线跨越地非常频繁。
假如一个Touch move事件或者Pan move事件你手指每移动一小点它都会触发一次JS跟Native的一个跨语言通讯所以说整个的性能会非常差最后基本上会有5毫秒到10毫秒左右的一个延迟有60帧的话每一秒钟有300毫秒被占掉了帧率就下去了。
![](https://static001.geekbang.org/resource/image/ce/66/cec057f7bc548c01e0ef3bafa6975766.jpg)
这就是我们最初开始做Binding模式的原因。我们的Binding模式expression传递一次给Native然后它会去做大量的绑定所有的过程都是由Native来完成的Native做完了以后还需要再更新一下VDOM所以这操作就完全由Native完成通讯次数就降下来了。除此之外我们还额外收获了性能上的收益。
![](https://static001.geekbang.org/resource/image/3f/c5/3f1c0f0a6313fac231e3328e0a07f7c5.jpg)
我们的结论其实淘宝一个交互体系是这样的是以Binding为核心下面的平台支持了weexWebReact Native。DSL上面我们支持了View和Rax两种在上面是由我们自己建的Components体系。
![](https://static001.geekbang.org/resource/image/c2/92/c25d8385b4fba22294bbab5e30b95a92.jpg)
最后,还有一个展望,我们用绘制层相结合,会有更多的想象空间,我们通过各种各样的输入、手势、时间、陀螺仪,我们其实可以去控制矢量图,也可以去控制绘制,这些都是前端未来的想象空间。
如果你对今天的内容有所思考,可以给我留言,我们一起讨论。