读书人

用javascript预加载图片、css、js的步

发布时间: 2013-03-06 16:20:31 作者: rapoo

用javascript预加载图片、css、js的方法研究

用javascript预加载图片、css、js的方法研究

预加载的好处可以让网页更快的呈现给用户,缺点就是可能会增加无用的请求(但图片、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()加载
  1. newImage().src ='http://img02.taobaocdn.com/tps/i2/T1iQhUXnxpXXXXXXXX-171-48.png';newImage().src ='http://static.paipaiimg.com/module/logo/logo_2011_02_22.png';newImage().src ='http://co.youa.baidu.com/picture/services/images/logo.png';newImage().src ='http://img1.t.sinajs.cn/t35/style/images/common/header/logoNew_nocache.png';

    加载图片没啥好说的,IE6-9/CM/FF/OP/都返回304,预加载成功。

    1.2、测试用new Image()加载css
    1. newImage().src ='http://a.tbcdn.cn/p/global/1.0/global-min.css';newImage().src ='http://static.paipaiimg.com/member/activate.css';newImage().src ='http://co.youa.baidu.com/picture/services/base.css';newImage().src ='http://img1.t.sinajs.cn/t35/skin/skin_008/skin.css';
    2. newImage().src ='http://a.tbcdn.cn/s/kissy/1.1.6/kissy-min.js';newImage().src ='http://static.paipaiimg.com/js/pp.noticeBoard.js';newImage().src ='http://co.youa.baidu.com/picture/services/cms_core.js';newImage().src ='http://js.t.sinajs.cn/t35/miniblog/static/js/top.js';newImage().src ='http://shop.qq.com/act/static/week/fri/bang/day_1_p_0_10.js';
    3. var doc = document,
    4. ? ? ? ? obj = doc.createElement('object');
    5. ? ? ? ? ? ? ? ? ? ? ? ? obj.style.cssText ='position:absolute;top:-1px;width:1px;height:1px;';
    6. ? ? ? ? ? ? ? ? doc.body.appendChild(obj);? ? ? ?
    7. var doc = document,
    8. ? ? ? ? ifm = doc.createElement("iframe");
    9. ? ? ? ? ? ? ? ? ? ? ? ? ifm.style.cssText ='position:absolute;top:-10px;border:0;width:1px;height:1px;';
    10. ? ? ? ? ifm.scrolling ="no";
    11. ? ? ? ? doc.body.appendChild(ifm);
    12. window.onload =function(){? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? var ifmDoc = ifm.contentDocument || ifm.contentWindow.document;
    13. ? ? ? ? ifmDoc.open();
    14. ? ? ? ? ifmDoc.write('<!doctype><html><head></head><body>');
    15. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ifmDoc.write('<link rel="stylesheet" href="http://localhost/123.css?2011" />');
    16. ? ? ? ? ifmDoc.write('<script defer src="http://localhost/123.js?2011"><\/script>');? ? ? ? ifmDoc.write('<img width="1" height="1" src="http://localhost/123.png?2011" />');
    17. ? ? ? ? ifmDoc.write('</body></html>');
    18. ? ? ? ? ifmDoc.close();
    19. };

    然后创建新页面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 SP3: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.cnblogs.com/mofish/archive/2011/01/18/1938570.html。 文章里面提到了用背景图和隐藏的img标签来预加载,调理很清晰。也可以作为参考。

    另外,模仿新浪的cache.html自己写了个,如果喜欢把iframe作为独立文件使用的可以作为参考。

    1. <!DOCTYPE html><html><head><metacharset="utf-8"></head><body>
    2. <script>
    3. var win = window,
    4. ? ? ? ? doc = document,
    5. ? ? ? ? head = doc.getElementsByTagName("head")[0],
    6. ? ? ? ? getQuery =function(){
    7. ? ? ? ? ? ? ? ? var ret ={},
    8. ? ? ? ? ? ? ? ? ? ? ? ? sch = win.location.search,
    9. ? ? ? ? ? ? ? ? ? ? ? ? arr,
    10. ? ? ? ? ? ? ? ? ? ? ? ? tmp;
    11. ? ? ? ? ? ? ? ? if(sch){
    12. ? ? ? ? ? ? ? ? ? ? ? ? sch = sch.substr(1);
    13. ? ? ? ? ? ? ? ? ? ? ? ? arr = sch.split("&");
    14. ? ? ? ? ? ? ? ? ? ? ? ? for(var i =0, j = arr.length; i < j; i++){
    15. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tmp = arr[i].split('=');
    16. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ret[tmp[0]]= tmp[1];
    17. ? ? ? ? ? ? ? ? ? ? ? ? }
    18. ? ? ? ? ? ? ? ? }
    19. ? ? ? ? ? ? ? ? return ret;
    20. ? ? ? ? },
    21. ? ? ? ? version = getQuery().v ||'';
    22. win.onerror =function(){returntrue};
    23. win.onload =function(){
    24. ? ? ? ? var b = doc.createElement("script");
    25. ? ? ? ? b.src ='http://xx/1.js?v='+ version;
    26. ? ? ? ? head.appendChild(b);
    27. ? ? ? ? };
    28. doc.write('<link rel="stylesheet" href="http://xxx/3.css?version='+ version +'" \/>');
    29. </script>
    30. <imgsrc="http://xxx/4.png"/>
    31. </body></html>

读书人网 >CSS

热点推荐