首頁 >web前端 >js教程 >javascript預先載入圖片、css、js的方法範例介紹_javascript技巧

javascript預先載入圖片、css、js的方法範例介紹_javascript技巧

WBOY
WBOY原創
2016-05-16 17:20:091186瀏覽

預先載入的好處可以讓網頁更快的呈現給用戶,缺點就是可能會增加無用的請求(但圖片、css、js這些靜態檔案可以被快取),如果用戶造訪的頁裡面的css、js 、圖片預先載入了,使用者開啟頁面的速度會快很多,提升使用者體驗。在用到一些大圖片展示的時候,預載大圖是很不錯的方法,圖片更快的被呈現給使用者。不多說了,身為一個前端攻城師都懂的,下面分享我做的測試和得到的結果。

先說需要知道的伺服器回傳的status code:
status-code: 200 - 客戶端請求成功
status-code: 304 - 檔案已經在瀏覽器快取中,伺服器告訴客戶端,原來緩衝的文檔還可以繼續使用。
本文測試判斷檔案被是否被緩存,用的就是判斷是否回傳304.

下面針對預先載入的幾個方法,在不同的瀏覽器下載入img/js/css做個測試,主要包括new Image()、object、iframe。以下載入測試的js、css、圖片文件,是從幾個門戶網站找的(為啥找幾個?是為了盡可能滴測試到特殊的情況,測試中還真遇到了)。
1、測試用new Image()預先載入
1.1、new Image()載入

複製程式碼


程式碼如下:


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


然後再把圖片加到頁面內:javascript預先載入圖片、css、js的方法範例介紹_javascript技巧

載入圖片沒啥好說的,IE6-9/CM/FF/OP/都回304,預先載入成功。 1.2、測試用new Image()加載css複製代碼

代碼如下:


    new Image().src = 'http://a.tbcdn.cn/p/global/1.0/global-min.css'; //淘寶(1)
    new Image().src = 'http ://static.paipaiimg.com/member/activate.css'; //拍拍(2)
    new Image().src = 'http://co.youa.baidu.com/picture/services/ base.css'; //有啊(3)
    new Image().src = 'http://img1.t.sinajs.cn/t35/skin/skin_008/skin.css'; //新浪( 4)
    // http://auto.sina.com.cn/css/newstyles.css
    // 可以用這個測試IE下Expires設定的時間小於目前時間的情況


再把css加到頁內

這個有差別了:
CM/OP,都回傳304(無論有沒有設定Expires)。
FF, 全部回傳了200。
IE,1/2/4都回傳304,而3回傳200。對比回傳的HTTP-Header可以發現:1/2/4都設定了Expires過期時間,而3沒有設定。

說明IE下快取需要設定Expires(且設定的時間大於目前時間),而FF不支援利用new Image()預先載入。 1.3、測試用new Image()加載js複製代碼

代碼如下:


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

CM/OP,都回傳304
FF,只有5回傳了304,只有5的HTTP-Header最簡單(包括:Date、Server、Expires、Cache-Control)。
另外幾個的回應頭資訊內容都比較多,但也都設定了5裡面的這幾個。找規律,發現另外幾個的回應頭都有:Content-Type:text/javascript,而5裡面沒這個。
IE,2/5回傳了304,1/3/4回傳200,對比回應頭,應該還是Content-Type影響的,IE裡面2/5都沒看到Content-Type。
另外,感謝AndrewZhang(http://www.cnblogs.com/AndyWithPassion/)提到,IE下 image 預載js在httpwatch下查看content,資源的載入並不是完整的。我這裡測試也是如此。似乎有位元組限制,測試中2回傳的是完整的,5有一部分內容遺失了。所以用new Image載入JS一點都不可取。

這裡總結下:預先載入圖片用new Image()相容性沒問題。但css/js只有OP/CM可以,IE/FF基本上是無效(這點IE/FF到挺默契)。
2、測試用object預先載入

    var doc = document,
            obj = doc.createElement('object');
   的內容作為object標籤裡的text node)
            //obj.setAttribute('data', '123.js'); // img、css、js
  ;top:-1px;width:1px;height:1px;';
            // obj.style.width = ob object 標籤需要插入非head部分,以觸發載入*/
            //obj.onload = function(){ alert('loaded') }; // FF/OP/Webkit支援(如果data是圖片,IE9也可以)

然後再吧object裡面data載入的文件,建立標籤加到HTML內測試。

測試結果:

FF/OP/CM: 無論是img/js/css,都回傳304。
IE6-8:用object載入img/js/css,會直接Aborted。
IE9比較特殊:
IE9載入js/css,先請求並返回HTTP200,再請求並Aborted,這裡實際上是請求1次(第2次Aborted了)。
IE9載入img的情況,先要求並回傳HTTP200,再請求回圖片,所以圖片需要請求2次。

IE9的第1次請求回傳的內容是空的(並且此時瀏覽器一般會卡住,或直接失去回應)。 IE9首先會請求url,取得檔案類型,判斷是JS/CSS就Aborted,判斷是圖片才載入。

至於IE9第1次請求,大概是靠讀取HTTP頭資訊來得到文件類型,或是偷偷把文件下載下來,然後在沙盒裡面測試文件類型。

