Подтвердить что ты не робот

Асинхронный и готовый документ

Я пытаюсь оптимизировать свои страницы, помещая некоторые атрибуты async в мои скрипты. Кажется, он разбивает мой javascript, так как $(document).ready выполняется до загрузки всех скриптов!

Я видел, что могу решить проблему, поставив $(window).load вместо $(document).ready, но мне было интересно, есть ли лучшее решение. Это решение вызывает в моем случае 2 проблемы:

  • Мне нужно изменить все $(document).ready и сообщить всем разработчикам, чтобы он больше не использовал его
  • Сценарии будут выполнены после загрузки всех изображений. На моем веб-сайте много тяжелых изображений, и мне действительно нужно, чтобы некоторые сценарии исполнялись как можно скорее после того, как dom готов.

Есть ли у вас какие-то волшебные трюки? Может, положить все сценарии в конец? используйте defer вместо async?

4b9b3361

Ответ 1

После некоторых обширных исследований я могу определенно сказать, что создание сценариев в конце страницы - лучшая практика.

Yahoo соглашается со мной: http://developer.yahoo.com/performance/rules.html#js_bottom

Google не говорит об этой практике и предпочитает асинхронные скрипты: https://developers.google.com/speed/docs/best-practices/rtt#PreferAsyncResources

IMHO, размещение script в конце страницы имеет несколько преимуществ по сравнению с async/defer:

  • Он будет работать для всех браузеров (да, даже IE;))
  • Вы гарантируете выполнение заказа
  • Вам не нужно использовать $(document).ready или $(window).load
  • Ваши скрипты могут выполняться до загрузки изображений
  • Как async/defer, ваша страница будет отображаться быстрее
  • Когда DOM запускает готовое событие, все сценарии загружаются
  • Может быть оптимизирован путем слияния всех js в одном файле без проблем (с помощью инструмента, такого как mod_pagespeed)

Единственный недостаток, который я вижу, заключается в том, что браузер не сможет распараллелить загрузку. Одной из веских причин использовать async/defer вместо этого является то, что у вас есть script, который полностью независим (не нужно полагаться на порядок выполнения) и который не нужно выполнять в определенный момент времени. Пример: аналитика google.

Ответ 2

Если вы не хотите использовать загрузчик сценариев, вы можете использовать следующий подход, который позволит вам оставить на месте ваши сценарии $ (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();

    })

Ответ 3

defer определенно лучше, чем async потому что он:

  • загружается асинхронно (как асинхронно)
  • гарантирует выполнение заказа (в отличие от асинхронного)
  • выполняется в конце (в отличие от асинхронного выполнения, которое выполняется параллельно, когда страница все еще загружается)
  • JQuery ready запускается после загрузки "отложенных" скриптов (это то, что вы спрашиваете)

Этот SO-ответ имеет очень хорошую картину, иллюстрирующую порядок отложенной/асинхронной загрузки, супер-понятный.