React拖拽組件Dragact V0.1.7:教你優化React組件性能與手感

倉庫地址:Dragact手感絲滑的拖拽佈局組件html

預覽地址:支持手機端噢~react

上回咱們說到,Dragact組件已經進行了一系列的性能優化,然而面對大量數據的時候,依舊比較吃力,讓咱們來看看,優化以前的Dragact。git

縱向堆疊着314個方塊,插入時明顯的卡頓,大約1秒的延遲

一樣縱向堆疊着314個方塊,插入時卡頓明顯減小不少,能夠接受

在實際生產過程當中,可能不會有那麼多物塊,就拿咱們項目的dashboard來講,整個屏幕最多隻有10個方塊,就已是了不得了。github

可是強迫症犯了,爲了使得性能達到極致,再次進行了深度的優化。緩存

React優化的策略有哪些呢?性能優化

策略一: shouldComponentUpdate()

由於React 的diff只是簡單的深度優先+刷新策略去diff html tag,因此數據的改變,React是不會知道的。閉包

所以,開發者必須得本身去diff數據,shouldComponentUpdate就是用來diff數據的一個特殊聲明周期函數。dom

具體的,請看我以前的回答和徐飛叔的回答:ide

方正: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~

各位,咱們下次見。

相關文章
相關標籤/搜索