DBMNG数据库管理与应用

所谓独创的能力,就是经过深思的模仿。
当前位置:首页 > 经验分享 > HTML5

深入理解HTML5离线缓存机制

TML5提供了一种离线应用缓存机制,使得网页应用可以离线使用,这种机制在移动端浏览器上支持度非常广,所有版本的android和ios浏览器都能很好的支持。我们可以放心的使用该特性来加速移动端页面的访问速度。

开启离线缓存的步骤也非常简单:

(1) 准备缓存清单文件(menifest text/cache-manifest),用于描述页面需要缓存的资源列表

(2) 在需要离线使用的页面中添加menifest属性,用于指定缓存清单文件的路径

让我们首先理解浏览器实现离线缓存的详细步骤,然后探讨使用离线缓存加速移动端网页访问速度的方案。

1. 下载/更新缓存的详细步骤

(1)当浏览器访问一个包含 manifest 特性的文档时,如果应用缓存不存在,浏览器会加载文档,然后获取所有在清单文件中列出的文件,生成应用缓存的第一个版本。

(2)对该文档的后续访问会使浏览器直接从应用缓存(而不是服务器)中加载文档与其他在清单文件中列出的资源。此外,浏览器还会向 window.applicationCache 对象发送一个 checking 事件,在遵循合适的 HTTP 缓存规则前提下,获取清单文件。

(3)如果当前缓存的清单副本是最新的,浏览器将向 applicationCache 对象发送一个 noupdate 事件,到此,更新过程结束。注意,如果你在服务器修改了任何缓存资源,同时也应该修改清单文件,这样浏览器才能知道它需要重新获取资源。

(4)如果清单文件已经改变,文件中列出的所有文件—也包括通过调用 applicationCache.add() 方法添加到缓存中的那些文件—会被获取并放到一个临时缓存中,遵循适当的 HTTP 缓存规则。对于每个加入到临时缓存中的文件,浏览器会向 applicationCache 对象发送一个 progress 事件。如果出现任何错误,浏览器会发送一个 error 事件,并暂停更新。

(5)一旦所有文件都获取成功,它们会自动移送到真正的离线缓存中,并向 applicationCache 对象发送一个 cached 事件。鉴于文档早已经被从缓存加载到浏览器中,所以更新后的文档不会重新渲染,直到页面重新加载(可以手动或通过程序).

以上只是一些详细步骤,具体也有一些值得注意的细节,比如menifest文件中列出的资源url必须和menifest本身使用同样的网络协议,如果menifest文件使用的是http协议,则列表中https协议的文件就会被忽略。总之,每当在使用Application Cache的过程中遇到奇怪的问题时,随时查阅W3C标准文档。

2.离线缓存事件流

浏览器在解析HTML文档的过程中,遇到HTML标记的menifest属性时,就立即在后台开启一个新的进程下载需要离线缓存的资源。在下载离线缓存的过程中,会在ApplicationCache上触发一系列事件。

离线缓存事件流

关于离线缓存中要触发的事件,有一个很有趣的特性。从离线缓存W3C标准中,我们经常看到如下描述:'queue a post-load task to fire a simple event named (checking|noupdate|downloading)',每一个HTML文档都有一个离线缓存事件队列(queue),离线缓存下载过程中的事件都存放在这个队列里,用于在文档的onload事件触发后执行。也就是说,所有的ApplicationCache事件都在html的onload事件触发后才触发。

3.使用离线缓存加速移动端网页开发

上文提到过,Application Cache在移动端支持的很好,几乎所有的android浏览器和ios浏览器都能很好的支持。事实上使用Application Cache加速移动端网页访问速度是行业类普遍采用的优化方案,在包括新浪微博和QQ浏览器等大型产品中都有非常广泛的使用。但是在使用离线缓存时,我们需要留意一些问题。

(1).二次更新的问题

我们知道每次使用离线应用时,在有网络连接的情况下,浏览器都会逐字节的检查menifest文件是否有更新,而当menifest文件有更新时,就会重新下载menifest文件中列出的所有资源,资源下载成功后会触发updateready事件。这时离线应用本身并不会立即更新,而会在下次访问时才更新,这就是我们所说的二次更新。我们在开发web程序时,一般都是前端页面和后端接口同步更新,但是二次更新问题会导致页面更新不受控制,无法和后端接口同步更新,因此要做好后端接口的向前兼容,这迫使我们抛弃传统的web开发思路而采取native开发思路来管理离线应用。我们可以通过检测updateready事件,在新的缓存可用时通知用户更新。

window.addEventListener('load', function(e) {  

    window.applicationCache.addEventListener('updateready', function(e) { 

        //缓存更新完毕 

        if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {  

            //切换为最新缓存

            window.applicationCache.swapCache();  

            if (confirm('新版本已经更新完成,是否重新加载?')) {  

                window.location.reload();  

            }  

        }  

    }, false);  

}, false);  

(2).超出大小限制的问题

Application Cache的W3C标准中并没有对大小限制做出详细的描述。因此浏览器实现起来也是参差不齐,为了最大化的使用离线缓存,我们应该清楚自己业务的目标浏览器的离线缓存大小限制,使用chrome://appcache-internals/可以轻易的管理chrome浏览器的离线缓存。我们可以写一个DEMO,采用二分搜索法,不断的测试浏览器的Application Cache大小限制,直到触发相应的error事件。这个链接可以测试Application Cache的大小限制。通过监听Application的error事件来能够处理超出离线缓存大小限制的情况:

window.applicationCache.addEventListener('error',function(e){

    if(e.reason == 'quota'){

        //超出离线缓存大小限制

    }

});

离线缓存的是一套网页加速方案,超出Application Cache的大小限制后,会对我们的应用有不同的影响,具体表现就是:

首次下载缓存时超出大小,所有资源都不会缓存,而是请求网络,应用功能正常。

更新资源后超出大小,缓存不会更新,应用无法更新。

(3).webview中的问题

在标准的html5浏览器中,我们可以放心的使用Application Cache,并且不需要任何设置。但是在webview中,则可能需要显示的设置,比如android系统的webview默认是不支持Application Cache的,因此需要显示设置:

webView.getSettings().setAppCacheEnabled(true);        //默认是关闭的

webView.getSettings().setAppCacheMaxSize(1024*1024*5); //缓存大小

webView.getSettings().setAppCachePath("路径");          //缓存路径

本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by DEVSOARTECH            豫ICP备11002312号-2

豫公网安备 41010502002439号