React池化技术

606 阅读3分钟

概念

池化技术也叫做对象池模式,主要的作用是:一方面限制一个类的实例个数。防止无限制的生产实例,最后导致有些实例无法释放,引起内存的泄露。一方面是无需每次都生成实例,而是从池中选取一个拿来使用。(生成实例的性能消耗也是很大的,能够少的生成实例,就能提升性能。React性能不是某一件事做的,而是散列在整个React内的,每一个地方都稍稍的提升了些性能,整体的性能提升幅度就打了很多。量变引起质变。)

步骤

1 addPoolingTo 创建对象(添加到池中)

2 getPooled 借实例来用(从池中拿一个)

3 release 用完还回去(释放到池中)

PooledClass 类。

    var PooledClass = {
        addPoolingTo: addPoolingTo,
        oneArgumentPooler: oneArgumentPooler,
        twoArgumentPooler: twoArgumentPooler,
        threeArgumentPooler: threeArgumentPooler,
        fourArgumentPooler: fourArgumentPooler,
        fiveArgumentPooler: fiveArgumentPooler
    };

我们先来看看 创建对象的过程 addPoolingTo方法

    var addPoolingTo = function (CopyConstructor, pooler) {
          <!--
                CopyConstructor参数是那些想要使用池化技术的类。
          -->
          
          var NewKlass = CopyConstructor;
          
          <!--
            为想要使用池化技术的类,初始化一个属性 instancePool,这就是'池化''池'.就是用来放置类的实例的。
          -->
          NewKlass.instancePool = [];
          <!--
            为类添加一个方法getPooled,这个方法就是从池中返回一个实例来使用。
            pooler:主要有五个,这五个只是接受的参数的数量不一样,其他的都一样。下边我们来分析,pooler做 什么。
          -->
          NewKlass.getPooled = pooler || DEFAULT_POOLER;
          
          if (!NewKlass.poolSize) {
            <!--
                设定池子的大小默认是10.
            -->
            NewKlass.poolSize = DEFAULT_POOL_SIZE;
          }
          <!--
            好借好还再借不难,这个release方法就是用来还回实例的。
          -->
          NewKlass.release = standardReleaser;
          return NewKlass;
    };

addPoolingTo方法主要做了几件事:

1 为要池化的对象生成一个池子:instancePool

2 为要池化的对象安装一个从池子中 '借' 实例的方法:getPooled

3 设定这个池子的大小,防止池子太大,费性能: poolSize

4 为要池化的对象安装一个 '还'回 之前'借'的实例方法: release。

接下来看看从池中 '借'实例的方法:getPooled

getPooled有五个,区别在于接受参数的个数,我们以只接受一个参数的方法来看看。

    var oneArgumentPooler = function (copyFieldsFrom) {
        <!--
            先来看下这个this是什么鬼
            在addPoolingTo中我们可以知道:
            [要使用池化技术的类].getPooled= oneArgumentPooler
            [要使用池化技术的类].getPooled方法是 借 实例的方法。
            由此,我们可以知道this指向的就是 [要使用池化技术的类]
        -->
        var Klass = this;
        <!--
            先看看这个类的 池中有没有实例
        -->
        if (Klass.instancePool.length) {
            <!--
                有实例就取出来一个。
            -->
            var instance = Klass.instancePool.pop();
            <!--
                这里是使用构造类来将一个实例重新初始化,这个消耗手要远远小于new一个新实例的。
                
            -->
            Klass.call(instance, copyFieldsFrom);
            return instance;
        } else {
            return new Klass(copyFieldsFrom);
        }
    };

有借有还,再借不难standardReleaser方法:

    var standardReleaser = function (instance) {
        <!--
            this当然还是要使用池化技术的类本身。
        -->
        var Klass = this;
        <!--
            destructor方法是 要使用池化技术的类提供的一个方法。
            方法的主要作用是将实例内的属性初始化。
        -->
        instance.destructor();
        if (Klass.instancePool.length < Klass.poolSize) {
            Klass.instancePool.push(instance);
        }
    };

如此,便是React的池化技术,简单而又有深意,值得反复的思索。