讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議148:使用本地存儲數據 >

建議148:使用本地存儲數據

除了依賴瀏覽器處理緩存之外,還可以用手工方法直接存儲那些從服務器收到的響應報文。可將響應報文存放在一個對像中,以URL為鍵值對它進行索引。以下是一個XHR封裝,它首先檢查一個URL此前是否被取用過。


var localCache={};

function xhrRequest(url,callback){

if(localCache[url]){

callback.success(localCache[url]);

return;

}

var req=createXhrObject;

req.onerror=function{

callback.error;

};

req.onreadystatechange=function{

if(req.readyState==4){

if(req.responseText===''||req.status=='404'){

callback.error;

return;

}

localCache[url]=req.responseText;

callback.success(req.responseText);

}

};

req.open("GET",url,true);

req.send(null);

}


當然,設置一個Expires頭是更好的解決方案,實現起來比較容易,而且其緩存內容可以跨頁面或跨對話。而一個手工緩存可以利用程序廢止緩存內容並獲取新的數據。設想一種情況,為每個請求緩存數據,用戶可能觸發某些動作導致一個或多個響應報文作廢。在這種情況下從緩存中刪除報文十分簡單:


delete localCache['/user/friendlist/'];

delete localCache['/user/contactlist/'];


本地緩存也可很好地工作於移動設備上。此類設備上的瀏覽器緩存小或根本不存在,手工緩存成為避免不必要請求的最佳選擇。

值得注意的是,在大部分XHR技術中要用到流功能。通過監聽readyState=3,可以在一個大的響應報文沒有完全接收之前就開始解析它,這時可以實時處理報文片斷。這也是MXHR能夠大幅度提高性能的原因之一。不過大多數JavaScript庫不允許直接訪問readystatechange事件,這意味著必須等待整個響應報文接收完才能使用它。

直接使用XMLHttpRequest對象並非像看起來那麼不好。除一些個別行為之外,所有主流瀏覽器的最新版本均以同樣方式支持XMLHttpRequest對象,均可訪問不同的readyState。要支持老版本的IE,只需要多加幾行代碼。下面例子中的函數返回一個XHR對象,可以直接調用這個對象。


function createXhrObject{

var msxml_progid=['MSXML2.XMLHTTP.6.0',

'MSXML3.XMLHTTP',

'Microsoft.XMLHTTP',

'MSXML2.XMLHTTP.3.0'];

var req;

try{

req=new XMLHttpRequest;

}catch(e){

for(var i=0,len=msxml_progid.length;i<len;++i){

try{

req=new ActiveXObject(msxml_progid[i]);

break;

}catch(e2){

}

}

}finally{

return req;

}

}


此函數首先嘗試支持readyState=3的XMLHttpRequest,然後回落到那些不支持此狀態的版本中。直接操作XHR對像減少了函數開銷,進一步提高了性能。只是放棄使用Ajax庫,可能會在極少數的瀏覽器上遇到一些問題。