HTML5缓存机制浅析:移动端Web加载性能优化
Indexed Database
IndexedDB也是一种数据库的存储机制,但不同于已经不再支持的Web SQL Database。IndexedDB不是传统的关系数据库,可归为NoSQL数据库。IndexedDB又类似于Dom
Storage的key-value的存储方式,但功能更强大,且存储空间更大。
IndexedDB存储数据是key-value的形式。Key是必需,且要唯一;Key可以自己定义,也可由系统自动生成。Value也是必需的,但Value非常灵活,可以是任何类型的对象。一般Value都是通过Key来存取的。
IndexedDB提供了一组API,可以进行数据存、取以及遍历。这些API都是异步的,操作的结果都是在回调中返回。
下面代码演示了IndexedDB中DB的打开(创建)、存储对象(可理解成有关系数据的“表”)的创建及数据存取、遍历基本功能。
<script type="text/javascript">
var db;
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
//浏览器是否支持IndexedDB
if (window.indexedDB) {
//打开数据库,如果没有,则创建
var openRequest = window.indexedDB.open("people_db", 1);
//DB版本设置或升级时回调
openRequest.onupgradeneeded = function(e) {
console.log("Upgrading...");
var thisDB = e.target.result;
if(!thisDB.objectStoreNames.contains("people")) {
console.log("Create Object Store: people.");
//创建存储对象,类似于关系数据库的表
thisDB.createObjectStore("people", { autoIncrement:true });
//创建存储对象, 还创建索引
//var objectStore = thisDB.createObjectStore("people",{ autoIncrement:true });
// //first arg is name of index, second is the path (col);
//objectStore.createIndex("name","name", {unique:false});
//objectStore.createIndex("email","email", {unique:true});
}
}
//DB成功打开回调
openRequest.onsuccess = function(e) {
console.log("Success!");
//保存全局的数据库对象,后面会用到
db = e.target.result;
//绑定按钮点击事件
document.querySelector("#addButton").addEventListener("click", addPerson, false);
document.querySelector("#getButton").addEventListener("click", getPerson, false);
document.querySelector("#getAllButton").addEventListener("click", getPeople, false);
document.querySelector("#getByName").addEventListener("click", getPeopleByNameIndex1, false);
}
//DB打开失败回调
openRequest.onerror = function(e) {
console.log("Error");
console.dir(e);
}
}else{
alert('Sorry! Your browser doesn't support the IndexedDB.');
}
//添加一条记录
function addPerson(e) {
var name = document.querySelector("#name").value;
var email = document.querySelector("#email").value;
console.log("About to add "+name+"/"+email);
var transaction = db.transaction(["people"],"readwrite");
var store = transaction.objectStore("people");
//Define a person
var person = {
name:name,
email:email,
created:new Date()
}
//Perform the add
var request = store.add(person);
//var request = store.put(person, 2);
request.onerror = function(e) {
console.log("Error",e.target.error.name);
//some type of error handler
}
request.onsuccess = function(e) {
console.log("Woot! Did it.");
}
}
//通过KEY查询记录
function getPerson(e) {
var key = document.querySelector("#key").value;
if(key === "" || isNaN(key)) return;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var request = store.get(Number(key));
request.onsuccess = function(e) {
var result = e.target.result;
console.dir(result);
if(result) {
var s = "<p><h2>Key "+key+"</h2></p>";
for(var field in result) {
s+= field+"="+result[field]+"<br/>";
}
document.querySelector("#status").innerHTML = s;
} else {
document.querySelector("#status").innerHTML = "<h2>No match!</h2>";
}
}
}
//获取所有记录
function getPeople(e) {
var s = "";
db.transaction(["people"], "readonly").objectStore("people").openCursor().onsuccess = function(e) {
var cursor = e.target.result;
if(cursor) {
s += "<p><h2>Key "+cursor.key+"</h2></p>";
for(var field in cursor.value) {
s+= field+"="+cursor.value[field]+"<br/>";
}
s+="</p>";
cursor.continue();
}
document.querySelector("#status2").innerHTML = s;
}
}
//通过索引查询记录
function getPeopleByNameIndex(e)
{
var name = document.querySelector("#name1").value;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var index = store.index("name");
//name is some value
var request = index.get(name);
request.onsuccess = function(e) {
var result = e.target.result;
if(result) {
var s = "<p><h2>Name "+name+"</h2><p>";
for(var field in result) {
s+= field+"="+result[field]+"<br/>";
}
s+="</p>";
} else {
document.querySelector("#status3").innerHTML = "<h2>No match!</h2>";
}
}
}
//通过索引查询记录
function getPeopleByNameIndex1(e)
{
var s = "";
var name = document.querySelector("#name1").value;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var index = store.index("name");
//name is some value
index.openCursor().onsuccess = function(e) {
var cursor = e.target.result;
if(cursor) {
s += "<p><h2>Key "+cursor.key+"</h2></p>";
for(var field in cursor.value) {
s+= field+"="+cursor.value[field]+"<br/>";
}
s+="</p>";
cursor.continue();
}
document.querySelector("#status3").innerHTML = s;
}
}
</script>
<p>添加数据<br/>
<input type="text" id="name" placeholder="Name"><br/>
<input type="email" id="email" placeholder="Email"><br/>
<button id="addButton">Add Data</button>
</p>
<p>根据Key查询数据<br/>
<input type="text" id="key" placeholder="Key"><br/>
<button id="getButton">Get Data</button>
</p>
<div id="status" name="status"></div>
<p>获取所有数据<br/>
<button id="getAllButton">Get EveryOne</button>
</p>
<div id="status2" name="status2"></div>
<p>根据索引:Name查询数据<br/>
<input type="text" id="name1" placeholder="Name"><br/>
<button id="getByName">Get ByName</button>
</p>
<div id="status3" name="status3"></div><br>
将上面的代码复制到indexed_db.html中,用Google Chrome浏览器打开,就可以添加、查询数据。在Chrome的开发者工具中,能查看创建的DB
、存储对象(可理解成表)以及表中添加的数据。

IndexedDB有个非常强大的功能,就是index(索引)。它可对Value对象中任何属性生成索引,然后可以基于索引进行Value对象的快速查询。
要生成索引或支持索引查询数据,需求在首次生成存储对象时,调用接口生成属性的索引。可以同时对对象的多个不同属性创建索引。如下面代码就对name和email两个属性都生成了索引。
var objectStore = thisDB.createObjectStore("people",{ autoIncrement:true });
//first arg is name of index, second is the path (col);
objectStore.createIndex("name","name", {unique:false});
objectStore.createIndex("email","email", {unique:true});<br>
生成索引后,就可以基于索引进行数据的查询。
function getPeopleByNameIndex(e)
{
var name = document.querySelector("#name1").value;
var transaction = db.transaction(["people"],"readonly");
var store = transaction.objectStore("people");
var index = store.index("name");
//name is some value
var request = index.get(name);
request.onsuccess = function(e) {
var result = e.target.result;
if(result) {
var s = "<p><h2>Name "+name+"</h2><p>";
for(var field in result) {
s+= field+"="+result[field]+"<br/>";
}
s+="</p>";
} else {
document.querySelector("#status3").innerHTML = "<h2>No match!</h2>";
}
}
}<br>
分析:IndexedDB是一种灵活且功能强大的数据存储机制,它集合了Dom Storage和Web SQL Database的优点,用于存储大块或复杂结构的数据,提供更大的存储空间,使用起来也比较简单。可以作为Web
SQL Database的替代。不太适合静态文件的缓存。
- 以key-value 的方式存取对象,可以是任何类型值或对象,包括二进制。
- 可以对对象任何属性生成索引,方便查询。
- 较大的存储空间,默认推荐250MB(分Host),比Dom Storage的5MB要大得多。
- 通过数据库的事务(tranction)机制进行数据操作,保证数据一致性。
- 异步的 API 调用,避免造成等待而影响体验。
Android在4.4开始加入对IndexedDB的支持,只需打开允许JS执行的开关就好了。
WebView myWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = myWebView.getSettings(); webSettings.setJavaScriptEnabled(true);<br>
本文文字及图片出自 CSDN
你也许感兴趣的:
- Win1到Win11历届Windows图形界面:优劣与丑陋(排名)
- 你抽屉里断电的固态硬盘里的数据正在悄然丢失
- 台积电亚利桑那工厂停电 苹果芯片晶圆报废
- 编程语言 Rust 的几个核心问题
- 充气式空间站
- 由于视频编码算法H.265专利费上涨,戴尔和惠普部分机型暂停对其支持
- JavaScript中的错误链:借助Error.cause实现更清晰的调试
- PHP 8.5 新特性
- 说真的,我这次要装Linux了
- 对比安卓替代系统:Lineage OS、∕e∕OS 与 Graphene OS
你对本文的反应是: