重溫localStorage的表現
現在幾週內從 localStorage
周圍的大量手環中移除了性能 在瀏覽器方面,我了解了更多關於 Mozilla 為何存在如此擔憂的信息(這促使 Chris 撰寫了他的博文
1
)。這篇文章遭到了質疑,因為它缺少兩個關鍵部分:數字和比較。斷言是 localStorage
速度很慢,但是沒有數據可以備份。
想要深究,我
2
和約翰·奧爾索普
3
寫博客文章試圖提供圍繞 localStorage
的數字 . John 的帖子專注於量化執行單次讀取和單次寫入所需的時間,這為我們提供了這些操作的良好初始數字。我的帖子側重於比較 localStorage
從 JavaScript 讀取和寫入 cookie 讀取和寫入。我的理論是 cookie 是 localStorage
的最接近的近似 由於它的內容存儲在磁盤上並由指向同一來源的所有選項卡共享。約翰和我最後都說 localStorage
無論是作為總評分還是與 cookie 相比,都不會對性能產生明顯的不良影響。
更多詳情
在那之後,我開始與來自 Mozilla 的 Jonas Sicking 進行對話,他實際上在 localStorage
工作 Firefox 的實現等具有獨特的視角。根據 John 和 I 的數據,他從存在性能問題的位置開始,而我從沒有性能問題的位置開始。Jonas 指出了一個我不知道的關鍵信息:性能問題是't with individual reads and writes, it's with the initial read into memory.
Firefox 首先從 localStorage
讀取所有數據 進入內存作為頁面的來源。一旦數據在內存中,讀取和寫入應該相對較快(儘管它們看起來仍然比讀取和寫入原生 JavaScript 對象慢——不知道為什麼),所以我們對讀取和寫入的測量並不能捕捉到完整的畫面. Jonas 的斷言是從 localStorage
讀取數據 頁面加載是問題。
正如 Jonas 一直告訴我的(最後它卡住了),localStorage
的真正問題 是它是一個同步 API,這使得實現者在有限數量的選項之間做出決定。一種選擇是在頁面加載時加載所有數據,但這會降低初始頁面加載速度,因為 JavaScript 使用 localStorage
直到 localStorage
的數據才能執行 已完全閱讀。這意味著 localStorage
中有大量數據 實際上可能會增加頁面加載時間,因為 JavaScript 在執行前需要等待。
另一種選擇也好不了多少。如果你要等到第一次 localStorage
使用時,最初從磁盤讀取數據時將需要完全(阻塞)停止。再一次,如果磁盤上有大量數據,這可能會很明顯。更重要的是,您可能會爭辯說調用 localStorage.getItem()
的延遲 是出乎意料的,因為假設您已經在內存中工作,因此操作應該很快。這就是 Firefox 在頁面加載時加載數據的原因。
實際上,這和 cookie 是一樣的問題。 Cookies 存儲在磁盤上,並在頁面加載時讀入內存。區別在於數據的大小。 Cookie 的大小仍然相當有限(大約 4KB),其中 localStorage
很大(5MB)。當然,從文件系統中讀取 5MB 的文件會比通過 Internet 下載要快,但誰能說會不會顯著影響頁面加載時間呢?
基準測試?
我嘗試運行一些基準測試,但遇到了技術限制:沒有人確定我們當前的測試工具是否準確地採用了初始 localStorage
考慮到。沒有這些信息,很難知道 localStorage
是否 實際上是初始頁面加載的性能問題。這絕對不是事後讀寫的性能問題(儘管如前所述,這並非沒有成本)。
新的 API?
調用創建新 API 來替換 localStorage
看起來有點不成熟,但基本上圍繞著三個主要思想:
- 瀏覽器不需要在頁面加載時從磁盤讀取大量數據。
- 從磁盤讀取應該是異步的,並且不會阻塞 UI 線程。
- 開發人員應該能夠指示何時應該進行讀取。
這導致 Jonas 在 Chris 的原始帖子中提出了幾種替代 API。我最喜歡的是這個:
getBetterLocalStorage(function(storage) {
x = storage.foo;
storage.bar = calculateStuff(y);
storage.baz++;
});
忽略名稱,getBetterLocalStorage()
函數向瀏覽器發出信號,是時候將所有內容讀入內存了,所以 storage
對象可以用作任何其他對象。一旦回調函數完成執行,更改將被寫回磁盤。雖然我還沒準備好扔掉 localStorage
完全,我喜歡這個 API 的方向。事實上,它緊跟我提出的改進 localStorage
的建議 帶有到期日期和加密。
4
結論
是否localStorage
是頁面加載的性能問題仍然是一個問題。在我們從瀏覽器中獲得一些好的基準之前,很難確定這是否是一個真正的問題。不幸的是,這可能必須來自瀏覽器開發人員,他們可以查看代碼並確定 localStorage
已經算了,如果沒有,如何衡量。
同時,IndexedDB 絕對是不是 localStorage
的合適替代品 在幾乎所有情況下。正如 Jonas 所指出的,可以使用 IndexedDB 來創建類似於他提出的解決方案。但是,寫出來仍然有點開銷。我的建議:不要太擔心 localStorage
現在……但也不要在其中存儲 5MB 的數據,以防萬一。
參考
- Chris Heilmann 的 localStorage 沒有簡單的解決方案
- 為我的 localStorage 辯護
- localStorage,John Allsopp 可能沒有那麼有害
- 邁向更安全的客戶端數據存儲