完整的手写源仓库
它是插件机制的核心。不仅可以解释官方源代码,还可以使用他自己的想法来实现它,并将其与官方操作时间进行比较。与WebPack作者有关的讨论可以单击查看。此优化方法不一定根据动态生成功能。当我们熟悉Tapable时,我们基本上了解WebPack插件的基本逻辑,然后回头看WebPack源代码
在包装和构造过程中,将有数千个(数字实际上取决于其自身的业务复杂性)。执行插头钩。同时,当执行相同类型的钩子时,函数参数是固定的,并且函数主体相同。因此,对于这些业务方案,对于这些业务方案进行了相应优化。最重要的是使用单核细胞和多态性。内部午餐的原理也可以看一下此ISUE。要实现此目标,动态生成功能的方法用于执行身体,主要逻辑在源代码的源代码的源代码中。
考虑下面的两个实现,哪个执行效率很高,哪一个实现很简单?
目的是实现一组具有相同参数调用的方法并依次执行它们。显然,该方法明显更高,并且很容易扩展,可以支持一组未修复的方法。根据单个状态和内部关节缓存,很明显,方法两的实现效率更高,也存在一个问题,也就是说,只有三种传递A,B和C的方法以及参数形式也已固定。易于说明,没有办法灵活。您可以同时照顾效率和灵活性吗?答案还可以。我们可以使用动态方式来生成功能主体。
当我们在浏览器控制台执行上述代码时:
缝合后的完整功能执行主体:
可以看出,通过这种动态方式来生成功能,我们可以同时考虑性能和灵活性。我们可以通过方法添加任意数量的任务,并通过初始化构造函数传递任何参数。
实际上,这是官方hookcodefactory.js.ss的简化版本。
主要的源代码位于中间。它主要提供了一种方法。每个都称为构造函数内部的初始化实例。执行主体主要基于动态生成函数。
以此为例,钩子用如下:
我们使用此演示作为逐步检查的情况。
主要逻辑如下:
主要逻辑如下:
考虑挂钩源代码中的几个问题。每当我们调用注册插件的方法时,该过程如下:
在数组中添加插头-in的方法相对简单,但是这里有一个细节要注意。为什么我需要调用此。
当我们第一次打电话(第一次注意)时,该方法实际上调用了该方法
呼叫函数根据注册的动态生成函数执行车身。设置的返回值已缓存,如果更改,则需要重新生成。
目前,如果我们第二次打电话,我们不需要重新加工该功能即可再次执行身体。这也是Tapable的优化技术之一。这也回答了问题1:为什么要call_delegate需要?
如果我们致电n次,然后致电注册的插头,我们目前无法重复使用。我们需要重新重新构成函数的功能。重置此功能是必要的。呼叫和其他方法。它是时候知道重新生成的过程是时间-Consuming。因此,当我们使用它时,最好一次注册所有插头,然后调用
避免以下呼叫方法:
现在让我们看一下第三个问题。调用该方法时,该方法实际上被调用:
关于问题四,实际上,这与V8引擎有关。通过在构造函数中绑定这些方法,类中的属性形式是固定的,因此在找到这些方法时,可以使用V8引擎中的属性来找到改善性能的机制。
主要逻辑:
所有手写的挂钩可敲击,并比较我们自己实施的钩子和官方执行时间
其中的每个文件将实现官方挂钩,并比较执行时间。以Synchook为例,当注册1,000个插件时,我们手写的Mysynchook执行时间为0.12ms,官员需要6ms。这是整个中间的50倍。差异!
你可以看我的仓库
原始:https://juejin.cn/post/7097881373754687525