前端性能優化一:性能指標javascript
前端性能優化二:現代瀏覽器javascript性能優化(1)前端
前端性能優化三:現代瀏覽器javascript性能優化-ICsjava
前面一章咱們已經介紹過js引擎是如何經過shape和ICs來優化js對象。若是沒看過的同窗能夠先看前面一章。這一章介紹一下js引擎是如何對原型鏈進行優化的。web
咱們都知道js是基於原型鏈的編程語言,全部的方法都是經過原型鏈進行共享的。編程
function Bar(x) {
this.x = x;
}
Bar.prototype.getX = function getX() {
return this.x;
};
const foo = new Bar(true);
複製代碼
在js中原型對象就是一個普通的js對象,由於原型對象就是一個普通的js對象,因此原型對象有一個屬於本身的shape
對象,這個shape比較特殊,原型對象的shape
對象沒法共享.瀏覽器
當咱們建立一個對象的實例的時候在內存中會發生什麼咱們已經知道了,那當咱們須要使用getX
方法的時候會發生什麼呢緩存
getX
方法,沒有包含getX
方法。Bar.prototype
,檢查他的的shape,有getX
方法。 也就是一個簡單的讀取須要進行1+2N(N表示找到方法須要的原型鏈的個數)次查找,1次本身自己的shape,不存在找到原型,而後在檢查原型的shape。
const anchor = document.createElement('a');
DOM有6層的原型鏈。Element.prototype
上才能找到,也就是說根據前面的1+2N公式,須要7次的查找。由於DOM操做在web上是很是常見的操做,那麼這樣的查找是很是的不高效的。
回到前面的例子foo.getX
,若是咱們能把原型的查找的和方法的查找包裹在一塊兒作就行了。js引擎經過把原型鏈的指針從實例自己轉移到他的shape上實現了這一操做性能優化
以前提到,prototype的shape沒法和別的對象共享,就是由於每一個prototype的shape有一個特殊的ValidityCell字段。這個ValidityCell字段標識了是否有人修改了原型對象。同時爲了讓查找更快js引擎也加入了inline cache。前端性能
可是若是你修改了原型對象,好比delete Bar.prototype.getX
在原型對象上刪掉了getX方法。這個時候原型的shape對象會被從新分配,ValidityCell也會變成false,當下一次使用inline cache的時候也通不過檢查從而得不到offset的緩存了,這會影響性能。編程語言
回到以前那個DOM元素的例子,任何對原型鏈的修改都會將ValidityCell設置爲false,若是你修改了Object.prototype
,不僅有Object.prototype
的shape的ValidityCell
變成了false,全部「繼承」他的原型對象的ValidityCell
所有都變成了false。也就是說修改Object.prototype
了之後會對程序的性能形成很大的影響,由於全部的對象最終都"繼承"Object
。
以前一章咱們介紹了shape和ICs,這一張咱們又介紹了prototype的shape對象,基於這些知識咱們知道了一個技巧能夠提升咱們的性能:不要修改原型對象,若是你真的須要修改原型對象,請在其餘代碼執行以前就將原型對象修改好。