原文地址html
做者:Nicholas Zakashtml5
在Web開發人員使用的工具中,Web Storage(dev.w3.org/html5/webst…)迅速成爲了HTML5新增的最受歡迎的功能。具體來講,localStorage提供了快速簡單的客戶端數據存儲功能,能夠跨多個會話存儲數據,這使得localStorage在世界各地Web開發人員中被廣爲應用。經過使用簡單的鍵值接口,咱們看到不少網站以各類獨特而有趣的方式應用localStorage這一技術。web
Disqus(www.disqus.com/),是一個很是流行的反饋管理系統。它使用localStorage來實時保存您正在輸入的評論。所以,即便有可怕的意外發生,你也能夠重啓瀏覽器,從出現問題以前的地方繼續。瀏覽器
谷歌(www.google.com/)和Bing(www.bing.com/)用localStorage存儲JavaScript和CSS,來改善他們的移動網站性能。緩存
在我瞭解的案例中,Google/Bing的這種方式彷佛愈來愈受人們的歡迎。部分緣由是因爲HTML5 application cache使用困難,部分緣由是該技術獲得了Steve Souders和其餘人的青睞。事實上,隨着我愈來愈多地和人們說起localStorage以及用它來存儲UI相關信息是多麼的有用,我發現更多人開始嘗試這種技術。app
我發現一個使人費解的現象,人們在使用localstorage時有一個內定不成文的假設:從localStorage讀取數據開銷不大。我曾經從其餘開發者那裏聽到傳言說遇到異常的性能問題,因此我設計了一個實驗來量化localStorage的性能特色,以肯定用它讀取數據的實際成本。jsp
2.1 基準測試工具
不久前,我建立並共享了一個簡單的基準測試,來測量從localStorage取值和從一個對象屬性取值的性能。有人基於這個測試作了改良,並開發了更可靠的版本(jsperf.com/localstorag…)。最終結果是:每一個瀏覽器中,從localStorage讀取數據比從對象屬性中讀取相同數據慢幾個數量級。到底有多慢呢?請看圖2-1所示(數字越高越好)。 性能
看了這個圖後,你可能會感到困惑,由於它彷佛沒有展現出從localStorage中讀取數據的結果。事實上它被展示出來了,你看不到它的緣由是這一數字實在過小,在圖示比例上甚至不可見。除了Safari 5能夠顯示實際的localStorage的讀取數據結果,全部其餘瀏覽器的巨大差別使得你根本不可能在這張圖上看到實際數據。當我調整y軸的值後,你才能夠看到不一樣瀏覽器中的測量結果。測試
經過改變y軸的比例,如今你能夠看到從local Storage和從對象屬性讀取數據的真實對比(見圖2-2)。能夠看出,結果仍然如此,幾乎到了滑稽的程度,這是爲何呢?
2.2 這是怎麼回事
爲了保持跨瀏覽器會話,localStorage的數據被寫入磁盤中。這意味着當你從localStorage中讀取數據時,你其實是從硬盤驅動器上讀取這些字節。讀寫硬盤開銷高昂,特別是相對於讀寫內存來講。從本質上講,這正是個人基準測試所測試的內容,即從緩存(對象屬性)讀取數據和從磁盤(localStorage)讀取數據的速度比較。
更有趣的是,localStorage按源存儲數據,這意味着,在同一時間內,瀏覽器中的多個標籤頁能夠訪問相同的localStorage數據。
這對於那些須要弄明白如何實現各標籤頁同步訪問localStorage的瀏覽器開發商來講十分頭疼。當須要從localStorage中讀取數據時,瀏覽器首先須要停下來看看是否有其餘標籤頁正在訪問同一數據區域。若是是的話,瀏覽器必須等到以前的訪問操做完成,才能夠讀取該值。
所以,與從localStorage讀取數據相關的延遲是不定的,它在很大程度上取決於在那個時間點上瀏覽器還在進行的其餘操做。
2.3 優化策略
既然從localStorage讀取數據有必定開銷,那麼這會怎樣影響你如何使用這一技術呢?在下結論以前,我運行了另外一個基準測試(http://jsperf .com/localstorage-string- size),以肯定從localStorage讀取不一樣大小數據的效果。咱們保存4種不一樣大小的字符串(100個字符、500個漢字、1000個字符和2000個字符)到localStorage中,而後把它們讀取出來。結果有點使人驚訝,在全部瀏覽器中,讀取數據量的大小不會影響讀取速度的快慢。
我測試了不少次,並懇請個人Twitter粉絲提供更多的信息(twitter.com/ slicknet/s…)。能夠確定的是,對於不一樣的瀏覽器會有些許差別,但這些差別都不大,並無實質性的不一樣。個人結論是:從單一localStorage鍵值中讀取的數據量對速度沒有影響。
我又進行了另外一個基準測試(jsperf.com/localstorag…)來檢驗個人新結論,最好儘量地減小讀取數據的次數。和此前的基準測試結果相似,在大多數瀏覽器中,讀取100個字符10次比一次讀取10 000字符慢90%左右。
鑑於此,從localStorage讀取數據的最佳策略是使用盡量少的鍵值,存儲儘量多的數據。由於讀取10個字符和讀取2000個字符所需時間大體是相同的,因此你應該嘗試把儘量多的數據保存爲一個鍵值對應的值。每次調用getItem()(或從localStorage讀取屬性)都會增長時耗,因此必定要確保每次訪問讀取數據最大化。對於任何一個變量或對象屬性,你越快將它讀取到內存,後續的全部操做也會越快。
2.4 跟進
這篇文章一經發表就引起了大量圍繞localStorage性能的討論。討論最開始出如今Mozilla 的Chris Heilmann的博客文章中,題爲「localStorage沒有簡單的解決方案」。在文章中,Chris認爲localStorage做爲一個總體存在性能問題。在不少博文討論(其中也包括個人)以後,我最終可以聯繫上Firefox負責實現localStorage的工程師Jonas Sicking。事實上,localStorage所存在的性能問題並不僅是比從對象讀取數據花費時間長一些那麼簡單。問題的關鍵是,localStorage是一個同步API,這自己就使瀏覽器實現這個API時捉襟見肘。全部的localStorage數據都存儲在磁盤文件上。這意味着,爲了讓您能夠用JavaScript訪問這些數據,瀏覽器必須先將該文件讀取到內存中。當讀取操做發生時性能問題便產生了。當第一次訪問localStorage就可能產生性能問題,但在隨後的讀取操做中瀏覽器有可能會凍結。在處理少許數據時,這可能不是一個大問題,但若是你已經達到5 MB限制時,就會有明顯的影響。Firefox採納的另外一種解決方案,是在加載頁面的同時讀取localStorage數據。這將確保以後對localStorage的訪問最快,並有可預測性。這種方法的缺點是對頁面加載時間形成不利影響。到我寫這篇文章之時,這一問題仍然沒有被解決。有人呼籲用一個全新的API來代替localStorage,其餘的人則試圖修復現有API的問題。無論發生什麼狀況,不久的未來仍會有客戶端數據存儲領域的更多研究。無論發生什麼狀況,最近一段時間內,咱們仍然須要在客戶端數據存儲方面作更多的研究。