Web开发:localStorage与缓存的HTTP

时间:2011-08-21 06:07:43

标签: javascript ajax html5 local-storage

假设我有一个Web服务器响应带有.json文件的GET。对该GET的响应指定浏览器将响应缓存5年。

我们还说我有一个网页,当页面加载时,它会对JSON数据发出GET请求。当响应返回时,JSON数据将放入localStorage

此时,如果我想再次检索该JSON数据,这将更快:

  1. localStorage
  2. 获取
  3. 执行另一个Ajax GET请求(浏览器实际上不会发出请求 - 它将访问浏览器缓存)
  4. 您能用自动化测试或示例证明吗?

    为什么你的回答是正确的?

3 个答案:

答案 0 :(得分:9)

我认为你问的是错误的问题。哪个更快在活动会话期间基本上是无关紧要的,因为两者都存储在本地,并且本地查找几乎是即时的(与远程查找相比)。 (需要注意的是:并非所有浏览器都依赖于缓存标头,但通常它更倾向于过度缓存,而不是缓存不足。)

但是,您的示例情况是假设浏览器的缓存永远不会被清除。这通常是错误的:用户不仅可以随时清除缓存(或将其设置为自动清除),但浏览器本身可能会决定随意删除网站的缓存数据(通常取决于空间)。

相反,您应该考虑数据的寿命,以及用户再次寻找它的频率。

如果这些信息是他们偶尔只能访问的信息,那么您应该依赖浏览器的内置缓存机制。这允许浏览器在不再需要时将其删除。

但是,如果数据是定期加载的,或者每次访问网站时都需要,那么您应该使用localStorage。本地存储使用缓存自动清除,实际上通常只有在用户清除该网站的cookie时才会清空。这使得信息可以保留更长时间,即使网站没有经常访问以保持缓存刷新。但是你现在突然要负责维护这个信息数据库。

最后,最重要的问题是:作为一名开发人员,开发一个更复杂localStorage的解决方案是否值得进行成本效益交易?换句话说,您是否会看到最终用户缓存1-2s查找的足够好处,或者您是在谈论大量信息,用户将看到30s +增益。

  

作为一个例子,对于我开发的大型复杂Web应用程序,我使用localStorage来存储大量的JS库。当重新访问该站点时,只需从本地副本解析它们(在验证哈希之后)。该解决方案允许各种浏览器看到启动时间的大幅减少,即使缓存已被清除。 (我不是说这是一个很好的用途,但它当时有效。)

答案 1 :(得分:3)

两个消息来源都声称localStorage能够加速浏览器缓存。

这是我从localStorage加载JavaScript文件的看法。代码很小,您可以在我的Github项目https://github.com/webpgr/cached-webpgr.js中查看它,或者使用下面完整示例中的代码。

完整的图书馆:

function _cacheScript(c,d,e){var a=new XMLHttpRequest;a.onreadystatechange=function(){4==a.readyState&&(200==a.status?localStorage.setItem(c,JSON.stringify({content:a.responseText,version:d})):console.warn("error loading "+e))};a.open("GET",e,!0);a.send()}function _loadScript(c,d,e,a){var b=document.createElement("script");b.readyState?b.onreadystatechange=function(){if("loaded"==b.readyState||"complete"==b.readyState)b.onreadystatechange=null,_cacheScript(d,e,c),a&&a()}:b.onload=function(){_cacheScript(d,e,c);a&&a()};b.setAttribute("src",c);document.getElementsByTagName("head")[0].appendChild(b)}function _injectScript(c,d,e,a){var b=document.createElement("script");b.type="text/javascript";c=JSON.parse(c);var f=document.createTextNode(c.content);b.appendChild(f);document.getElementsByTagName("head")[0].appendChild(b);c.version!=e&&localStorage.removeItem(d);a&&a()}function requireScript(c,d,e,a){var b=localStorage.getItem(c);null==b?_loadScript(e,c,d,a):_injectScript(b,c,d,a)};

调用库

requireScript('jquery', '1.11.2', 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js', function(){
    requireScript('examplejs', '0.0.3', 'example.js');
});

答案 2 :(得分:-3)

如果在现代UAs(浏览器)中这两种方法中的任何一种都应该可忽略不计,那么差异很大。

为什么我的回答是正确的你问?因为我实现了这两种机制。