国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

幫你讀懂preact源碼(三)

yuanxin / 3481人閱讀

摘要:對回收的處理在中,回收調(diào)用了兩個方法,節(jié)點的回收一般會調(diào)用,組件的回收會調(diào)用。個人理解從以上源碼閱讀中我們可以看到,最大的性能問題在于遞歸的,中的與也是為了緩解這個問題。為不同類型的更新分配優(yōu)先級。

對回收的處理

在preact中,回收調(diào)用了兩個方法,dom節(jié)點的回收一般會調(diào)用recollectNodeTree,組件的回收會調(diào)用unmountComponent。

preact復(fù)用dom的秘密在于當要卸載一個組件的時候,只有組件的根節(jié)點會從父節(jié)點上卸載掉,組件完整的dom仍然存在,被卸載的組件會保存在components對象中。

在創(chuàng)建組件的時候又通過nodeName拿到對應(yīng)的dom節(jié)點樹,掛載在組件實例的inst.nextBase上,在renderComponent的時候,再diff nextBase與新的虛擬dom樹rendered。

相關(guān)主要代碼如下:

function createComponent(Ctor, props, context) {
    let list = components[Ctor.name],
        inst;

    if (Ctor.prototype && Ctor.prototype.render) {
        inst = new Ctor(props, context);
        Component.call(inst, props, context); 
    } else { // 對應(yīng)函數(shù)組件
        inst = new Component(props, context);
        inst.constructor = Ctor;
        inst.render = doRender;
    }

    if (list) {
        for (let i = list.length; i--;) {
            if (list[i].constructor === Ctor) {
                inst.nextBase = list[i].nextBase;
                list.splice(i, 1);
                break;
            }
        }
    }

    return inst;
}
setState的處理

更改組件上的state,然后將要渲染的組件放在一個數(shù)組中,在下一次event loop的時候渲染:

    setState: function setState(state, callback) {
        let s = this.state;
        if (!this.prevState) this.prevState = extend({}, s);
        extend(s, typeof state === "function" ? state(s, this.props) : state);
        if (callback)(this._renderCallbacks = this._renderCallbacks || []).push(callback);
        enqueueRender(this);
    },

    function enqueueRender(component) {
        // component._dirty為false且items原本為空數(shù)組就能渲染
        if (!component._dirty && (component._dirty = true) && items.push(component) == 1) {
            (options.debounceRendering || defer)(rerender); //異步的執(zhí)行render,要執(zhí)行render方法的component中的_dirty設(shè)為true
        }
    },

    function rerender() {
        let p,
            list = items;
        items = [];
        while (p = list.pop()) {
            if (p._dirty) renderComponent(p);
        }
    }
preact對事件的處理

preact為了減少增減事件對性能和內(nèi)存的影響,當為dom做事件監(jiān)聽時,添加的是一個代理函數(shù)。

function setAccessor(node, name, old, value, isSvg) {
// ...
if (name[0] == "o" && name[1] == "n") {
            let useCapture = name !== (name = name.replace(/Capture$/, ""));
            name = name.toLowerCase().substring(2);
            if (value) {
                if (!old) node.addEventListener(name, eventProxy, useCapture);
            } else {
                node.removeEventListener(name, eventProxy, useCapture);
            }
            (node._listeners || (node._listeners = {}))[name] = value; 
        } 
// ...
}
    function eventProxy(e) {
        return this._listeners[e.type](options.event && options.event(e) || e);
    }
fiber(個人理解)

從以上源碼閱讀中我們可以看到,react最大的性能問題在于遞歸的diff,react中的shouldCompnentUpdate與PureComponent也是為了緩解這個問題。但是當應(yīng)用比較大的時候一個高級別組件的diff還是很容易使得動畫掉幀。

