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
Async and document ready
提问by tibo
I try to optimize my pages by putting some async
attributes on my scripts. It seems to break my javascript since $(document).ready
is executed before the all scripts are loaded!
我尝试通过async
在我的脚本上放置一些属性来优化我的页面。它似乎破坏了我的 javascript,因为它$(document).ready
是在加载所有脚本之前执行的!
I saw that I can resolve my problem by putting $(window).load
instead of $(document).ready
but I was wondering if there is a better solution.
This solution trigger 2 problems in my case :
我看到我可以通过 put$(window).load
而不是解决我的问题,$(document).ready
但我想知道是否有更好的解决方案。在我的情况下,此解决方案会引发 2 个问题:
- I have to change all
$(document).ready
and tell all the developpers to not use it anymore - 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.
- 我必须改变所有
$(document).ready
并告诉所有开发人员不要再使用它 - 加载所有图像后将执行脚本。我的网站有很多沉重的图像,我真的需要在 dom 准备好后尽快执行一些脚本。
Do you have some magic tricks? Maybe putting all scripts at the end? use defer
instead 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).ready
or$(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
defer
would definitely help here.
defer
肯定会在这里有所帮助。
defer
is generally better than async
because it:
defer
通常比async
因为它更好:
- loads asynchronously (just like
async
) - guarantees the execution order (unlike
async
) - executes at the end (unlike
async
that executes in parallel when the page is still loading and it actually haltsthe dom-parsing!) - jquery
ready
fires 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();
})