Почему jQuery.ready рекомендуется, когда это так медленно? - PullRequest
32 голосов
/ 04 марта 2012

Я задавал подобный вопрос ранее, но я никогда не разъяснял свою точку зрения точно, или, по крайней мере, я думаю, что это такой важный вопрос, что стоит поднять его и посмотреть, может ли кто-нибудь дать какой-то проницательныймысли.

При использовании jQuery многие из нас используют функцию jQuery.ready для выполнения init после загрузки DOM.Фактически это стало стандартным способом добавления программ манипулирования DOM на веб-страницу с использованием jQuery.Связанное событие существует изначально в некоторых браузерах, но jQuery эмулирует его в других браузерах, таких как некоторые версии IE.Пример:

<head>
<script>
    var init = function() { alert('hello world'); };
    $.ready(init);
</script>

Теперь все наши тесты показывают, что это событие может быть довольно медленным.Это не так медленно, как window.onload, но все равно часто перед запуском задержка составляет около 100 мс.Если FF, то это может быть до 200-300 мс, особенно при обновлении.

Это очень важные миллисекунды, потому что это время, в течение которого отображается начальный макет перед выполнением любых манипуляций с DOM (например,скрытие выпадающего списка).Во многих случаях «мерцание» макета в основном вызывается медленным событием готовности DOM, заставляющим программистов скрывать элементы с использованием CSS и потенциально делающим его менее доступным.

Теперь, если вместо этого мы поместим функцию init втег script перед закрытием тега body будет выполняться намного быстрее, обычно примерно вдвое, но иногда даже быстрее:

<head>
<script>
    var init = function() { alert('hello world'); };
</script>
</head>
<body>
<!-- some HTML -->
<script>init();</script>
</body>

Простая тестовая страница, которая доказывает различия: http://jsbin.com/aqifon/10

Я имею в виду, мы не говорим о едва заметных различиях, поскольку некоторые из «полицейских по оптимизации» поощряют использование эффективных селекторов.Мы говорим о некоторых значительных задержках при выполнении манипуляций с DOM-нагрузкой.При использовании этого примера в FF, domready может иногда быть более чем в 100 раз медленнее (300 мс против 2 мс).

Теперь на мой вопрос: Почему рекомендуется использовать jQuery.ready, когда он явно многомедленнее других альтернатив?И каковы недостатки вызова init перед закрытием тела против использования jQuery.ready?Возможно, более «безопасно» использовать domReady, но в каком контексте это более безопасно, чем другой вариант?(Я имею в виду такие вещи, как document.write и отложенные сценарии) Мы использовали BODY почти 5 лет на многих клиентских сайтах и ​​никогда не сталкивались с какими-либо проблемами.Это просто намного быстрее.

Мне также интересно, так как jsPerf и оптимизация селекторов для пары мс на 10000 выполнений так много размышляют, почему не так много разговоров об этом?По сути, это первая задержка, с которой сталкивается пользователь, и, кажется, довольно просто нарезать 50-100 мс при каждой загрузке страницы ...

Ответы [ 4 ]

8 голосов
/ 05 марта 2012

В первую очередь:

Нет, нет недостатка в том, чтобы позвонить вам init перед закрытием <body>. Он, как вы заметили, будет работать лучше, чем полагаться на $.ready(), а также будет работать со всеми браузерами. без нареканий (даже на IE).

Теперь есть причины использовать $.ready(), которые в вашем случае они, вероятно, не применяются:

  1. $.ready() позволяет разработчикам легко делать вещи в правильном порядке. В частности, важно не ссылаться на элементы DOM, которые не были загружены. Хотя это достаточно просто, многие разработчики все еще находят это в замешательстве. $.ready() легкая задача, хотя и медленная.
  2. Например, у вас есть несколько сценариев, которые должны init(), не обязательно просто / удобно вручную делать это в конце своего тела. Это требует дисциплины и знания того, что делают эти сценарии. В частности, вы часто будете видеть $.ready() в библиотеках, зависящих от jQuery, поскольку это заставляет вещи работать независимо от того, каким образом разработчики будут использовать для загрузки библиотек.
  3. Поскольку определение асинхронного модуля (например, require.js ) становится популярным в качестве способа загрузки вашего javascript, метод конца <body/> не гарантируется.
6 голосов
/ 04 марта 2012

Одним из преимуществ будет то, что вы можете разместить код в любом месте страницы.В нашем случае мы используем систему шаблонов в нашей CMS, которая объединяет страницу из 10-30 шаблонов для разных частей (в зависимости от сложности).

Поскольку вы хотите, чтобы шаблоны работали на любой страницеиспользуются, вы должны включить в него необходимый Javascript.В этих случаях функция ready() - это реальная возможность для жизни.

2 голосов
/ 05 марта 2012

Если вы написали JS-файл, который другие люди включают в свои страницы, безопаснее использовать document.ready внутри этого файла (при условии, что он должен выполнить некоторую обработку автоматически после того, как DOM будет готов), потому что вы не можетебудьте уверены, будет ли файл включен в заголовок или в конец тела.

Когда речь идет о страницах, которые вы полностью контролируете, тогда, очевидно, у вас нет такого беспокойства, поэтому я неЯ не вижу, что более «безопасно» использовать document.ready, чем вызывать ваш init() с конца тела.Использование document.ready (или onload) и помещение скрипта в конец тела - два наиболее распространенных способа сделать это, и они распространены, потому что они оба работают хорошо.

Вы упомянули document.write() каквозможное исключение, но вы не хотите вызывать это из document.ready или в конце тела, потому что в любом случае вся страница уже была проанализирована.

0 голосов
/ 13 ноября 2013

Потому что это замедляет работу domReady и window.load.

Легко оптимизировать в соответствии с метрикой, а не с точки зрения пользователя.Таким образом, графики «оптимизации реального пользователя» исчезают, даже если интерактивность задерживается.

...