37

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

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

  1. 我必须全部更改$(document).ready并告诉所有开发人员不要再使用它了
  2. 加载所有图像后,将执行脚本。我的网站有很多沉重的图像,我真的需要在 dom 准备好后尽快执行一些脚本。

你有一些魔术技巧吗?也许将所有脚本放在最后?使用defer而不是async

4

3 回答 3

33

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

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

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

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

  • 它适用于所有浏览器(是的,甚至 IE ;))
  • 您保证执行顺序
  • 您不需要使用$(document).ready$(window).load
  • 您的脚本可以在加载图像之前执行
  • 作为异步/延迟,您的页面将显示得更快
  • 当 DOM 触发 ready 事件时,所有脚本都被加载
  • 可以通过将所有js合并到一个文件中来优化(通过mod_pagespeed之类的工具)

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

于 2012-06-15T11:20:33.303 回答
4

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

defer通常比async因为它更好:

  • 异步加载(就像async
  • 保证执行顺序(不像async
  • 在最后执行(与async页面仍在加载时并行执行不同,它实际上停止了 dom 解析!)
  • jquery在“延迟”脚本加载ready触发(这就是你要问的)

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

于 2019-05-14T10:48:52.600 回答
1

如果您不想使用脚本加载器,您可以使用以下方法,让您将 $(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();

    })
于 2018-11-12T09:14:03.480 回答