由一个vue代码仓库PR引起的思考

517 阅读2分钟

免死声明:以下观点全是个人思考,由于知识面有限,可能理解片面,还望理性交流。

事情是这样发生的,之前在查看vue2.6.13版本升级的releases文档时候,看到一条性能优化的PR:预初始化类型检测正则表达式

e3cab65e36e0ee948f6c4e4fbdea52e6.png

点了进去看看,改动如下:

677cef014c29d51a1392e6f03d4d7d4b.png

初看感觉,这优化了啥,多写了一个全局变量,还增加了两行代码。

回过神来仔细一想,事情也许没那么简单。

  1. 会不会是多个地方用到这个表达式,写在外面定义为常量方便统一管理?

    看了整个文件的代码,并没有其他地方使用过这个正则表达式。

  2. 是不是把正则表达式定义为常量,方便阅读?

    那也没必要多生成一个外部变量,定义在getType方法内部不是更好。

那到底是提升了什么性能呢?

我们先来看看getType这个方法,显然它是公用的工具类方法,并且在当前文件暴露的方法中多次引用。而当前文件正式vue核心代码prop.js,暴露的方法必然会在vue实例中多次被调用。

那么,问题来了:难道跟getType方法调用的频率有关?

首先分析,修改前后的代码执行情况差异,更改后从外部取正则表达式,更改前是在当前作用域生成正则表达式,那么,

更改后:每次执行getType方法,由于正则表达式是定义在全局,不会销毁,所以每次都是一个从内存中读取的操作;

更改前:每次执行getType方法,正则表达式每次都会在当前函数作用域新开辟内存块来接收,然后执行完getType方法,退出函数作用域时候被销毁;

如此一来,更改前的代码,虽然没有产生多余的全局变量,及时释放了内存空间,但是却增加了执行消耗。

如果是低频引用的方法,更改前的代码更符合规范。但是考虑到框架代码的引用频率,采用把表达式定义在全局的预处理方法,从理论上来讲确实会快那么一丢丢。

其实思考到这里,感觉这种做法跟柯里化的原理有那么一丝相似,都是预处理一部分代码,缓存起来,以便后面的执行能更快更方便。