1. 程式人生 > >React懶加載組件實現

React懶加載組件實現

算子 port ack node style 事件 ren 實現 ==

懶加載的好處

當我們一次性大批量的加載資源的時候,會占用大量的內存,尤其是在一些低內存的設備上會造成卡頓的現象,所以我們就需要在必要的時候再進行資源的加載。

懶加載就是在真正需要資源才加載資源,這樣就可以節省內存,盡可能的減少卡頓現象的出現。

技術分享圖片

懶加載原理

懶加載的原理就如上圖所示,當組件進入可視區域加載子組件,不在可視區域內卸載子組件。懶加載的原理就是這麽簡單,下面介紹一下懶加載具體的實現方法。

1. 計算子組件是否在可視區域之內

const checkVisible = (component,offset=100,parent) => {
   //獲取實際的DOM const node
= ReactDOM.findDOMNode(component)
  //獲取距離頂部的距離 const {top}
= node.getBoundingClientRect() const windowHeight = window.innerHeight || document.documentElement.clientHeight const {top:parentTop,bottom:parentBottom } = parent.getBoundingClientRect()
   //可視區域頂部的位置 const finalTop
= Math.max(parentTop,0)
   //可視區域底部的位置
const finalBottom
= Math.min(parentBottom,windowHeight)
   //計算是否在可視區域之內
if(top > finalTop - 100 && top < finalBottom + 100){ return true } return false }

2. 添加滾動事件

首先我們先利用上面的函數檢查檢查子組件是否在可視區域內,如果是則設置isVisible為true,則顯示組件,否則不顯示組件。

checkedVisible(parent){
     //是否只懶加載一次,once為true 加載之後不再操作dom
const once
= this.props.once ; const offset = this.props.offset return throttle(()=>{ const visibleState = this.state.isVisible if(!(once && visibleState)){ const isVisible = checkVisible(this,offset,parent) this.setState({isVisible}) } },200) }
const parent = getScrollParent(node);
const checkedVisibleFn = this.checkedVisible(parent) ;
//添加滾動事件
window.addEventListener("scroll",checkedVisibleFn,false)

為window對象添加滾動事件,為防止滾動事件頻繁觸發checkedVisible,我們為檢查checkVisible函數節流,減少性能開銷。此處我們利用的throttle函數,更多關於節流函數和函數去抖的介紹可參考這邊博客:JS魔法堂:函數節流(throttle)與函數去抖(debounce)。

3. 獲取可滾動的父組件

當前我們只是為考慮了window對象可滾動的情況,如果是DOM對象可滾動我們就需要獲取可滾動的父對象,而不只是僅僅window對象。

//獲取滾動的父元素
const getScrollParent = (node) => {
    if(!node){
        return document.documentElement
    }

    let parent = node ;
    //正則
    const overflowReg = /(scroll|auto)/
    while(parent){
        if(!parent.parentNode){
            return document.documentElement 
        }
        const {overflow} = window.getComputedStyle(parent)
        if(overflowReg.test(overflow)){
            return parent
        }
        parent = parent.parentNode
    }
    return document.documentElement
}

export default getScrollParent

4. 再次添加滾動事件

如果不僅僅是window可滾動我們在添加滾動事件之前進行一次判斷。

const node = ReactDOM.findDOMNode(this) ;
const parent = getScrollParent(node);
const checkedVisibleFn = this.checkedVisible(parent) ;

 if(parent === document.documentElement){
       window.addEventListener("scroll",checkedVisibleFn,false)
 }else{
       parent.addEventListener("scroll",checkedVisibleFn,false)
 }  

總結

以上基本就是react懶加載基本實現的方法,具體的代碼以及demo,可以參考源碼:https://github.com/volcanoliuc/react-lazyload-demo

此demo僅僅只是簡化版的react懶加載,如果是在實際的項目中需要使用推薦使用 react-lazyload。

React懶加載組件實現