日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

用javascript預(yù)加載圖片、css、js的方法研究

 CevenCheng 2012-05-24

用javascript預(yù)加載圖片、css、js的方法研究

預(yù)加載的好處可以讓網(wǎng)頁(yè)更快的呈現(xiàn)給用戶(hù),缺點(diǎn)就是可能會(huì)增加無(wú)用的請(qǐng)求(但圖片、css、js這些靜態(tài)文件可以被緩存),如果用戶(hù)訪問(wèn)的頁(yè)面里面的css、js、圖片被預(yù)加載了,用戶(hù)打開(kāi)頁(yè)面的速度會(huì)快很多,提升用戶(hù)體驗(yàn)。在用到一些大圖片展示的時(shí)候,預(yù)加載大圖是很不錯(cuò)的方法,圖片更快的被呈現(xiàn)給用戶(hù)。不多說(shuō)了,作為一個(gè)前端攻城師都懂的,下面分享我做的測(cè)試和得到的結(jié)果。

先說(shuō)需要知道的服務(wù)器返回的status code:
status-code: 200 - 客戶(hù)端請(qǐng)求成功
status-code: 304 - 文件已經(jīng)在瀏覽器緩存中,服務(wù)器告訴客戶(hù)端,原來(lái)緩沖的文檔還可以繼續(xù)使用。
本文測(cè)試判斷文件被是否被緩存,用的就是判斷是否返回304.

下面針對(duì)預(yù)加載的幾個(gè)方法,在不同的瀏覽器下加載img/js/css做個(gè)測(cè)試,主要包括new Image()、object、iframe。以下加載測(cè)試的js、css、圖片文件,是從幾個(gè)門(mén)戶(hù)網(wǎng)站找的(為啥找?guī)讉€(gè)?是為了盡可能滴測(cè)試到特殊的情況,測(cè)試中還真遇到了)。

1、測(cè)試用new Image()預(yù)加載

1.1、new Image()加載

  1. new Image().src = 'http://img02./tps/i2/T1iQhUXnxpXXXXXXXX-171-48.png'; //淘寶
  2. new Image().src = 'http://static./module/logo/logo_2011_02_22.png'; //拍拍
  3. new Image().src = 'http://co.youa.baidu.com/picture/services/images/logo.png'; //有啊
  4. new Image().src = 'http://img1.t./t35/style/images/common/header/logoNew_nocache.png'; //新浪*/

然后再把圖片添加到頁(yè)面內(nèi):<img src="xxx" />

加載圖片沒(méi)啥好說(shuō)的,IE6-9/CM/FF/OP/都返回304,預(yù)加載成功。

1.2、測(cè)試用new Image()加載css

  1. new Image().src = 'http://a./p/global/1.0/global-min.css'; //淘寶(1)
  2. new Image().src = 'http://static./member/activate.css'; //拍拍(2)
  3. new Image().src = 'http://co.youa.baidu.com/picture/services/base.css'; //有啊(3)
  4. new Image().src = 'http://img1.t./t35/skin/skin_008/skin.css'; //新浪(4)
  5. // http://auto.sina.com.cn/css/newstyles.css
  6. // 可以用這個(gè)測(cè)試IE下Expires設(shè)置的時(shí)間小于當(dāng)前時(shí)間的情況

再把css添加到頁(yè)面內(nèi)

這個(gè)有區(qū)別了:
CM/OP,都返回304(無(wú)論有沒(méi)有設(shè)置Expires)。
FF, 全部返回了200。
IE,1/2/4都返回304,而3返回200。對(duì)比返回的HTTP-Header可以發(fā)現(xiàn):1/2/4都設(shè)置了Expires過(guò)期時(shí)間,而3沒(méi)有設(shè)置。
說(shuō)明IE下緩存需要設(shè)置Expires(并且設(shè)置的時(shí)間要大于當(dāng)前時(shí)間),而FF不支持利用new Image()預(yù)加載。