一個有意思的事情,例如用object加載JS,IE9有時也能加載進來,也就是第1個請求沒判斷出文件是JS(想看到這個要看運氣了,貌似網速慢的時候可能發生)

據說以前IE是靠文件後綴來判斷文件類型的,後期用HTTP頭資訊來判斷,而他們都可以偽造,所以object在IE下有安全問題。

IE6/7,如果檔案後綴為.js/.css不會發出請求,如果改成http://xxx/test.js?123.png,就發送請求了,然後用script標籤引入,發現可被快取(css這樣搞也OK^^)。
IE8,後綴為js/css也不會發出請求,改後綴為png可以發出請求並得到內容,然後頁面創建標籤引入,文件並沒有被緩存。但如果文件是真正的圖片就被快取了。
題外話:透過上面可以發現,隨著IE的升級,安全性也越來越高了。

So,這裡的結論是:FF/OP/CM下可以用object預先加載,IE就千萬別用了。

3、測試用iframe預先載入

先建立頁面a.html,再加上下面的js。


複製程式碼 程式碼如下:

    var doc = document,
            ifm = doc.createElement("iframe"));            ifm.style.cssText = 'position:absolute;top:-10px;border:0;width:1px; .scrolling = " no";
            doc.body.appendChild(ifm);
    window.onload = function(){ // 預載appendChild,然後再寫onload(如果順序顛倒,IE下不能觸發)
            // ifm.onload = function(){ alert('ifm loaded . ,contentDocument-IE9/FF/OP/CM支援
            var ifmDoc = ifm.contentDocument || ifm.contentWindow.document 🠎>          ifmDoc.write('');
            //ifmDoc.write(''); // 用於測試
            //ifmDoc.write('<script>alert("a")</script>'); // 用於測試
   >

test

test

test

test

');// 用於測試
            // 開始載入
            ifmDoc.write('' /localhost/123.js?2011">'); //不加defer,你會發現IE卡死。 。
            ifmDoc.write('javascript預先載入圖片、css、js的方法範例介紹_javascript技巧');');
            ifmDoc.close();
    };


然後建立新頁面b.html,把要上面預先載入的檔案加到html裡面,測試是否已經預先載入。
結果:IE/FF/OP/CM都成功預先載入。

需要說明的是:當開啟a.html後,再刷新頁面後,iframe內載入檔案的情況。
FF,回傳200(注意,這個200不是伺服器回傳的200,是請求快取成功。因為發送請求的時間顯示的是0)。
CM,顯示狀態是(from cache).
OP,雖然顯示狀態是n/a,但是也是from cache。 IE,IE自備的偵錯工具顯示304,HttpWatch顯示from cache。

測試環境:
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 SP33: IE8
工具:IE9自帶的調試工具、HttpWatch、firebug、chrome自帶的調試工具、Opera Dragonfly。

最後得出的結論:js預先載入圖片使用new Image()基本上夠用了。但是css、js特殊一些,使用object需要判斷瀏覽器。如果考慮到js、css、img都能相容實作預加載,可以考慮使用iframe。

另外,上面的方法創建iframe後,不使用write()寫入要載入的文件,直接設定iframe.src = "cache.html",然後把要預先載入的文件寫在cache.html內也是可行的(以前看過有文章介紹新浪微博是這樣做的,但是文章地址找不到了,搜尋也沒搜到),cache的網址我收藏了:http://tjs.sjs.sinajs.cn/ miniblog2/static/html/cache.html,但看微博的首頁沒找到這個,不知道哪個頁使用的。
其他預先載入的一點補充

doc.createElement('script') 可以預先載入js,如果js裡面有對頁面的操作,就會對頁面產生影響。
doc.createElement('link') 可以預先載入css,但是對目前頁面的樣式也可能會有影響。
所以這樣預先載入不太可取。
用ajax載入img/js/css,相容性不錯,檔案可以被緩存,但是只能限制同域,所以使用範圍有限。
預先載入圖片還可以利用CSS的背景圖片實作。牛人lifesinger之前寫過關於圖片的HTTP請求的文章,不過他部落格以前的資料沒了。網路上搜尋到一篇:http://www.jb51.net/web/110275.html。 文章裡面提到了用背景圖和隱藏的img標籤來預先加載,調理很清晰。也可以作為參考。

另外,模仿新浪的cache.html自己寫了個,如果喜歡把iframe當作獨立檔案使用的可以當作參考。

複製程式碼 程式碼如下:

   
    <script><BR>    //格式:cache.html ?v=123<BR>    var win = window,<BR>            doc = 文檔,<BR>     get.         getQuery = function (){<BR>                    var ret = {},<BR>                          sch = win.location.search,<    arr,<BR>                           >                           sch = sch.substr( 1);<🠎    arr = sch.split("&");<BR>                                                 tmp = arr[i] .split('=') ;<BR>                                    ret[tmp[0]] = tmp[1];<BR>                            }<BR>                    }<BR>                     返回ret;<BR>            },<BR>            version = getQuery( ).v || '';<BR>    win.onerror = function(){return true}; // 發光js錯誤提示<BR>    win.onload = function(){<BR>            var b = doc.createElement("script" v=' version;<BR>            head.appendChild(b);<BR>            //...<link] > /xxx/3.css?version='版本'"/>');<BR>    </script>
    javascript預先載入圖片、css、js的方法範例介紹_javascript技巧
    正文>


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn