预加载javascript和CSS文件 [英] Preload javascript and css files

查看:78
本文介绍了预加载javascript和CSS文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个移动网站,其中包含大量图片,css和javascript(例如,使用150KB未压缩的库).我为图像构造了一个预加载器,效果很好:

I'm currently developing a mobile website which is heavy on the images, css and javascript (it uses a library which is 150KB uncompressed for example). I've constructed a preloader for the images which works rather nicely:

function loadImages(images){
    var sum = 0;
    for(i in images){
        sum += images[i][1]; // file size
    }
    setMaxProgress(sum);
    for(i in imageArray){
        var img = new Image();
        img.onload = function(){ addProgress(imageArray[i][1]); };
        img.src = imageArray[i][0];
    }
}

但是,我现在想对javascript和css做类似的事情,但是可用的资源却少得多.我发现的唯一方法是在文档加载后对html标签进行document.write(),但这并不能使我(可靠地)指示何时加载文件.

However I would now like to do something similar for the javascript and css, but there are a lot less resources available to do that. The only way I've found is to document.write() the html tags after the document is loaded but this doesn't hive me a (reliable) indication of when the files are loaded.

在我仍然可以衡量进度的同时,有没有办法做到这一点?

Is there a way to do this while I can still measure progress?

顺便说一句:我将它用作常规优化技术的补充,例如最小化js/css,gzipping,css sprite和适当的缓存控制,而不是替代.用户可以跳过加载,然后网站可以正常运行,尽管运行不顺利

BTW: I use this as an addition to normale optimizing techniques like minifying js/css, gzipping, css sprites and proper cache control, not as a replacement. Users can skip loading and the site works perfectly fine then, albeit less smoothly

推荐答案

如果需要了解 何时加载JS,请使用以下 loadScript 函数.您也许可以对CSS进行类似的操作,但是我还没有尝试过:

If you need to know when JS is loaded use the following loadScript function. You might be able to do similarly for CSS, but I haven't tried it:

function preload(src, callback, node)
{
  var script,
      ready,
      where;

  where = node || document.body;
  ready = false;
  script = where.ownerDocument.createElement('script');
  script.src = src;
  script.onload=script.onreadystatechange=function(){
    if ( !ready && ( !this.readyState || this.readyState == 'complete' ) )
    {
      ready = true;
      callback();
      script.parentNode.removeChild(script);
    }
  };
  where.appendChild(script);
}

我已经更新了该功能,并在Firefox中对其进行了测试.它适用于js和css(css需要一些跨浏览器检查.

I've updated the function, and tested it in firefox. It works for both js and css (some cross-browser checking is required for css.

我还想添加更多有关为什么使用 script 元素而不是 link 元素来预加载css的信息.

I'd also like to add a bit more information as to why you'd use the script element to preload css instead of a link element.

在加载页面时,需要分析影响DOM结构的资源,并按照它们出现的顺序进行插入.脚本元素需要在部分加载的DOM的上下文中执行,以便它们仅影响现有的DOM节点.

When the page is being loaded, resources that affect the structure of the DOM need to be analyzed and inserted in the order that they appear. Script elements need to be executed in the context of the partially loaded DOM so that they affect only existing DOM nodes.

样式表不会更改DOM(忽略可能通过 url 插入的javascript).在DOM树解析之前或之后加载样式表都没有关系,因此没有关于资源何时加载的回调.如果使用脚本元素链接到样式表,则在javascript解释器可以决定是否执行任何操作还是应该因异常而崩溃之前,仍然需要加载外部资源.

Stylesheets included via link elements don't change the DOM (ignoring possible javascript insertion via url). It doesn't matter if the stylesheet is loaded before during or after the DOM tree is parsed, so there's no necessary callback as to when the resource is loaded. If a script element is used to link to a stylesheet, the external resource still needs to be loaded before the javascript interpreter can decide whether to perform any actions, or whether it should crash with an exception.

如果您在隐藏的iframe上下文中预加载每个脚本,则可以将所有错误包含在单独的上下文中,而不会导致页面上运行的javascript崩溃.

If you preload each script in the context of a hidden iframe, you can contain all the errors to a separate context without crashing javascript running on the page.

请注意:执行功能的外部脚本在删除之前仍然有机会执行.如果脚本正在执行Ajax轮询或类似的不必要操作,请考虑预加载该特定脚本.

One word of caution: external scripts that perform functions will still have a chance to execute before being removed. If the script is performing ajax polling or similarly unnecessary actions, consider not pre-loading that particular script.

您也许可以使用'loaded'代替'complete'来解决此问题,但是有些旧的浏览器仅 支持 onload ,因此对于那些浏览器,脚本仍将执行.预加载实际上是用于需要在各种不同页面上调用的库组件的.

You may be able to get around this using 'loaded' in the place of 'complete', however there are some older browsers that only support onload, so for those browsers the scripts would still be executed. Pre-loading is really meant to be used for library components that need to be called on various different pages.

这篇关于预加载javascript和CSS文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