Flipboard推出React Canvas 15-02-11 banq Flipboard增加React组件渲染,而不是DOM。该开源项目不少代码已经进入flipboard.com的生产阶段:Flipboard/react-canvas · GitHub Facebook刚刚发布React.js是基于DOM渲染,通过算法计算虚拟DOM和实际物理DOM之间的差别,然后渲染差别达到快速性能。参考:使用React Native的第一印象,React.js单方向的数据流和声明API已经改变了人们构建应用的方式:flux模式 如果将React组件绑定到canvas布局(而不是DOM)会怎样呢?Flipboard进行了大胆尝试: Flipboard已经有很长的构建面向移动设备的界面历史,他们发现移动应用相对原生应用感觉比较慢的是DOM,CSS动画和切换是在Web上最快速实现平滑动画的方式,但是它们有一些限制,而React Canvas考虑到大多数现代浏览器已经有硬件加速的canvas。 同时还有其他试图绑定Canvas绘图API实现React,它们更加注重在视觉效果和游戏。在构建不同用户界面上的重点不同导致React Canvas的差别,事实上,渲染到canvas是一个实现细节。 React Canvas给Web开发者带来熟悉的API,并带给他们一个高性能绘图引擎。 以使用Javascript实现页面滚动效果来说明,使用一个canvas元素实现滚动,当发生每个触摸事件时,当前渲染树被当前根据滚动偏移量计算的每个节点更新,整个渲染树然后重新使用新的坐标系渲染。这个过程会很慢,但是这里有一个重要的性能优化:可将绘图操作结果缓存在一个off-screen离屏canvas上,这个off-screen离屏canvas然后在稍后时间用来重画。 这种技术不但可用于图片层,文字和图形都可以,很费力的绘图操作是填充文字和图形图像,但是一旦等到这些层画完,能够使用off-screen离屏canvas快速重画它们。下图每个页面分为两个层,一个图片层和一个文字层,文字层包含很多组元素,在滚动动画的每一帧中,两个层使用缓存位图bitmap进行重画: 使用React Canvas的实现代码: var ListView = React.createClass({ getInitialState: function () { return { scrollTop: 0 }; }, render: function () { var items = this.getVisibleItemIndexes().map(this.renderItem); return ( <Group onTouchStart={this.handleTouchStart} onTouchMove={this.handleTouchMove} onTouchEnd={this.handleTouchEnd} onTouchCancel={this.handleTouchEnd}> {items} </Group> ); }, renderItem: function (itemIndex) { // Wrap each item in a <Group> which is translated up/down based on // the current scroll offset. var translateY = (itemIndex * itemHeight) - this.state.scrollTop; var style = { translateY: translateY }; return ( <Group style={style} key={itemIndex}> <Item /> </Group> ); }, getVisibleItemIndexes: function () { // Compute the visible item indexes based on <code>this.state.scrollTop</code>. }});触摸事件: // Create the Scroller instance on mount.componentDidMount: function () { this.scroller = new Scroller(this.handleScroll);},// This is called by the Scroller at each scroll event.handleScroll: function (left, top) { this.setState({ scrollTop: top });},handleTouchStart: function (e) { this.scroller.doTouchStart(e.touches, e.timeStamp);},handleTouchMove: function (e) { e.preventDefault(); this.scroller.doTouchMove(e.touches, e.timeStamp, e.scale);},handleTouchEnd: function (e) { this.scroller.doTouchEnd(e.timeStamp);}这么简单的代码体现了React的最好品质,触摸事件被声明地绑定在render()中,每个触摸事件转发到Scroller,在那里计算当前滚动距离顶部的偏移差值,从Scroller发出的每个滚动事件更新ListView组件的状态,只是更新屏幕上可见部分,所有这些在16毫秒内发生,因为React的比较算法非常快。 React Canvas相比iOS/Andriod原生应用的优点,比如原生应用中不能从应用程序中复制一段文本,或者复制一个链接到浏览器,复制电话号码或地址。而基于DOM/Canvas能做到这些。 [该贴被banq于2015-02-11 17:13修改过]