fiber的出現(xiàn)就是為了解決這個問題,react fiber將計算工作分成了多個小片,這使得整個計算工作可以暫停,中止,或重新開始。為不同類型的更新分配優(yōu)先級。當動畫或用戶交互觸發(fā)時,就可以先暫停低優(yōu)先級的更新工作,保證動畫的流暢性,等所有的渲染計算工作完成,對dom更新進行一次commit。

參考

https://calendar.perfplanet.c...

https://reactjs.org/docs/impl...

https://segmentfault.com/a/11...

https://www.w3ctech.com/topic...

https://zhuanlan.zhihu.com/p/...

https://github.com/acdlite/re...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95133.html

相關(guān)文章

  • 幫你讀懂preact源碼(一)

    摘要:是一個最小的庫,但由于其對尺寸的追求,它的很多代碼可讀性比較差,市面上也很少有全面且詳細介紹的文章,本篇文章希望能幫助你學(xué)習(xí)的源碼。建議與源碼一起閱讀本文。 作為一名前端,我們需要深入學(xué)習(xí)react的運行機制,但是react源碼量已經(jīng)相當龐大,從學(xué)習(xí)的角度,性價比不高,所以學(xué)習(xí)一個react mini庫是一個深入學(xué)習(xí)react的一個不錯的方法。 preact是一個最小的react mi...

    XboxYan 評論0 收藏0
  • 幫你讀懂preact源碼(二)

    摘要:最后刪除新的樹中不存在的節(jié)點。而中會記錄對其做了相應(yīng)的優(yōu)化,節(jié)點的的情況下,不做移動操作。這種情況,在中得到了優(yōu)化,通過四個指針,在每次循環(huán)中先處理特殊情況,并通過縮小指針范圍,獲得性能上的提升。 上篇文章已經(jīng)介紹過idff的處理邏輯主要分為三塊,處理textNode,element及component,但具體怎么處理component還沒有詳細介紹,接下來講一下preact是如何處理...

    Warren 評論0 收藏0
  • 數(shù)據(jù)結(jié)構(gòu)與算法():帶你讀懂選擇排序(Selection sort)

    摘要:基本介紹選擇式排序也屬于內(nèi)部排序法,是從欲排序的數(shù)據(jù)中,按指定的規(guī)則選出某一元素,再依規(guī)定交換位置后達到排序的目的。而移動次數(shù)與序列的初始排序有關(guān)。空間復(fù)雜度簡單選擇排序需要占用個臨時空間,在交換數(shù)值時使用。 showImg(https://img-blog.csdnimg.cn/20190509221741422.gif); showImg(https://segmentfault....

    Kaede 評論0 收藏0
  • 源碼入手,一文帶你讀懂Spring AOP面向切面編程

    摘要:,,面向切面編程。,切點,切面匹配連接點的點,一般與切點表達式相關(guān),就是切面如何切點。例子中,注解就是切點表達式,匹配對應(yīng)的連接點,通知,指在切面的某個特定的連接點上執(zhí)行的動作。,織入,將作用在的過程。因為源碼都是英文寫的。 之前《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》詳細講了Spring容器的初始化和加載的原理,后面《你真的完全了解Java動態(tài)代理嗎?看這篇就夠了》介紹了下...

    wawor4827 評論0 收藏0
  • 少啰嗦!一分鐘帶你讀懂Java的NIO和經(jīng)典IO的區(qū)別

    摘要:的選擇器允許單個線程監(jiān)視多個輸入通道。一旦執(zhí)行的線程已經(jīng)超過讀取代碼中的某個數(shù)據(jù)片段,該線程就不會在數(shù)據(jù)中向后移動通常不會。 1、引言 很多初涉網(wǎng)絡(luò)編程的程序員,在研究Java NIO(即異步IO)和經(jīng)典IO(也就是常說的阻塞式IO)的API時,很快就會發(fā)現(xiàn)一個問題:我什么時候應(yīng)該使用經(jīng)典IO,什么時候應(yīng)該使用NIO? 在本文中,將嘗試用簡明扼要的文字,闡明Java NIO和經(jīng)典IO之...

    Meils 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<