Object.prototype.hasOwnProperty的性能問題

前言

今天下午在閱讀Vue3,Component相關源碼時,發現了這麼一段註釋。(源碼地址: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.性能

大體意思是以下:優化

在渲染期間,對渲染上下文進行訪問時,hasOwn()操做很昂貴。而在普通對象上進行屬性訪問的操做,速度會快不少。因此在Vue3中使用accessCache對象,對對象進行緩存。ui

實驗

那麼Object.prototype.hasOwnProperty操做是有多昂貴,值得尤大進行優化。我使用下面的代碼,進行了實驗。this

const obj = {
  name: 'Natalie portman'
}
const accessCache = { ...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: ${new Date().getTime() - start}`)

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

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

// log
// duration: 35
// duration: 4
複製代碼

在進行500萬次,讀取屬性操做時,二者的性能相差了大約9倍。spa

當Vue的組件樹很大時,掛載的屬性不少時。使用accessCache對象,對Object.prototype.hasOwnProperty操做進行緩存,應該仍是頗有必要的。prototype

緣由

查詢了相關資料,大體緣由以下:code

Chrome的V8引擎,會維護一個全局的緩存。一旦高速緩存被填充,它老是會在隨後被重複命中。這意味着val[key]屬性查找,將始終在編譯時處理,而不會進行運行時。component

而V8引擎不會對,hasOwnProperty或者key in value進行任何緩存,老是進入運行時。對象

結語

👏歡迎你們指正。Vue3響應式數據源碼,nextTick,watch,相對來講很獨立,看起來很輕鬆。可是看到到Component後,涉及的內容太多了,推動的很慢。

參考資料

相關文章
相關標籤/搜索