preface

This afternoon while reading the Vue3 Component source code, I came across a comment like this. (the source address: packages/runtime – core/SRC/componentProxy ts)

This getter gets called for every property access on the render context during render and is a major hotspot. The most expensive part of this is the multiple hasOwn() calls. It’s much faster to do a simple property access on a plain object, so we use an accessCache object (with null prototype) to memoize what access type a key corresponds to.

The general meaning is as follows:

The hasOwn() operation is expensive when accessing the render context during rendering. Property access on ordinary objects is much faster. So Vue3 uses accessCache objects to cache objects.

The experiment

Then the Object. The prototype. HasOwnProperty is how expensive operation, is especially big optimization. I experimented with the following code.


const obj = {
  name: 'Natalie portman'
}
constaccessCache = { ... obj }const hasOwnProperty = Object.prototype.hasOwnProperty
const hasOwn = (val, key) = > hasOwnProperty.call(val, key)

let start = new Date().getTime()
for (let i = 0; i < 5000000; i++) {
  hasOwn(obj, 'name')}console.log(`duration: The ${new Date().getTime() - start}`)

start = new Date().getTime()
for (let i = 0; i < 5000000; i++) {
  accessCache.name
}

console.log(`duration: The ${new Date().getTime() - start}`)

// log
// duration: 35
// duration: 4
Copy the code

At five million reads of properties, the performance difference between the two is about nine times.

When the Vue component tree is large and many properties are mounted. We used the accessCache Object, the Object. The prototype. The hasOwnProperty operation for caching, should or very be necessary.

why

Related information has been inquired, and the general reasons are as follows:

Chrome’s V8 engine maintains a global cache. Once the cache is filled, it is always hit repeatedly later. This means that val[key] attribute lookups are always handled at compile time, not run time.

V8 doesn’t cache any hasOwnProperty or key in Value, it always goes to runtime.

conclusion

Comments are welcome at 👏. Vue3 responsive data source, nextTick, Watch, relatively independent, looks easy. However, after seeing the Component, there are too many contents involved and the progress is slow.

The resources

  • Why is getting a member faster than calling hasOwnProperty?