1.3、測(cè)試用new Image()加載js

  1. new Image().src = 'http://a./s/kissy/1.1.6/kissy-min.js'; //淘寶(1)
  2. new Image().src = 'http://static./js/pp.noticeBoard.js'; //拍拍(2)
  3. new Image().src = 'http://co.youa.baidu.com/picture/services/cms_core.js'; //有啊(3)
  4. new Image().src = 'http://js.t./t35/miniblog/static/js/top.js'; //新浪(4)
  5. new Image().src = 'http://shop.qq.com/act/static/week/fri/bang/day_1_p_0_10.js'; //QQ(5)

再把js添加到頁(yè)面內(nèi)。

CM/OP,都返回304
FF,只有5返回了304,也只有5的HTTP-Header最簡(jiǎn)單(包括:Date、Server、Expires、Cache-Control)。
另外幾個(gè)的響應(yīng)頭信息內(nèi)容都比較多,但也都設(shè)置了5里面的這幾個(gè)。找規(guī)律,發(fā)現(xiàn)另外幾個(gè)的響應(yīng)頭都有:Content-Type:text/javascript,而5里面沒(méi)這個(gè)。
IE,2/5返回了304,1/3/4返回200,對(duì)比響應(yīng)頭,應(yīng)該還是Content-Type影響的,IE里面2/5都沒(méi)看到Content-Type。
另外,感謝AndrewZhang(http://www.cnblogs.com/AndyWithPassion/)提到,IE下 image 預(yù)加載js在httpwatch下查看content,資源的加載并不是完整的。我這里測(cè)試也是如此。貌似有字節(jié)限制,測(cè)試中2返回的是完整的,5有一部分內(nèi)容丟失了。所以用new Image加載JS一點(diǎn)都不可取。

這里總結(jié)下:預(yù)加載圖片用new Image()兼容性沒(méi)問(wèn)題。但是css/js只有OP/CM可以,IE/FF基本是無(wú)效(這點(diǎn)IE/FF到挺有默契)。

2、測(cè)試用object預(yù)加載

  1. var doc = document,
  2.         obj = doc.createElement('object');
  3.         //obj.data = '123.js'; //Ps: 這樣寫(xiě)OP下無(wú)效(會(huì)把data的內(nèi)容作為object標(biāo)簽里的text node)
  4.         //obj.setAttribute('data', '123.js'); // img、css、js
  5.         obj.style.cssText = 'position:absolute;top:-1px;width:1px;height:1px;';
  6.         // obj.style.width = obj.style.height = 0;
  7.         doc.body.appendChild(obj); // 插入object 標(biāo)簽需要插入到非head部分,以觸發(fā)加載*/
  8.         //obj.onload = function(){ alert('loaded') }; // FF/OP/Webkit支持(如果data是圖片,IE9也可以)

然后再吧object里面data加載的文件,創(chuàng)建標(biāo)簽加到HTML內(nèi)測(cè)試。

測(cè)試結(jié)果:
FF/OP/CM: 無(wú)論是img/js/css,都返回304。
IE6-8:用object加載img/js/css,會(huì)直接Aborted。
IE9比較特殊:
IE9加載js/css,先請(qǐng)求并返回HTTP200,再請(qǐng)求并Aborted,這里實(shí)際上是請(qǐng)求1次(第2次Aborted了)。
IE9加載img的情況,先請(qǐng)求并返回HTTP200,再請(qǐng)求返回圖片,所以圖片需要請(qǐng)求2次。

IE9的第1次請(qǐng)求返回的內(nèi)容是空的(并且此時(shí)瀏覽器一般會(huì)卡住,或者直接失去響應(yīng))。 IE9首先會(huì)請(qǐng)求url,獲取文件類(lèi)型,判斷是JS/CSS就Aborted,判斷是圖片才加載。

至于IE9第1次請(qǐng)求,大概是靠讀取HTTP頭信息來(lái)得到文件類(lèi)型,或者偷偷把文件下載下來(lái),然后在沙盒里面測(cè)試文件類(lèi)型。
一個(gè)有意思的事情,比如用object加載JS,IE9有時(shí)也能加載進(jìn)來(lái),也就是第1個(gè)請(qǐng)求沒(méi)判斷出文件是JS(想看到這個(gè)要看運(yùn)氣了,貌似網(wǎng)速慢的時(shí)候可能發(fā)生)

據(jù)說(shuō)以前IE是靠文件后綴來(lái)判斷文件類(lèi)型的,后期用HTTP頭信息來(lái)判斷,而他們都可以偽造,所以object在IE下存在安全問(wèn)題。
IE6/7,如果文件后綴后綴為.js/.css不會(huì)發(fā)出請(qǐng)求,如果改成http://xxx/test.js?123.png,就發(fā)送請(qǐng)求了,然后用script標(biāo)簽引入,發(fā)現(xiàn)可被緩存(css這樣搞也OK^^)。
IE8,后綴為js/css也不會(huì)發(fā)出請(qǐng)求,改后綴為png可以發(fā)出請(qǐng)求并得到內(nèi)容,然后頁(yè)面創(chuàng)建標(biāo)簽引入,文件并沒(méi)有被緩存。但如果文件是真正的圖片就被緩存了。
題外話(huà):通過(guò)上面可以發(fā)現(xiàn),隨著IE的升級(jí),安全性也越來(lái)越高了。

So,這里的結(jié)論是:FF/OP/CM下可以用object預(yù)加載,IE就千萬(wàn)別用了。

3、測(cè)試用iframe預(yù)加載

先創(chuàng)建頁(yè)面a.html,然后加上下面的js。

  1. var doc = document,
  2.         ifm = doc.createElement("iframe");
  3.         //ifm.id="preLoadIfm";
  4.         // ifm.style.border = ifm.width = ifm.height = 0;
  5.         ifm.style.cssText = 'position:absolute;top:-10px;border:0;width:1px;height:1px;';
  6.         ifm.scrolling = "no";
  7.         doc.body.appendChild(ifm);

  8. window.onload = function(){ // 預(yù)加載當(dāng)然最好是window.onload之后觸發(fā)
  9.         //要觸發(fā)onload,需要先appendChild,然后再寫(xiě)onload(如果順序顛倒,IE下不能觸發(fā))
  10.         // ifm.onload = function(){ alert('ifm loaded'); }
  11.         // contentWindow.document-所有都支持,contentDocument-IE9/FF/OP/CM支持
  12.         var ifmDoc = ifm.contentDocument || ifm.contentWindow.document;
  13.         ifmDoc.open();
  14.         ifmDoc.write('<!doctype><html><head></head><body>');
  15.         //ifmDoc.write('<style>html{background:#000;color:#fff}</style>'); // 用于測(cè)試
  16.         //ifmDoc.write('<script>alert("a")<\/script>'); // 用于測(cè)試
  17.         //ifmDoc.write('<p>test</p><p>test</p><p>test</p><p>test</p><p>test</p>');// 用于測(cè)試
  18.         // 開(kāi)始加載
  19.         ifmDoc.write('<link rel="stylesheet" href="http://localhost/123.css?2011" />');
  20.         ifmDoc.write('<script defer src="http://localhost/123.js?2011"><\/script>'); //不加defer,你會(huì)發(fā)現(xiàn)IE卡死。。
  21.         ifmDoc.write('<img width="1" height="1" src="http://localhost/123.png?2011" />');
  22.         ifmDoc.write('</body></html>');
  23.         ifmDoc.close();
  24. };

然后創(chuàng)建新頁(yè)面b.html,把要上面預(yù)加載的文件加到html里面,測(cè)試是否已經(jīng)預(yù)加載。
結(jié)果:IE/FF/OP/CM都成功預(yù)加載。

需要說(shuō)明的是:當(dāng)打開(kāi)a.html后,再刷新頁(yè)面后,iframe內(nèi)加載文件的情況。
FF,返回200(注意,這個(gè)200不是服務(wù)器返回的200,是請(qǐng)求緩存成功。因?yàn)榘l(fā)送請(qǐng)求的時(shí)間顯示的是0)。
CM,顯示狀態(tài)是(from cache).
OP,雖然顯示狀態(tài)是n/a,但是也是from cache。 IE,IE自帶的調(diào)試工具顯示304,HttpWatch顯示from cache。

