打開DevTools先後,對象的打印有什麼區別?

chrome-devtools

前幾天,羣裏有個朋友問了一個頗有意思的問題:前端

function Person (myName, myAge) {
    this.name = myName;
    this.age = myAge;
}
Person.prototype = {
    say:function () {
        console. log(" prototype中的輸出");
    }
}
let person = new Person("John" ,12);
console.log(Person.prototype);
console.log(Person.prototype.constructor);
console.log(person.__proto__);

就這段代碼而言,第一次運行後打開 Chrome 的 DevTools,會發現打印出來的結果是:git

1

而若是在此基礎上刷新瀏覽器,會發現打印的結果變成了這樣:github

2

這確實是個很不起眼可是頗有意思的問題 —— 爲何 Chrome 沒有在第一次的時候就直接打印 {say:f},而是像 console.dir 那樣打印出一個不具有對象屬性預覽的 Objectchrome

也許這樣作是有什麼好處,不過先讓咱們排除一些沒必要要的干擾因素。第一個是:是否和原型相關?雖然羣友給的案例代碼涉及到了原型,但其實和原型沒有任何關係。我嘗試將代碼改成簡單的 console.log({a:1})後,依然會發生一樣的狀況 —— 即第一次只打印 Object,刷新以後纔打印 {a:1}。第二個是:是否和瀏覽器相關?目前爲止運行代碼的環境都是 Chrome,在其它瀏覽器下打印結果會是怎麼樣的呢?api

在 FireFox 下,發現刷新先後都是直接打印對象屬性預覽:瀏覽器

3

在 Edge 下,發現刷新先後存在相似 Chrome 的差別:性能優化

4

那麼,Chrome 這樣作的目的是什麼呢?帶着這個疑問,我先是來到 StackOverflow 提問,不過並無獲得滿意的回答。雖然我極力提醒回答者這道題的困惑之處在於刷新先後打印結果的差別,但他仍是「跑題」了......不過,他的回答中有一個地方引發了個人注意,就是「 a very slow operation」。這確實是給出了一個思考的方向:Chrome 在一開始沒有直接打印對象的預覽,會不會是由於這是一個耗時操做呢?因此,也許這是一個性能相關的問題?chrome-devtools

接着我嘗試到知乎提問,最終很驚喜地獲得了大佬的回覆 —— 這確實是一個爲了性能優化而採起的行爲:性能

點進回答裏提供的連接看一下,有更加詳細的解釋:學習

簡單地說,這個行爲的差別不是因爲刷新瀏覽器致使的,而是因爲打開 DevTools 致使的。咱們在第一次運行代碼以後,對象就打印出來了,但此時尚未打開 DevTools,因此這部分打印的內容是暫時放在內存的緩衝區(buffer)中的。並且對一個普通的用戶來講,他極可能永遠也不須要打開 DevTools,在這種狀況下若仍然選擇呈現預覽對象,會對內存和 CPU 有必定的要求,考慮到這一點,在設計上會讓此次的打印不呈現預覽對象。

對咱們來講,若是這一次打開 DevTools,咱們看到的就只會是 Object。可是,若是在打開以後再次刷新,那麼咱們看到的就是所指望的 {a:1}。所以,這種行爲差別是在「保留信息」和「減小內存佔用」之間所作的權衡(trade-off)。

咱們還能夠進一步驗證一下:隨便打開一個頁面,而且打開控制檯,而後把代碼文件直接拖到該頁面運行:

這時候會發現,控制檯裏是直接打印出 {a:1} 這樣的預覽對象的,這是由於在打印以前咱們就提早把 DevTools 打開了,這時候打印的對象並不會放在緩衝區中。

此外,回答裏還提到一個叫作 ObjectPreview 的東西,它其實就是上面所講的可以呈現對象屬性預覽的東西,其實是 cdp( ChromeDevToolsProtocol ) 協議的一個 api。cdp 協議容許咱們檢測和調試 Chrome 瀏覽器,咱們所熟知的 ChromeDevTools 就是遵循這個協議的。從這點來講,當咱們打開 DevTools 時,其實就已經在使用 cdp 協議了。

FireFox 可能認爲這個優化對性能提高並非很明顯,因此在設計上選擇的是直接打印 ObjectPreview。固然不排除還有其它方面的考慮,具體的我就沒有再深挖啦,畢竟咱也不是開發瀏覽器的,瞭解一下,知道有這麼一個東西就行了。關鍵的是,此次的疑惑獲得了一個比較官方而準確的解答,我認爲這纔是最大的收穫。

參考:

https://www.zhihu.com/questio...

https://twitter.com/ziyunfei/...

https://chromedevtools.github...

交流

目前專一於前端領域和交互設計領域的學習,熱愛分享和交流。感興趣的朋友能夠關注公衆號,一塊兒學習和進步。

Snipaste_2020-07-09_16-09-39.png

相關文章
相關標籤/搜索