浏览器缓存(Browser Caching)是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据,整体 上加速网页展示给用户。
浏览器端缓存的机制种类较多,总体归纳为九种,这里详细分析下这九种缓存机制的原理和使用场景。打开浏览器的调试模式 ->resources左侧就有浏览器的8种缓存机制。
一、http缓存
http缓存是基于HTTP协议的浏览器文件级缓存机制。即针对文件的重复请求情况下,浏览器可以根据协议头判断从服务器端请求文件还是从本地读取文 件,chrome控制台下的Frames即展示的是浏览器的http文件级缓存。以下是浏览器缓存的整个机制流程。主要是针对重复的http请求,在有缓 存的情况下判断过程主要分3步:
- 判断expires,如果未过期,直接读取http缓存文件,不发http请求,否则进入下一步
- 判断是否含有etag,有则带上if-none-match发送请求,未修改返回304,修改返回200,否则进入下一步
- 判断是否含有last-modified,有则带上if-modified-since发送请求,无效返回200,有效返回304,否则直接向服务器请求
如果通过etag和last-modified判断,即使返回304有至少有一次http请求,只不过返回的是304的返回内容,而不是文件内容。所以合理设计实现expires参数可以减少较多的浏览器请求。
二、websql
websql这种方式只有较新的chrome浏览器支持,并以一个独立规范形式出现,主要有以下特点
- Web Sql 数据库API 实际上不是HTML5规范的组成部分;
- 在HTML5之前就已经存在了,是单独的规范;
- 它是将数据以数据库的形式存储在客户端,根据需求去读取;
- 跟Storage的区别是: Storage和Cookie都是以键值对的形式存在的;
- Web Sql 更方便于检索,允许sql语句查询;
- 让浏览器实现小型数据库存储功能;
- 这个数据库是集成在浏览器里面的,目前主流浏览器基本都已支持;
websql API主要包含三个核心方法:
- openDatabase : 这个方法使用现有数据库或创建新数据库创建数据库对象。
- transaction : 这个方法允许我们根据情况控制事务提交或回滚。
- executeSql : 这个方法用于执行真实的SQL查询。
openDatabase方法可以打开已经存在的数据库,不存在则创建
var db = openDatabase('mydatabase', '2.0', my db', 2 * 1024);
openDatabasek中五个参数分别为:数据库名、版本号、描述、数据库大小、创建回调。创建回调没有也可以创建数据库。
database.transaction() 函数用来查询,executeSql()用于执行sql语句
例如在mydatabase数据库中创建表t1:
var db = openDatabase(' mydatabase ', '1.0', 'Test DB', 2 * 1024 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS t1 (id unique, log)'); });
插入操作
var db = openDatabase('mydatabase', '2.0', my db', 2 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS t1 (id unique, log)'); tx.executeSql('INSERT INTO t1 (id, log) VALUES (1, "foobar")'); tx.executeSql('INSERT INTO t1 (id, log) VALUES (2, "logmsg")'); });
在插入新记录时,我们还可以传递动态值,如:
var db = openDatabase(' mydatabase ', '2.0', 'my db', 2 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS t1 (id unique, log)'); tx.executeSql('INSERT INTO t1 (id,log) VALUES (?, ?'), [e_id, e_log]; //e_id和e_log是外部变量 });
读操作,如果要读取已经存在的记录,我们使用一个回调捕获结果:
var db = openDatabase(mydatabase, '2.0', 'my db', 2*1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS t1 (id unique, log)'); tx.executeSql('INSERT INTO t1 (id, log) VALUES (1, "foobar")'); tx.executeSql('INSERT INTO t1 (id, log) VALUES (2, "logmsg")'); }); db.transaction(function (tx) { tx.executeSql('SELECT * FROM t1, [], function (tx, results) { var len = results.rows.length, i; msg = "<p>Found rows: " + len + "</p>"; document.querySelector('#status').innerHTML += msg; for (i = 0; i < len; i++){ alert(results.rows.item(i).log ); } }, null); });
三、indexDB
IndexedDB 是一个为了能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索的 API。虽然 DOM 存储 对于存储少量数据是非常有用的,但是它对大量结构化数据的存储就显得力不从心了。IndexedDB 则提供了这样的一个解决方案。 IndexedDB 分别为同步和异步访问提供了单独的 API 。同步 API 本来是要用于仅供 Web Workers 内部使用,但是还没有被任何浏览器所实现。异步 API 在 Web Workers 内部和外部都可以使用,另外浏览器可能对indexDB有50M大小的限制,一般用户保存大量用户数据并要求数据之间有搜索需要的场景。
- 异步API
异步 API 方法调用完后会立即返回,而不会阻塞调用线程。要异步访问数据库,要调用 window 对象 indexedDB 属性的 open() 方法。该方法返回一个 IDBRequest 对象 (IDBOpenDBRequest);异步操作通过在 IDBRequest 对象上触发事件来和调用程序进行通信。
- IDBFactory 提供了对数据库的访问。这是由全局对象 indexedDB 实现的接口,因而也是该 API 的入口。 - IDBCursor 遍历对象存储空间和索引。 - IDBCursorWithValue 遍历对象存储空间和索引并返回游标的当前值。 - IDBDatabase 表示到数据库的连接。只能通过这个连接来拿到一个数据库事务。 - IDBEnvironment 提供了到客户端数据库的访问。它由 window 对象实现。 - IDBIndex 提供了到索引元数据的访问。 - IDBKeyRange 定义键的范围。 - IDBObjectStore 表示一个对象存储空间。 - IDBOpenDBRequest 表示一个打开数据库的请求。 -IDBRequest 提供了到数据库异步请求结果和数据库的访问。这也是在你调用一个异步方法时所得到的。 - IDBTransaction 表示一个事务。你在数据库上创建一个事务,指定它的范围(例如你希望访问哪一个对象存储空间),并确定你希望的访问类型(只读或写入)。 - IDBVersionChangeEvent 表明数据库的版本号已经改变。
- 同步API
规范里面还定义了 API 的同步版本。同步 API 还没有在任何浏览器中得以实现。它原本是要和webWork 一起使用的。
http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/init/all.jshttp://caniuse.com/#feat=indexeddb
四、cookie
Cookie(或者Cookies),指一般网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。 cookie一般通过http请求中在头部一起发送到服务器端。一条cookie记录主要由键、值、域、过期时间、大小组成,一般用户保存用户的认证信 息。cookie最大长度和域名个数由不同浏览器决定,具体如下:
IE7以上 | 50个 | 4095B |
Firefox | 50个 | 4097B |
Opera | 30个 | 4096B |
Safari/WebKit | 无限制 | 4097B |
不同域名之间的cookie信息是独立的,如果需要设置共享可以在服务器端设置cookie的path和domain来实现共享。浏览器端也可以通过document.cookie来获取cookie,并通过js浏览器端也可以方便地读取/设置cookie的值。
https://github.com/component/cookie/blob/master/index.js
五、localstorage
localStorage是html5的一种新的本地缓存方案,目前用的比较多,一般用来存储ajax返回的数据,加快下次页面打开时的渲染速度。
IE8以上 | 5M |
Firefox 8以上 | 5.24M |
Opera | 2M |
Safari/WebKit | 2.6M |
//localStorage核心API: localStorage.setItem(key, value) //设置记录 localStorage.getItem(key) //获取记录 localStorage.removeItem(key) //删除该域名下单条记录 localStorage.clear() //删除该域名下所有记录
值得注意的是,localstorage大小有限制,不适合存放过多的数据,如果数据存放超过最大限制会报错,并移除最先保存的数据。
https://github.com/machao/localStorage
六、sessionstorage
sessionStorage和localstorage类似,但是浏览器关闭则会全部删除,api和localstorage相同,实际项目中使用较少。
七、application cache
application cahce是将大部分图片资源、js、css等静态资源放在manifest文件配置中。当页面打开时通过manifest文件来读取本地文件或是请求服 务器文件。 离线访问对基于网络的应用而言越来越重要。虽然所有浏览器都有缓存机制,但它们并不可靠,也不一定总能起到预期的作用。HTML5 使用ApplicationCache 接口可以解决由离线带来的部分难题。前提是你需要访问的web页面至少被在线访问过一次。 使用缓存接口可为您的应用带来以下三个优势:
- 离线浏览 – 用户可在离线时浏览您的完整网站
- 速度 – 缓存资源为本地资源,因此加载速度较快。
- 服务器负载更少 – 浏览器只会从发生了更改的服务器下载资源。
一个简单的离线页面主要包含以下几个部分:
index.html
<html manifest="clock.manifest"> <head> <title>AppCache Test</title> <link rel="stylesheet" href="clock.css"> <script src="clock.js"></script> </head> <body> <p><output id="clock"></output></p> <div id="log"></div> </body> </html>
clock.manifest
CACHE MANIFEST #VERSION 1.0 CACHE: clock.css clock.js
clock.js和clock.css为独立的另外文件。 另外需要注意的是更新缓存。在程序中,你可以通过window.applicationCache 对象来访问浏览器的app cache。你可以查看 status 属性来获取cache的当前状态:
var appCache = window.applicationCache; switch (appCache.status) { case appCache.UNCACHED: // UNCACHED == 0 return 'UNCACHED'; break; case appCache.IDLE: // IDLE == 1 return 'IDLE'; break; case appCache.CHECKING: // CHECKING == 2 return 'CHECKING'; break; case appCache.DOWNLOADING: // DOWNLOADING == 3 return 'DOWNLOADING'; break; case appCache.UPDATEREADY: // UPDATEREADY == 4 return 'UPDATEREADY'; break; case appCache.OBSOLETE: // OBSOLETE == 5 return 'OBSOLETE'; break; default: return 'UKNOWN CACHE STATUS'; break; };
为了通过编程更新cache,首先调用 applicationCache.update()。这将会试图更新用户的 cache(要求manifest文件已经改变)。最后,当 applicationCache.status 处于 UPDATEREADY 状态时, 调用applicationCache.swapCache(),旧的cache就会被置换成新的。
var appCache = window.applicationCache; appCache.update(); // Attempt to update the user’s cache. … if (appCache.status == window.applicationCache.UPDATEREADY) { appCache.swapCache(); // The fetch was successful, swap in the new cache. }
这里是通过更新menifest文件来控制其它文件更新的。
八、cacheStorage
CacheStorage是在ServiceWorker的规范中定义的。CacheStorage 可以保存每个serverWorker申明的cache对象,cacheStorage有open、match、has、delete、keys五个核心 方法,可以对cache对象的不同匹配进行不同的响应。
cacheStorage.has() 如果包含cache对象,则返回一个promise对象。 cacheStorage.open() 打开一个cache对象,则返回一个promise对象。 cacheStorage.delete() 删除cache对象,成功则返回一个promise对象,否则返回false。 cacheStorage.keys() 含有keys中字符串的任意一个,则返回一个promise对象。 cacheStorage.delete() 匹配key中含有该字符串的cache对象,返回一个promise对象。
caches.has('v1').then(function() { caches.open('v1').then(function(cache) { return cache.addAll(myAssets); }); }).catch(function() { someCacheSetupfunction(); });;
var response; var cachedResponse = caches.match(event.request).catch(function() { return fetch(event.request); }).then(function(r) { response = r; caches.open('v1').then(function(cache) { cache.put(event.request, response); }); return response.clone(); }).catch(function() { return caches.match('/sw-test/gallery/myLittleVader.jpg'); });
then.addEventListener('activate', function(event) { var cacheWhitelist = ['v2']; event.waitUntil( caches.keys().then(function(keyList) { return Promise.all(keyList.map(function(key) { if (cacheWhitelist.indexOf(key) === -1) { return caches.delete(keyList[i]); } }); }) ); });
https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage
九、flash缓存
这种方式基本不用,这一方法主要基于flash有读写浏览器端本地目录的功能,同时也可以向js提供调用的api,则页面可以通过js调用flash去读写特定的磁盘目录,达到本地数据缓存的目的。
注释PS
- Web Storage / Web SQL Database / Indexed Database 的数据都存储在浏览器对应的用户配置文件目录(user profile directory)下,以 Windows 7 为例,Chrome 的数据存储在”C:\Users\your-account-name\AppData\Local\Google\Chrome\User Data\Default\”下,而 Firefox 的数据存储在”C:\Users\your-account-name\AppData\Local\Mozilla\Firefox\Profiles \”目录下。
- cookie文件存储于documents and settings\userName\cookie\文件夹下。通常的命名格式为:userName@domain.txt。
- 较多的缓存机制目前主流浏览器并不兼容,不过可以使用polyfill的方法来处理
浏览器涉及的缓存方式主要包含这些,具体结合自己的业务场景进行选择使用
http://www.techug.com/browser-cache-methods
相关推荐
WebAssembly是一种新型的字节码格式,它被设计为一种安全、快速、平台无关的编译目标,能够使得开发人员使用诸如C、C++、Rust等编程语言编写代码,并将其编译为WebAssembly字节码,这样可以在浏览器端运行。...
2. **基于AJAX技术的浏览器缓存**:利用客户端浏览器的缓存机制,减少数据传输量,提高Web应用的响应速度。 通过以上介绍可以看出,缓存技术在Web开发和移动开发中扮演着极其重要的角色,合理地设计和使用缓存可以...
一种常见的方式是使用第三方库,如Android的Glide或Picasso,它们能够高效地加载网络或本地存储的图片,并且支持缓存策略,优化用户体验。 二、图片缩略图生成 为了快速显示图片列表,应用通常会生成图片的缩略图...
### Python爬虫DNS解析缓存方法实例分析 #### 前言 在现代网络爬虫技术中,提高爬取效率和降低服务器负载是一项至关重要的任务。对于大型爬虫项目而言,即使是很小的时间延迟也可能导致整体性能大幅下降。其中,...
例如,使用事件委托来减少内存占用,通过缓存DOM选择结果提高效率,以及防止XSS(Cross-Site Scripting)和CSRF(Cross-Site Request Forgery)等攻击。 总的来说,"基于浏览器的客户端编程开发综合案例"将涵盖HTML...
3. InPrivate浏览:这是一种隐私浏览模式,不保存浏览历史、cookies和缓存,让用户实现无痕浏览。用户可以通过安全菜单开启InPrivate浏览。 4. InPrivate筛选:此功能旨在防止网站内容提供商收集用户访问站点的信息...
### 如何清除垃圾文件和缓存的关键知识点 #### 一、理解垃圾文件与缓存的重要性 在日常使用计算机的过程中,由于频繁的操作与网络活动,电脑内部会产生大量的垃圾文件和缓存数据。这些文件不仅占用宝贵的硬盘空间,...
以下将详细介绍ASP.NET中实现用户状态保持的九种常见方法。 1. **视图状态(ViewState)**:默认情况下,ASP.NET页面会自动使用ViewState来存储控件的状态信息。ViewState数据被编码并嵌入到HTML页面中,然后在回发时...
### Windows 8系统免受病毒侵扰的九种方法 随着信息技术的发展,计算机病毒和恶意软件也变得越来越复杂,对用户的计算机系统构成了严重威胁。为了帮助Windows 8用户更好地保护自己的计算机不受病毒侵扰,本文将详细...
百游网页游戏浏览器(简称百游浏览器)由九百游团队耗时半年倾力打造,是一款真正站在玩家角度而设计的网页游戏专用浏览器,拥有游戏变速(加速,或者减速),小号多开,一键隐藏,定时提醒,按键精灵,自动喊话,...
新分页页面中显示了最近九个造访过网站的缩图,以及最常搜索的网站、最近的书签和最近关闭的分页。 多功能网址列(Omnibox) 在每个标签页的上方是被称作“Omnibox”的网址列,是根据Opera上的网址列而来。...
本文将针对这一现象,详细介绍导致QQ空间无法打开的原因,并提供九种常见有效的解决方案。 #### 原因分析: 1. **网络问题**:可能是由于网络连接不稳定或速度过慢导致。 2. **浏览器兼容性问题**:不同浏览器对...
- 合理使用浏览器缓存,减少不必要的资源加载。 - 限制JavaScript和AJAX的使用,避免页面渲染延迟。 #### 九、错误的缓存策略导致过度的垃圾收集 不当的缓存策略可能导致缓存数据的频繁更新,从而增加垃圾收集的...
"九宫格"布局是一种常见的多图展示方式,它由9个等大的正方形组成。在Android中,我们可以使用GridView或者RecyclerView配合GridLayoutManager来实现这一效果。每个单元格是一个ImageView,通过设置适配器将Bitmap...
前后端分离是一种现代Web开发模式,它将应用程序的逻辑分为两个独立的部分:前端(客户端)和后端(服务器端)。前端负责用户界面和用户体验,而后端负责业务逻辑和数据管理。通过API接口,前端向后端发送请求获取...
每种方法都有其独特的功能和适用场景: - GET适用于只读操作。 - POST用于创建新资源或提交数据。 - PUT用于更新资源,而PATCH用于部分更新资源。 - DELETE用于删除资源。 - HEAD和OPTIONS则分别用于获取资源的元...
在UI设计中,九宫格是一种常见的布局方式,用于展示多个元素。在Android中,可以使用`GridLayout`或者`GridLayoutManager`(配合`RecyclerView`)来实现。`GridLayout`是一个基本的视图组,允许子视图在行和列中排列...