Как намалихме времето за зареждане на site до под една секунда
Скоростта не е суетна метрика — тя движи класирането и приходите. Ето точната работа по производителността, която извършваме при всеки build, в реда, който има най-голямо значение.
Повечето бавни уебсайтове не са бавни поради мистериозни причини. Те са бавни поради шепа предвидими проблеми, натрупани един върху друг — и се коригират в предвидим ред. Когато клиент дойде при нас с три секунди време за зареждане, рядко се нуждаем от екзотични трикове. Нуждаем се от дисциплина.
Това е същият контролен списък (checklist), който изпълняваме при всеки ангажимент за производителност, приблизително по ред на приоритет. Всяка стъпка е евтина спрямо въздействието си, а повечето sites се усещат драстично по-бързи след първите три.
Измерете, преди да докоснете каквото и да било
Не можете да подобрите това, което не измервате, и определено не можете да докажете подобрение без изходно ниво (baseline). Започваме всеки ангажимент с данни от реална среда (field data), а не просто с лабораторни резултати.
- Лабораторни — Lighthouse и WebPageTest за контролирана, възпроизводима моментна снимка.
- Реални (Field) — метрики за реални потребители (CrUX / RUM) за това, което хората действително изпитват.
- Бюджет — твърд таван за всеки маршрут (route), така че регресиите да се улавят в CI, а не в production.
Лабораторен резултат от 100 не означава нищо, ако вашите реални потребители използват телефони от среден клас и нестабилни мрежи. Оптимизирайте за реална среда (field).
Елиминирайте ресурсите, блокиращи рендирането (render-blocking)
Единствената най-голяма победа при повечето sites е изваждането на CSS и JavaScript от критичния път. Браузърът не може да изобразява (paint), докато не приключи с парсването на блокиращите рендирането ресурси — така че колкото по-малко са те, толкова по-бързо се появява нещо.
// defer everything that isn't critical
const load = () => import('./analytics.js');
if ('requestIdleCallback' in window)
requestIdleCallback(load);
else setTimeout(load, 2000);
Вградете (inline) малкото количество CSS, необходимо за първия екран (viewport), след което заредете останалата част асинхронно. Отложете (defer) некритичните скриптове. Целта е първото изобразяване (first paint) да не чака нищо, което не му е абсолютно необходимо.
Отнасяйте се към изображенията като към бюджет
Изображенията обикновено са най-тежкото нещо на една страница и най-лесното за сгрешаване. Три правила покриват деветдесет процента от случаите:
- Предоставяйте съвременни формати — AVIF или WebP — с алтернатива (fallback).
- Оразмерявайте изображенията спрямо техните рендирани размери; никога не изпращайте 3000px hero изображение в 600px слот.
- Зареждайте мързеливо (lazy-load) всичко под видимата част (below the fold) и резервирайте пространство, за да избегнете изместване на оформлението (layout shift).
Кеширане в периферията (edge)
След като страницата е олекотена, следващият въпрос е колко бързо байтовете достигат до потребителя. CDN с разумни заглавни части за кеширане (cache headers) превръща 600ms пътуване до оригиналния сървър в 30ms достъп от edge. За динамично съдържание, stale-while-revalidate ви дава незабавни отговори, докато се обновява във фонов режим.
Производителността е функционалност. Планираме бюджет за нея по същия начин, по който планираме бюджет за всяка друга част от изработката (build).
Резултатът
При проекта, който вдъхнови тази статия, началната страница премина от 3,1s до 0,9s largest contentful paint, а органичните конверсии се увеличиха измеримо в рамките на месеца. Нищо от това не беше магия — просто контролният списък по-горе, приложен по ред.
Ако вашият site се усеща муден и не сте сигурни откъде да започнете, свържете се с нас — един кратък одит обикновено разкрива двете или трите промени, които имат най-голямо значение.