Почему в 2025 году стоит отказаться от jQuery ради $(document).ready?
Если вы всё ещё пишете $(document).ready(function() { ... }) — вы либо работаете с легаси-проектом, либо упускаете возможности современного JavaScript. В 2025 году jQuery — это как телефон с кнопками: работает, но все уже давно перешли на сенсорные экраны.
На Stack Overflow вопрос $(document).ready equivalent without jQuery собрал сотни тысяч просмотров. Это значит, что разработчики по всему миру ищут лёгкие, быстрые и современные способы выполнить код после загрузки DOM. И ответ прост: нативная поддержка браузеров уже давно покрывает 100% потребностей, которые когда-то решал jQuery.
В этой статье мы разберём 3 лучших способа заменить $(document).ready на чистый JavaScript, обсудим нюансы производительности и покажем реальные примеры кода, которые вы сможете использовать прямо сегодня.
DOMContentLoaded — главный герой без jQuery
Самый прямой аналог $(document).ready — это событие DOMContentLoaded. Оно срабатывает, когда браузер полностью загрузил и разобрал HTML-документ, но до загрузки изображений, стилей и других ресурсов. Именно это и делал jQuery под капотом.
Вот как выглядит базовый синтаксис:
document.addEventListener('DOMContentLoaded', function() {
// Ваш код выполнится после полной загрузки DOM
console.log('DOM полностью загружен и готов к работе!');
document.querySelector('.header').style.color = '#2c3e50';
});
Почему это лучше jQuery?
- Скорость: Не нужно загружать 30+ КБ библиотеки ради одной функции.
- Контроль: Вы точно знаете, что происходит в момент загрузки.
- Совместимость: Работает во всех современных браузерах (IE9+, Chrome, Firefox, Safari, Edge).
Но есть нюанс: если ваш скрипт подключается после загрузки DOM, событие уже не сработает. Решение — проверка document.readyState:
function ready(fn) {
if (document.readyState !== 'loading') {
fn(); // DOM уже загружен
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
ready(function() {
console.log('Гарантированно выполнится после загрузки DOM');
});
Этот паттерн — золотой стандарт для замены $(document).ready в 2025 году.
Атрибут defer: самый простой способ без единой строки кода
А что если я скажу, что можно вообще не писать DOMContentLoaded? Атрибут defer в теге <script> делает всю работу за вас:
<script src="script.js" defer></script>
Как это работает? Браузер загружает скрипт параллельно с HTML, но выполняет его только после полного разбора документа. Это эквивалентно тому, что весь код внутри script.js автоматически обёрнут в $(document).ready.
Плюсы:
- Нуль дополнительного кода — просто добавьте атрибут.
- Скрипты с
deferвыполняются в порядке их появления в HTML. - Работает в 97% браузеров (включая старые версии Safari).
Когда использовать? Идеально для обычных скриптов, которые должны работать с DOM, но не блокируют рендеринг. Например:
<script src="analytics.js" defer></script>
<script src="app.js" defer></script>
<!-- app.js выполнится после analytics.js, но до window.onload -->
Сравните с jQuery: $(document).ready внутри app.js — это лишний код. А с defer вы просто пишете:
// app.js — никаких обёрток, чистый код
document.querySelector('.button').addEventListener('click', function() {
alert('Современный JavaScript без jQuery!');
});
async vs defer: что выбрать для вашего проекта?
Многие путают async и defer. Давайте разберём разницу раз и навсегда:
- defer: Скрипт выполняется после загрузки HTML, в порядке очереди. Идеально для замены
$(document).ready. - async: Скрипт выполняется сразу, как только загрузится, не дожидаясь DOM. Подходит для независимых скриптов (счётчики, реклама).
Вот наглядный пример для образовательного сайта pythonlib.ru:
<!-- Замена $(document).ready — используем defer -->
<script src="dom-manipulation.js" defer></script>
<!-- Независимый скрипт — async -->
<script src="https://example.com/analytics.js" async></script>
Важно: Если вы используете async, не надейтесь, что DOM будет доступен. Для гарантии загрузки DOM всё равно придётся использовать DOMContentLoaded внутри скрипта.
Полная замена $(document).ready: готовый полифилл
Для тех, кто хочет максимально точный аналог $(document).ready без jQuery, вот готовое решение, которое можно скопировать в свой проект:
// Полный аналог $(document).ready на чистом JS
window.docReady = function(fn) {
// Создаём функцию, которая проверяет состояние DOM
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', fn);
} else {
// DOM уже загружен — выполняем немедленно
setTimeout(fn, 0); // setTimeout для асинхронности
}
};
// Использование
docReady(function() {
console.log('Это полная замена $(document).ready');
document.querySelectorAll('.article').forEach(article => {
article.classList.add('loaded');
});
});
Почему это лучше jQuery?
- Вес: 0.5 КБ против 30+ КБ.
- Прозрачность: вы контролируете каждую строчку.
- Производительность: нет лишних абстракций.
Но в 2025 году я рекомендую не писать такие полифиллы, а просто использовать defer + DOMContentLoaded для сложных сценариев. Это быстрее, чище и поддерживается всеми браузерами.
Практический пример: переписываем jQuery-код на vanilla JS
Давайте посмотрим, как будет выглядеть реальный код на образовательном сайте pythonlib.ru до и после