React拖拽组件Dragact V0.1.7:教你优化React组件性能与手感

仓库地址:Dragact手感丝滑的拖拽布局组件

预览地址:支持手机端噢~

上回我们说到,Dragact组件已经进行了一系列的性能优化,然而面对大量数据的时候,依旧比较吃力,让我们来看看,优化之前的Dragact。

纵向堆叠着314个方块,插入时明显的卡顿,大约1秒的延迟

同样纵向堆叠着314个方块,插入时卡顿明显减少很多,可以接受

在实际生产过程中,可能不会有那么多物块,就拿我们项目的dashboard来说,整个屏幕最多只有10个方块,就已经是了不起了。

但是强迫症犯了,为了使得性能达到极致,再次进行了深度的优化。

React优化的策略有哪些呢?

策略一: shouldComponentUpdate()

因为React 的diff只是简单的深度优先+刷新策略去diff html tag,所以数据的改变,React是不会知道的。

因此,开发者必须得自己去diff数据,shouldComponentUpdate就是用来diff数据的一个特殊声明周期函数。

具体的,请看我之前的回答和徐飞叔的回答:

方正:Vue为什么没有shouldComponentUpdate的生命周期?

徐飞:Vue为什么没有shouldComponentUpdate的生命周期?

策略二:用记忆功能函数去缓存大量计算结果

有很多情况下,我们的遍历是不可避免的。

React中最著名性能问题,就是selector问题,现在大家也都知道用reselect去做性能优化了,但是本质呢?

我们写一点伪代码来做演示:

//首先,我们有一个斐波那契生成函数  fib();
//用户想用的时候,就会去掉这个函数
const number = fib();


//我们知道,fib()函数里面会经过大量的计算,才得出我们想要的结果
//但是,除了第一次计算之外,之后的所有计算都是不需要的,因为我们已经在一开始拿到结果了

//怎么做最好呢?闭包;

const Fib = function (){
   var cache = void 666;
   return function(){
      if(!cache){
          cache = fib();
          return cache;
       }
      return cache;
   }
}();

//当用户调用Fib的时候,只会在第一次进行计算,之后的后只会从cache中拿出来。

不要小看这种优化,很多时候,我们大量重复的遍历就会导致性能的低下。

策略三:减少dom的深度

我们都知道,每次react 更新的时候,都会进行diff,深度越大,diff的层次越多。

减少diff的层次是非常重要的性能优化手段,尤其是数据量巨大的时候。

具体怎么去减少dom的深度,方法有很多,我用的方法是:render children的办法。

简单的举个例子,拖拽组件:

<Dragger>
    <div>我是拖拽的组件</div>
</Dragger>

这样的一个设计,看似很简单,很明了。用Dragger组件去包囊我们想要的组件,就可以让其获得拖拽的属性。

这么做不是不行,但是很多时候我们在设计之初,没考虑那么多,就会使用这样一种方式去设计:

class Dragger extends Component{
    moving(){}......

    render(){
      return (<div
         onMouseDown={...}
         onTouchDown={...} 
         style={....}
         >
         {this.props.children}
         </div>)
    }

}

是不是很常见?这么做的问题其实很明显,就是无缘无故的,我们多了一层div,组件一多,那么就多会了几层div,无疑造成了渲染压力。

使用render children,我们可以这么设计

class Dragger extends Component{
    moving(){}......

    render(){
      const provided = {
       onMouseDown:this.onMouseDown
         onTouchDown:this.onTouchDown
         style:{....}
      }
      return this.props.children(provided);
    }
}

在外部使用的时候,就变成了:

<Dragger>
    {(provided)=><div {...provided}>我是拖拽的组件</div>}
</Dragger>

看似稍微蛋疼了一些,但是好处就是:减少了dom的层级。

还有更多好处,可以看之前的一篇文章:React组件:拖拽布局Dragact v0.1.6 发布

手感的优化

看似很标准,实际上用户需要拖动很远,才会物体进行交换

看似很标准,实际上用户需要拖动很远,才会物体进行交换,造成这样让人不适的感觉原因是因为计算时,我取的计算中心永远是物体的顶边。

所以,当物体向下滑动的时候,必须要物体的顶边到达下一个物块的中心才能发生交换。

上图我们可以看到,长条的物块,已经拖出了屏幕很远,才会进行交换。

就这一点点差异,让我顿时感到不爽!

为了使得手感更加优异,做了大量实验以后,我发现,把移动中心设置在物体的重力中心,最为舒适。

把移动中心设置在物体的重力中心,最为舒适。

这一点点设计的改变,使得手感完全不同了。

你可以狠狠的点击:预览地址

到此,Dragact组件,无论从性能,还是手感上来说,都已经相当的符合我们的需求了。

yeah~

各位,我们下次见。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom