预加载 javascript 和 css 文件

发布于 2024-11-25 14:14:14 字数 699 浏览 1 评论 0原文

我目前正在开发一个移动网站,该网站大量使用图像、CSS 和 JavaScript(例如,它使用一个未压缩的 150KB 的库)。我已经为图像构建了一个预加载器,效果相当好:

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() 操作,但这并不能为我提供文件加载时间的(可靠)指示。

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

顺便说一句:我使用它作为常规优化技术的补充,例如缩小 js/css、gzipping、css sprites 和适当的缓存控制,而不是作为替代。用户可以跳过加载,然后网站就可以正常工作,尽管不太顺利

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];
    }
}

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?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

反差帅 2024-12-02 14:14:14

如果您需要知道 JS 何时加载,请使用以下 loadScript 函数。 你也许可以对CSS做类似的事情,但我还没有尝试过

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 需要一些跨浏览器检查。

我还想添加更多信息来说明为什么使用 script 元素来预加载 css 加载页面

时,需要分析影响 DOM 结构的资源,并按照它们出现的顺序插入 Script 元素。部分加载的 DOM,以便它们仅影响现有的 DOM 节点。

通过 link 元素包含的样式表不会更改 DOM(忽略可能通过 url 插入的 javascript)。或者在解析 DOM 树之后,因此无需在加载资源时进行回调。如果使用脚本元素链接到样式表,则仍然需要加载外部资源,然后 JavaScript 解释器才能决定是否执行。任何行动,或者是否它应该会因异常而崩溃。

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

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

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

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);
}

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.

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.

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.

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.

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.

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.

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.

七秒鱼° 2024-12-02 14:14:14

“我发现的唯一方法是在加载文档后使用 document.write() html 标签,但这并不能为我提供文件加载时间的(可靠)指示”

您可以在您的文件中附加脚本元素,即head 标记并将处理程序附加到 onload 或 onreadystatechange “事件”,以指示文件何时加载。

以下网址详细解释了一些内容:

http://unixpapa.com/js/dyna.html

"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"

You could append script elements i.e in your head tag and attach handlers to the onload or onreadystatechange 'events' to have an indication of when the files are loaded.

Following url explains some things in detail:

http://unixpapa.com/js/dyna.html

情深如许 2024-12-02 14:14:14

问题得到解答后,我得出以下结论:在 HTML5 中,标签现在有一个 async 选项,最近主流浏览器也开始实现 defer 属性(它已经在 IE 中存在很长时间了)。您也可以将脚本放在身体的底部。

这些允许您将脚本的加载/执行推迟到页面加载之后,从而有效地获得所需的行为。

HTML5 还为脚本元素(标签)定义了 onload 属性,这可能就是使

After the question was answered I came onto the following: in HTML5 the tag now has an async option and recently major browsers also began to implement the defer attribute (it has been in IE for a long time). You can also place the scripts on the bottom of your body.

These allow you to defer loading/execution of the script until after the page has loaded and thus effectively get the desired behaviour.

HTML5 also defines the onload property for script elements (tags) which is probably what makes the

自由如风 2024-12-02 14:14:14

我是这样做的:

$('<link/>', {
  rel:'stylesheet',
  type:'text/css',
  href: => path goes here <=,
  media:'all'
}).appendTo('head');

只需在那里输入你的路径即可。

瞧。

(对我来说很完美)

[编辑]
当然,你需要Jquery

I did it this Way:

$('<link/>', {
  rel:'stylesheet',
  type:'text/css',
  href: => path goes here <=,
  media:'all'
}).appendTo('head');

Just enter your path there.

voilà.

(works perfect for me)

[edit]
of course, you need Jquery

奢欲 2024-12-02 14:14:14

$import.js 是一个小型实用程序,允许控制 js/css/less 文件仅在必要时加载到文档。

使用示例:

$import("script.js", "style.css", "[:js]script.php", function(files){ console.log(files); });

An $import.js is a tiny utility, that allows to control js/css/less files loading to the document when only it's necessary.

Usage example:

$import("script.js", "style.css", "[:js]script.php", function(files){ console.log(files); });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文