測(cè)試環(huán)境:
WIN7 EN SP1:OP 11.50、IE7-9、FF 3.6/6.0、Chrome 10
XP EN SP3:IE6
XP EN SP3:IE7
XP CN SP3:IE8
工具:IE9自帶的調(diào)試工具、HttpWatch、firebug、chrome自帶的調(diào)試工具、Opera Dragonfly。

最后得出的結(jié)論:js預(yù)加載圖片使用new Image()基本夠用了。但是css、js特殊一些,使用object需要判斷瀏覽器。如果考慮到j(luò)s、css、img都能兼容實(shí)現(xiàn)預(yù)加載,可以考慮使用iframe。

另外,上面的方法創(chuàng)建iframe后,不使用write()寫(xiě)入要加載的文件,直接設(shè)置iframe.src = "cache.html",然后把要預(yù)加載的文件寫(xiě)在cache.html內(nèi)也是可行的(以前看過(guò)有文章介紹新浪微博是這樣做的,但是文章地址找不到了,搜索也沒(méi)搜到),cache的網(wǎng)址我收藏了:http://tjs.sjs./miniblog2/static/html/cache.html,但是看微博的首頁(yè)沒(méi)找到這個(gè),不知道在哪個(gè)頁(yè)使用的。

其他預(yù)加載的一點(diǎn)補(bǔ)充

