jQuery 异步和文档就绪

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11043656/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 10:06:59  来源:igfitidea点击:

Async and document ready

jqueryhtml

提问by tibo

I try to optimize my pages by putting some asyncattributes on my scripts. It seems to break my javascript since $(document).readyis executed before the all scripts are loaded!

我尝试通过async在我的脚本上放置一些属性来优化我的页面。它似乎破坏了我的 javascript,因为它$(document).ready是在加载所有脚本之前执行的!

I saw that I can resolve my problem by putting $(window).loadinstead of $(document).readybut I was wondering if there is a better solution. This solution trigger 2 problems in my case :

我看到我可以通过 put$(window).load而不是解决我的问题,$(document).ready但我想知道是否有更好的解决方案。在我的情况下,此解决方案会引发 2 个问题:

  1. I have to change all $(document).readyand tell all the developpers to not use it anymore
  2. The scripts will be executed after all images are loaded. My website has a lot of heavy images and I really need some scripts to be executed ASAP after dom is ready.
  1. 我必须改变所有$(document).ready并告诉所有开发人员不要再使用它
  2. 加载所有图像后将执行脚本。我的网站有很多沉重的图像,我真的需要在 dom 准备好后尽快执行一些脚本。

Do you have some magic tricks? Maybe putting all scripts at the end? use deferinstead of async?

你有什么魔术吗?也许将所有脚本放在最后?使用defer代替async

采纳答案by tibo

After some extensive research, I can definitely say that putting scripts at the end of the page is THE best practice.

经过一些广泛的研究,我可以肯定地说,将脚本放在页面末尾是最佳实践。

Yahoo agrees with me : http://developer.yahoo.com/performance/rules.html#js_bottom

雅虎同意我的看法:http: //developer.yahoo.com/performance/rules.html#js_bottom

Google don't talk about this practice and seems to prefer async scripts : https://developers.google.com/speed/docs/best-practices/rtt#PreferAsyncResources

谷歌不谈论这种做法,似乎更喜欢异步脚本:https: //developers.google.com/speed/docs/best-practices/rtt#PreferAsyncResources

IMHO, putting script at the end of the page has several benefits over async/defer:

恕我直言,将脚本放在页面末尾比 async/defer 有几个好处:

  • It will work for all browser (yes, even IE ;) )
  • You guarantee the execution order
  • You do not need to use $(document).readyor $(window).load
  • Your scripts can execute before your images are loaded
  • As async/defer, your page will be displayed quicker
  • When the DOM trigger the ready event, all scripts are loaded
  • Can be optimized by merging all js in one file without problem (by a tool like mod_pagespeed)
  • 它适用于所有浏览器(是的,甚至 IE ;))
  • 您保证执行顺序
  • 您不需要使用$(document).ready$(window).load
  • 您的脚本可以在加载图像之前执行
  • 作为异步/延迟,您的页面将显示得更快
  • 当 DOM 触发 ready 事件时,所有脚本都被加载
  • 可以通过将所有 js 毫无问题地合并到一个文件中来进行优化(通过 mod_pagespeed 之类的工具)

The only drawback that I can see is that the browser won't be able to parallelize the downloads. One good reason to use async/defer instead is when you have a script that is completly independant ( do not need to rely on the execution order) and that don't need to be executed at a specific timing. Example : google analytics.

我能看到的唯一缺点是浏览器将无法并行下载。使用 async/defer 的一个很好的理由是,当您有一个完全独立的脚本(不需要依赖执行顺序)并且不需要在特定时间执行时。示例:谷歌分析。

回答by Alex

deferwould definitely help here.

defer肯定会在这里有所帮助。

deferis generally better than asyncbecause it:

defer通常比async因为它更好:

  • loads asynchronously (just like async)
  • guarantees the execution order (unlike async)
  • executes at the end (unlike asyncthat executes in parallel when the page is still loading and it actually haltsthe dom-parsing!)
  • jquery readyfires afterthe "deferred" scripts have been loaded (this is what you're asking)
  • 异步加载(就像async
  • 保证执行顺序(不同于async
  • 在最后执行(与async页面仍在加载时并行执行不同,它实际上停止了 dom 解析!)
  • jquery加载“延迟”脚本ready触发(这就是您要问的)

This SO answerhas a very nice picture illustrating defer/async load order, super-understandable.

这个 SO answer有一张很好的图片说明了延迟/异步加载顺序,超级好理解。

回答by john blair

If you didn't want to use a script loader, you could use the following approach which would allow you to leave your $(document).ready scripts in place - modified as follows:

如果您不想使用脚本加载器,您可以使用以下方法,它允许您将 $(document).ready 脚本留在原地 - 修改如下:

$(()=>{

    function checkAllDownloads() {
        // Ensure your namespace exists.
        window.mynamespace = window.mynamespace || {};

        // Have each of your scripts setup a variable in your namespace when the download has completed.
        // That way you can set async on all your scripts except jquery.
        // Use the document ready event - this code - to check if all your scripts have downloaded.
        if (window.mynamespace.script1 && window.mynamespace.script2){

          // Proceed with page initialisation now that all scripts have been downloaded.
          // [ Add your page initialisation code here ].
          return;
        } 
        // Not all downloads have completed.
        // Schedule another check to give the async downloads time to complete.
        setTimeout(checkAllDownloads, 500);
    }

    // check if it is safe to initialise the page by checking if all downloads have completed.
    checkAllDownloads();

    })