Если ваш сайт грузится дольше трёх секунд — половина посетителей уйдёт, даже не дождавшись. Часто виноват не хостинг и не PHP, а JavaScript, который блокирует отрисовку страницы. В этой статье разберём, как ускорить загрузку и выполнение скриптов, не превращая код в кашу. Вы узнаете, какие атрибуты спасают, а какие — вредят, и как применять современные методы без боли.
Ссылка на оригинальную статьюЧто происходит, когда браузер встречает script
Браузер читает HTML сверху вниз. Когда он натыкается на тег <script> без атрибутов, он останавливается, скачивает файл, выполняет его, и только потом продолжает строить страницу. Это как если бы вы ехали по дороге и перед каждым перекрёстком останавливались на час — даже если перекрёсток пустой.
Такой подход называется блокирующим. Он гарантирует, что скрипт выполнится до того, как пользователь что-то увидит, но ценой скорости. Особенно плохо, если скриптов много или они тяжёлые.
Атрибуты defer и async: как не блокировать загрузку
Чтобы браузер не останавливался, придумали два атрибута: defer и async. Они говорят браузеру: «скачивай скрипт в фоне, а выполнишь потом». Но между ними есть разница.
| Атрибут | Когда скачивается | Когда выполняется | Порядок выполнения |
|---|---|---|---|
| defer | Параллельно с парсингом HTML | После полного разбора документа | В порядке появления в HTML |
| async | Параллельно с парсингом HTML | Сразу после скачивания | Не гарантируется |
Правило: если скрипт зависит от других скриптов или от DOM — используйте defer. Если скрипт независим (например, счётчик аналитики) — async.
Пример правильного подключения:
<script src="app.js" defer></script>
<script src="analytics.js" async></script>
Минификация и сжатие: делаем файлы легче
Когда вы пишете код, вы ставите пробелы, переносы строк, комментарии — это удобно для чтения, но браузеру всё равно. Минификация убирает лишнее, уменьшая размер файла на 30-50%.
Сжатие (gzip или brotli) — это как упаковка чемодана вакуумным пакетом. Сервер сжимает файл, браузер распаковывает. Разница в скорости загрузки ощутима.
Как это делается на PHP? Например, можно настроить сжатие через .htaccess:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/javascript application/javascript
</IfModule>
Или использовать PHP-функцию ob_gzhandler:
ob_start('ob_gzhandler');
// остальной код
Лайфхак: используйте сборщики (Webpack, Vite), чтобы автоматически минифицировать скрипты при сборке. Это экономит время и исключает ошибки.
Code splitting: грузите только то, что нужно
Представьте, что вы заказываете пиццу, а вам привозят целый ресторан. Так и с JavaScript: если вы подключаете библиотеку для слайдера на всех страницах, а используете её только на одной — вы заставляете браузер скачивать лишнее.
Code splitting (разделение кода) позволяет разбить скрипт на части и загружать их по мере необходимости. Это делается с помощью динамического импорта:
// Вместо того чтобы подключать слайдер статически
// import Slider from './slider';
// Делаем динамический импорт, когда он нужен
async function initSlider() {
const { default: Slider } = await import('./slider');
new Slider('#my-slider');
}
Браузер загрузит слайдер только тогда, когда вызовется функция initSlider. Это ускоряет первую загрузку страницы.
Оптимизация выполнения: не блокируйте главный поток
JavaScript выполняется в одном потоке. Если скрипт делает тяжёлые вычисления, страница «зависает». Пользователь видит белый экран или невозможность кликнуть.
Чтобы этого избежать, разбивайте тяжёлые задачи на части или используйте requestAnimationFrame для анимаций и setTimeout для отложенных операций.
Пример разбиения тяжёлого цикла:
function processLargeArray(items) {
let index = 0;
function processChunk() {
const chunkSize = 100;
for (let i = 0; i < chunkSize && index < items.length; i++, index++) {
// тяжёлая обработка элемента
heavyOperation(items[index]);
}
if (index < items.length) {
// откладываем следующий кусок
setTimeout(processChunk, 0);
}
}
processChunk();
}
Этот подход заставляет браузер дышать, а не задыхаться.
Практические советы для PHP-разработчиков
Вы пишете на PHP, но JavaScript — ваш постоянный спутник. Вот что можно сделать прямо сейчас:
- Переносите скрипты в конец страницы перед
</body>, если не используетеdefer. - Используйте атрибут
deferдля скриптов, которые должны выполниться после загрузки DOM. - Проверяйте размер скриптов в DevTools: если больше 100 КБ — задумайтесь о разделении.
- Настройте кеширование на сервере, чтобы браузер не скачивал скрипты повторно.
- Используйте CDN для популярных библиотек (jQuery, React) — они могут быть уже в кеше у пользователя.
Пример настройки кеширования в PHP:
header("Cache-Control: public, max-age=31536000");
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 31536000) . " GMT");
Что в итоге
Оптимизация JavaScript — это не магия, а набор простых действий. Используйте defer и async, минифицируйте файлы, разбивайте код на части и не блокируйте главный поток. Ваши пользователи скажут спасибо, а сайт станет быстрее.
Помните: скорость — это не роскошь, а необходимость. Каждая секунда задержки — это потерянные посетители и деньги.