doc.createElement('script') 可以預(yù)加載js,如果js里面有對(duì)頁(yè)面的操作,就會(huì)對(duì)頁(yè)面產(chǎn)生影響。
doc.createElement('link') 可以預(yù)加載css,但是對(duì)當(dāng)前頁(yè)面的樣式也可能會(huì)有影響。
所以這樣預(yù)加載不太可取。
用ajax加載img/js/css,兼容性不錯(cuò),文件可以被緩存,但是只能限制同域,所以使用范圍有限。
預(yù)加載圖片還可以利用CSS的背景圖片實(shí)現(xiàn)。牛人lifesinger之前寫(xiě)過(guò)關(guān)于圖片的HTTP請(qǐng)求的文章,不過(guò)他博客以前的數(shù)據(jù)沒(méi)了。網(wǎng)上搜索到一篇轉(zhuǎn)載的:http://www.cnblogs.com/mofish/archive/2011/01/18/1938570.html。 文章里面提到了用背景圖和隱藏的img標(biāo)簽來(lái)預(yù)加載,調(diào)理很清晰。也可以作為參考。

另外,模仿新浪的cache.html自己寫(xiě)了個(gè),如果喜歡把iframe作為獨(dú)立文件使用的可以作為參考。

  1. <!DOCTYPE html><html><head><meta charset="utf-8"></head><body>
  2. <script>
  3. //usage: cache.html?v=123
  4. var win = window,
  5.         doc = document,
  6.         head = doc.getElementsByTagName("head")[0],
  7.         getQuery = function(){
  8.                 var ret = {},
  9.                         sch = win.location.search,
  10.                         arr,
  11.                         tmp;
  12.                 if (sch) {
  13.                         sch = sch.substr(1);
  14.                         arr = sch.split("&");
  15.                         for(var i = 0, j = arr.length; i < j; i++) {
  16.                                 tmp = arr[i].split('=');
  17.                                 ret[tmp[0]] = tmp[1];
  18.                         }
  19.                 }
  20.                 return ret;
  21.         },
  22.         version = getQuery().v || '';

  23. win.onerror = function(){return true}; //屏蔽js錯(cuò)誤提示

  24. win.onload = function(){
  25.         var b = doc.createElement("script");
  26.         b.src = 'http://xx/1.js?v=' + version;
  27.         head.appendChild(b);
  28.         //...
  29. };
  30. doc.write('<link rel="stylesheet" href="http://xxx/3.css?version=' + version + '" \/>');
  31. </script>
  32. <img src="http://xxx/4.png" />
  33. </body></html>

 / 分類(lèi): 開(kāi)發(fā),實(shí)踐 / TrackBack標(biāo)簽: cssjavascriptpreload

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多