css懒加载和预加载_预加载CSS / JavaScript而不执行

css懒加载和预加载

css懒加载和预加载

Preloading components in advance is good for performance. There are several ways to do it. But even the cleanest solution (open up an iframe and go crazy there) comes at a price - the price of the iframe and the price of parsing and executing the preloaded CSS and JavaScript. There's also a relatively high risk of potential JavaScript errors if the script you preload assumes it's loaded in a page different than the one that preloads.

预先预加载组件有助于提高性能。 有几种方法可以做到这一点。 但是,即使最干净的解决方案(打开iframe并在那里疯狂)也要付出代价-iframe的价格以及解析和执行预加载CSS和JavaScript的价格。 如果您预加载的脚本假定它加载的页面与预加载的页面不同,则存在潜在JavaScript错误的风险也相对较高。

After a bit of trial and lot of error I think I came up with something that could work cross-browser:

经过一番尝试和许多错误之后,我认为我想出了一些可以跨浏览器使用的功能:

  • in IE use new Image().src to preload all component types

    在IE中使用new Image().src预加载所有组件类型

  • in all other browsers use a dynamic <object> tag

    在所有其他浏览器中,使用动态<object>标签

代码和演示(Code and demo)

Here's the final solution, below are some details.

这是最终的解决方案,以下是一些详细信息。

In this example I assume the page prefetches after onload some components that will be needed by the next page. The components are a CSS, a JS and a PNG (sprite).

在此示例中,我假设页面在加载后会预取下一页需要的某些组件。 这些组件是CSS,JS和PNG(精灵)。

window.onload = function () {
 
    var i = 0,
        max = 0,
        o = null,
 
        // list of stuff to preload
        preload = [
            'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.png',
            'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.js',
            'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.css'
        ],
        isIE = navigator.appName.indexOf('Microsoft') === 0;
 
    for (i = 0, max = preload.length; i < max; i += 1) {
        
        if (isIE) {
            new Image().src = preload[i];
            continue;
        }
        o = document.createElement('object');
        o.data = preload[i];
        
        // IE stuff, otherwise 0x0 is OK
        //o.width = 1;
        //o.height = 1;
        //o.style.visibility = "hidden";
        //o.type = "text/plain"; // IE 
        o.width  = 0;
        o.height = 0;
        
        
        // only FF appends to the head
        // all others require body
        document.body.appendChild(o);
    }
    
};

A demo is here: http://phpied.com/files/object-prefetch/page1.php?id=1 In the demo the components are delayed with 1 second each and sent with Expries header. Feel free to increment the ID for a new test with uncached components.

此处是一个演示: http ://phpied.com/files/object-prefetch/page1.php?id=1在演示中,组件延迟了1秒,并随Expries标头发送。 可以为未缓存组件的新测试随意增加ID。

Tested in FF3.6, O10, Safari 4, Chrome 5, IE 6,7,8.

在FF3.6,O10,Safari 4,Chrome 5,IE 6、7、8中进行了测试。

评论 (Comments)

  • new Image().src doesn't do the job in FF because it has a separate cache for images. Didn't seem to work in Safari either where CSS and JS were requested on the second page where they sould've been cached

    new Image().src在FF中不起作用,因为它具有用于图像的单独缓存。 似乎在Safari中也不起作用,因为在第二个页面中要求缓存CSS和JS的地方

  • the dynamic object element has to be outside the head in most browsers in order to fire off the downloads

    在大多数浏览器中,动态object元素必须位于head之外,以触发下载

  • dynamic object works also in IE7,8 with a few tweaks (commented out in the code above) but not in IE6. In a separate tests I've also found the object element to be expensive in IE in general.

    动态object在IE7,8中也做了一些调整(在上面的代码中有注释),但在IE6中没有。 在单独的测试中,我还发现对象元素通常在IE中是昂贵的。

That's about it. Below are some unsuccessful attempts I tried which failed for various reasons in different browsers.

就是这样以下是我尝试的一些失败尝试,这些尝试由于各种原因在不同的浏览器中失败。

其他失败的尝试 (Other unsuccessful attempts)

1. I was actually inspired by this post by Ben Cherry where he loads CSS and JS in a print stylesheet. Clever hack, unfortunately didn't work in Chrome which caches the JS but doesn't execute it on the next page.

1.实际上,我受Ben Cherry这篇文章启发,他在打印样式表中加载CSS和JS。 不幸的是,聪明的hack不能在Chrome中起作用,因为Chrome可以缓存JS,但无法在下一页执行它。

2. One of the comments on Ben's post suggested (Philip and Dejan said the same) using invalid type attribute to prevent execution, e.g. text/cache.

2. Ben的帖子中有一条评论建议( PhilipDejan表示相同)使用无效的type属性来防止执行,例如text/cache

var s = document.createElement('script');
s.src = preload[1];
s.type = "text/cache";
document.getElementsByTagName('head')[0].appendChild(s);

That worked for the most parts but not in FF3.6 where the JavaScript was never requested.

这在大多数情况下都有效,但在FF3.6中却没有,因为FF3.6从未要求过JavaScript。

3. A dynamic link prefetch didn't do anything, not even in FF which is probably the only browser that supports this.

3.动态链接prefetch不执行任何操作,甚至在FF中也不起作用,FF可能是唯一支持此功能的浏览器。

for (i = 0, max = preload.length; i < max; i += 1) {
    var link = document.createElement('link');
    link.href = preload[i];
    link.rel = "prefetch";
    document.getElementsByTagName('head')[0].appendChild(link);
}

Then it took a bit of trial/error to make IE7,8 work with an object tag, before I stumbled into IE6 and gave up in favor of image src.

然后,花了一些试验/错误才能使IE7,8与对象标记一起使用,然后我偶然发现IE6并放弃了对image src的支持。

结论 (In conclusion)

I believe this is a solution I could be comfortable with, although it involves user agent sniffing. It certainly looks less hacky than loading JS as CSS anyways. And object elements are meant to load any type of component so no semantic conflict here I don't believe. Feel free to test and report any edge cases or browser/OS combos. (JS errors in IE on the second page are ok, because I'm using console.log in the preloaded javascript)

我相信这是我可以接受的解决方案,尽管它涉及用户代理嗅探。 无论如何,与将JS加载为CSS相比,它看起来似乎没有那么hacky。 对象元素旨在加载任何类型的组件,因此在这里我不相信任何语义冲突。 随时测试和报告任何极端情况或浏览器/ OS组合。 (第二页IE中的JS错误是可以的,因为我在预加载的javascript中使用console.log )

Thanks for reading!

谢谢阅读!

Tell your friends about this post on Facebook and Twitter

FacebookTwitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/preload-cssjavascript-without-execution/

css懒加载和预加载

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值