Простими словами про Core Web Vitals і як їх оптимізувати навіть на WordPress
В Америці люди почали менше вмирати, в Китаї знову зросла народжуваність, а в Україну повернувся попит на програмістів. Життя знову стало прекрасним, і всім нам хочеться вірити, що у
За диво, на жаль, ручатися не можу. Але знаю, що цього року Google «опустить» сайти, які не привели Core Web Vitals до прийнятних показників.
Мене звати Андрій Грушецький, я фронтенд-інженер в SCE, і в ефірі місяць тому мені дали завдання оптимізувати WordPress-сайт на одному з наших проєктів. Там уже й так стояв плагін для оптимізації. Сайт непогано працював. Але Core Web Vitals були червоними. Тому одного разу в нас з Олексієм Цибульським, моїм менеджером, відбулася така розмова:
— Andrii, we need Core Web Vitals to be green.
— Nice choice. But WordPress is diryavaya hernya and I can’t help in this case.
— І що, ти так просто здався? Я ж не вимагаю гарантію результату. Спершу хоча б спробуй!
— Ну добре.
Я почав читати документацію, блукати просторами інтернету, мучити свою фантазію і чисто по приколу тицяти кнопочки в налаштуваннях плагінів. Потихеньку почало розвиднюватися, що й до чого. І за тиждень, якраз під католицьке Різдво, гірлянда Core Web Vitals засвітилася зеленими лампочками.
Тепер ми не просто не боїмося, що краулер нас покусає. Наш сайт і справді працює як «ракєта-бомба-пітарда»: у нього зросли бали в PageSpeed Insights, він став як музика Моцарта, як обійми коханої, як антипригарна пательня, як ковбаса по 10 копійок, як GTA San Andreas, як подушка з гречаного лушпиння... Він приємний!
Я трохи затягнув свій вступ (хто має розум, давно уже прогортав), але хто дотерпів — знайте: кожен активний користувач інтернету хоче, щоб user experience в інтернеті був саме такий!
Тому в статті я розкажу, що таке Core Web Vitals, чому вони такі класні, як оптимізувати сайт під них і що робити, якщо у вас JQuery і WordPress.
Тож до справи!
Що таке Core Web Vitals
Core Web Vitals — це три комплексні життєво важливі показники зручності сайту. Розгляньмо їх докладніше.
Largest Contentful Paint (LCP)
Це найменш зрозумілий із назви показник (гуглери теж іноді називають свої змінні трохи по-дурному, тому, якщо LCP поки ні про що вам не говорить, не бійтеся і читайте далі, все значно простіше).
Якщо дослівно, це render time of the largest image or text block visible within the viewport. А якщо по-людськи, то уявімо, що у вас Motorola G4. У неї є видима ділянка екрана, viewport. І та верхня частина документа, яка в цей viewport потрапляє, тобто є перший екран документа. На ньому розміщені різні елементи. Серед них блоки для декорації, тобто contentless-блоки. І є contentful-блоки — блоки зі змістом (текстові блоки, малюнки, відео).
Так от, ці блоки зі змістом мають різну площу. Той, у якого найбільша площа, і є Largest Contentful елемент.
А показник Largest Contentful Paint — це те, скільки мине часу, перш ніж у вас на головному екрані буде відрендереним Largest Contentful елемент.
Нюанс. Оцінювати треба не на новеньких Google Pixel 5, iPhone 11, MacBook, Asus ROG тощо. А на всякому старому лайні. Бо Google PageSpeed Insights перевіряє сайти на емуляторі середньостатистичного девайса. А в цю статистику входять не лише 800 млн європейців і американців, а й кілька мільярдів індусів і африканців. Тому, якщо вірити віконцю Lightroom, середньостатистичний девайс коштує $150, а швидкість інтернету — Middle end 3G (навіть якщо ваша цільова аудиторія може дозволити собі набагато більше).
Цей показник трохи костильний sophisticated. Є багато нюансів:
- якщо якийсь об’єкт частково поміщається на перший екран, а частково вилазить з нього, то аналізатор зверне увагу лише на ту площу, яка входить у перший екран;
- тільки духи каліфорнійських печер знають, як Lightroom відрізняє contentless-елементи від contentful;
- до уваги береться саме largest, тобто найбільший елемент зі змістом. Навіть якщо він з’явиться згодом.
Позичено із гуглової документації у сподіванні, що це буде корисно
Чому Largest Contentful Paint такий vital
Перший екран формує перше враження. До того ж користувач часто поспішає (а так багато хочеться йому розказати!). Саме тому кожен піксель на головному екрані дорожчий за мою київську квартиру (якої в мене, до речі, нема :).
Відповідно дизайнер ставить на перший екран найбільшим саме той елемент, який, на його думку, вартий найбільшої уваги. Той, у якому вся суть певної сторінки. Що раніше користувач може побачити це, то краще для користувача SEO ранжування сторінки.
Звісно ж, не завжди найбільше місця займає найсуттєвіший елемент. Але я чув про людей, що програмують ногами. І це справа смаку :)
Як поліпшити Largest Contentful Paint
Є багато варіантів розв’язку однієї й тієї ж задачі. Це не вичерпний список. Більше деталей є тут і тут.
А якщо коротко, то:
- Зменште час відповіді сервера і швидкість, з якою він передає файли:
- налаштуйте CDN;
- налаштуйте кешування;
- допишіть
rel="preconnect"
абоrel="dns-prefetch"
до<link>ів
на third-party джерела; - перейдіть до кращого провайдера;
- дайте нарешті піддупник девопсу.
- Зменште час, коли JS і CSS заважає браузеру рендерити перший екран (reduce renderblocking resources):
- налаштуйте мініфікацію файлів (як код, так і медіа);
- відкладіть некритичний JS (атрибут defer);
- прочитайте далі й дізнайтеся, як без поломок відкласти JQuery або іншу бібліотеку;
- підготуйте Critical CSS і поставте йому атрибут rel="preload«;
- змініть дизайн, щоб елементи на першому екрані було легше відмалювати;
- створіть кілька версій малюнків і використовуйте srcset;
- викиньте свій лайнокод і найміть замість себе тямущих людей :)
- Зламайте систему і зробіть так, щоб спершу завантажився тільки Largest Contentful елемент. А тоді уже хай буде, що буде. Без костилів або фреймворків не обійтися.
Щодо сервера, то це питання до DevOps (я фронтендер, у мене лапки). А стосовно render blocking resources — більш докладно (і як це зробити конкретно на WordPress) є трохи нижче.
First Input Delay (FID)
Якщо дослівно, це затримка перед першим входом. А якщо зрозуміло, то First Input Delay — це через скільки секунд браузер закінчить перетравлювати ваш код і користувач нарешті зможе взаємодіяти з вашим документом (ну тобто тицяти пальцем, клацати мишкою тощо).
Чому юзер не може взаємодіяти з файлом одразу
Бо браузер — це однопотокова залупа програма.
Так працюють браузери на WebKit
У Mozilla, здається, трішки по-іншому. І взагалі я не сильно експерт у двигунах браузерів. Та й стаття не про це.
Суть: для браузера слухання подій від користувача, рендеринг розмітки та виконання скриптів відбуваються в одному потоці. Одне за одним. І поки браузер зайнятий перетравленням вашого коду, користувач самотньо сидить у туалеті й намагається оживити пальцями мертвий екран!
І от той час, поки екран мертвий, поки браузер перетравлює код і нікого не слухає, це і є First Input Delay.
Важливий нюанс: час на завантаження файлів не враховується. Обчислюють, скільки треба часу, щоб кнопковий 2G телефон моєї бабусі пережував ваші фічі.
Найкраще це
Чому First Input Delay такий важливий
Бо я не люблю, коли мене ігнорують. І користувачі теж не люблять. Ніхто не любить, коли його ігнорують.
Як поліпшити First Input Delay
Більше деталей є тут і отут. Ну і, звісно, на просторах інтернету. Цей список теж не є вичерпним:
- Розріжте свій код на менші шматочки. Дайте браузеру спершу найнеобхідніше й тільки потім підсувайте все інше.
- Відкладіть всі некритичні скрипти (defer | async).
- Мініфікуйте файли.
- Використовуйте лише необхідні частини бібліотек (якщо є можливість).
- Відмовтеся від важких бібліотек (ну або хоча б відкладіть їхнє завантаження. Хак буде нижче).
- Викиньте свій лайнокод і перепишіть усе на вебворкерах.
Деякі з цих пунктів я вже згадував у Largest Contentful Paint, далі буде докладніше.
Cumulative Layout Shift (CLS)
— Це коефіцієнт, що вказує на те, яка площа документа «прострілює». Зрозумів?
— Нєа.
— Дивись.
Коли навіть комп’ютер тебе не розуміє :)
Звідки береться Cumulative Layout Shift
— З неправильної оптимізації Largest Contentful Paint і First Input Delay. Зрозумів?
— Нєа.
— Дивись.
Є, наприклад, сторінка блогу. Ми подумали «навіщо вантажити main thread браузера?» і через setTimeout виставили, щоб стилі під’єднувалися поступово. Спершу долучився один CSS-файл, і документ почав набувати певного вигляду. Потім за секунду підвантажився інший файл стилів, і вигляд одразу ж трохи змінився. Можливо, ми навіть налаштували поступове підвантажування елементів через AJAX. І вийшло, що спочатку браузер завантажив малюнок, потім текст під ним, відтак інтернет трошки поглючив, fetch затримався — і за якийсь час раптово вистрілив заголовок.
Ми стали гарними хлопчиками, зменшили render blocking resources і розвантажили main thread. Просимо в менеджера премію і плануємо з командою п’янку. А користувачі тим часом відкривають наш сайт, і в браузера починається епілепсія.
Як вимірюють CLS
Формула така: distance fraction * impact fraction = Cumulative Layout Shift
Площа, через яку все посунулось, — це distance fraction. Вимірюється в десяткових дробах від видимої площі екрана.
Площа, де сумарно змінився вигляд, — це impact fraction. Теж вимірюється як 0,6 від видимої площі екрана.
Отже, 0,15 * 0,6 = 0,09
Чому Cumulative Layout Shift такий важливий
Бо хоча все не завжди так драматично, як на відео вище, але я не люблю дивитися, як браузер тіпає мій екран. Хочеться викинути телефон у вікно і втекти в тундру. Там тихо віє вітер, шелестять ялинки, білочки їдять горішки, ескімоси ловлять рибу, нема інтернету, щоб відкривати жахливі сайти, і в усьому гармонія. А не ґє, ґє ґє, ґє-є!
Як поліпшити Cumulative Layout Shift
Дуже банально.
1. Робіть «заглушки» для елементів, а потім їх підвантажуйте (або хоча б під’єднайте lazy loading). Як, наприклад, тут:
Ілюстрацію взято з козирних книжок про personal brand :)
2. Прописуйте width і height атрибути (або aspect ratio) для своїх малюнків. Це автоматично зробить на місці медіафайлів «заглушки», і вони не посунуть інший контент.
3.Якщо маєте підвантажувати нові елементи, які повинні посунути інші, робіть це з анімаціями (бажано вбудованими в CSS, тобто іноді через @keyframes, а іноді через простий transform. Можна й через JS, аби плавно. Просто на JS-анімаціях аналізатор частіше глючить).
4.Хочете видалити елемент — анімуйте його зменшення. (Убийте його ніжно.)
5.Не гасіть у собі почуття прекрасного. Слухайте серце та створюйте комфортний інтерфейс.
* Про нюанси анімацій (вони теж бувають тяжкими для процесора) є гарна стаття Вадима Ільченка.
З цим, думаю, розібралися.
Як це зробити на WordPress
Стиснути файли
Немає нічого простішого за це. Можна встановити модуль для webpack, можна щоразу ручками через онлайн-компресори. Ми, наприклад, просто встановили плагін (Autoptimize).
Відкласти другорядний JS
Атрибути defer і async творять дива. Але що робити, якщо я хороший хлопчик і вставляю скрипти через wp_enqueue_script?
Можна стати поганим хлопчиком і прописати підключення скрипта в хедері. А то й підключати лише необхідні скрипти для конкретних сторінок, вставляючи їх перед футером.
Додати defer для jQuery
Зазвичай схожі плагіни пропонують ‘exclude jquery’, можна так і зробити. Але на правах маминого оптимізатора пропоную скористатися моїм костилем лайфхаком. Нам це суттєво знизило FID.
Ортодоксальний WordPress-розробник скаже, що так не можна. Мовляв, Мойсей заповідав не творити херні. Але Ісус для мене більший авторитет, і я думаю, що «вордпрес для юзера, а не юзер для вордпресу», тому пропоную зробити таке: забираємо jQuery з винятків для defer, а всі написані на jQuery-скрипти загортаємо в:
window.initJqueryCode = () => { setTimeout(() => { if (window.$ && 'has come to the party') { //paste your code here } else { console.info('DJ staying in jam. Disco will start little later'); window.initJqueryCode(); } }, 500) } window.initJqueryCode(
Аналогічне підходить і для інших бібліотек. Головне правильно підібрати умову, яка означатиме, що бібліотека завантажилась.
Підготувати Critical CSS
Це можна зробити руками. Можна дати клацати рабам джунам. Або скористатися онлайн-генератором на зразок цього (безкоштовний). Або й взагалі під’єднати плагін. Наприклад, оцей (платний, але це не реклама).
Підвантажуйте лише необхідні певному девайсу стилі
У тегу <link>
є атрибут media, туди можна писати правило як у звичайному CSS. Наприклад: <link href="/laptop.css" rel="stylesheet" media=”min-width: 576px”>
підвантажиться на девайсах, лише коли vieport має ширину понад 575px. Мобілки його просто проігнорують.
Змінити дизайн першого екрана
Бувають випадки, коли на першому екрані важкий спецефект чи інша недоступна дешевим телефонам фіча. Це має ефектний вигляд, й іноді це краще продає. Але деколи є сенс зробити спецефект трохи простішим й від того більше оптимізованим.
Створити кілька версій одного малюнка і під’єднати їх через srcset
Також можна через <picture>
і в ній source. Раптом що, ось документація srcset attribute і picture tag.
Якщо коротко, то це ви вказуєте @media-правило і зазначаєте, який файл під’єднати, коли це медіаправило спрацьовує. Аналогічно можна вказувати URL на різні background-файли з використанням CSS.
Це можна робити руками або загуглити плагін. Smush Pro наче непоганий.
Ніхто не забороняє використовувати .svg, коли випадає така можливість.
<video>
вийде набагато оптимізованішим за найоптимізованішу <img src=”_____.gif”>
. На жаль, у Safari атрибут autoplay не працює і для лоадерів не підійде (хоча можна написати маленький скрипт).
Подружитись із сервером ще до того, як почали щось в нього просити
А точніше скласти список, до яких third-party ресурсів під’єднується ваш сайт, тоді в head (або в плагіні, тому ж Autoptimize чи Perfmatters) прописати щось типу:
<link rel="preconnect" href=”домен1.com”>
<link rel="preconnect" href=”домен2.net”>
тощо.
Налаштувати кешування
Можна залазити на бекенд і власноруч прописувати конфігурації. Або вибрати та під’єднати плагін. У деталях це буде довго й багато (і часто з костилями). А якщо коротко, є Hummingbird Pro (він ще й на CDN може закинути ваші ресурси). Є Autoptimize. А є Google Search, де можна знайти ще більше.
Відмовитися від Google Fonts
Коли я верстав свій перший вебдокумент у 2017 році, це була best practice технологія і... так, це було круто. Але нещодавно через ризики для конфіденційності користувачів Google вимкнув кешування шрифтів.
Воно все працює. Але браузер щоразу завантажує шрифти заново. І зараз передати людині шрифт з власного сервера (і зразу ж закинути його в кеш для наступних разів) буде значно швидше, ніж щоразу йти до гуглу по його CDN.
Деталі тут, а щоб менше мучитись із прописуванням @font-face, скористайтеся безкоштовною утилітою. (Вона забуває дописувати font-display: swap; тому це краще зробити руками.)
Увімкнути lazy loading для медіафайлів
Уже вп’яте скажу це слово, але з цим прекрасно впорається Autoptimize. Однак важливо: якщо у вас малюнок є Largest Contentful елементом, треба додати його у винятки.
Розставити пріоритети у коді
Буває не так вже й просто. Я з цим ніяк не допоможу, плагінів, які вміли б думати як людина, теж не знаю.
Єдине, що може допомогти — це поставити себе на місце користувача і спитати: «Які фічі я хотів би побачити першими?». Наприклад, спершу робочий слайдер на головному екрані, потім кнопку live chat і аж потім всі інші фічі.
Чому вебворкери — це класно
Бо є один-єдиний рушій V8 і є написаний вами JavaScript-код. Зазвичай усі шматочки коду (колбеки) стають у чергу. І якщо V8 зайнятий, то вони просто стоять у черзі й чекають, поки у рушія дійдуть руки.
Вебворкери дають змогу виконувати ваші шматочки коду в окремих потоках і просто повертати в головний потік результат їхньої роботи.
Але! Код в сторонніх потоках не може взаємодіяти з DOM.
AJAX доступний і на WordPress
У WordPress я недавно, і поки потреби не виникало. Тому не знаю, як саме це робиться, але знаю, що ця фіча доступна. Чув навіть, що можна встановити React на WordPress і через AJAX API WordPress підтягувати у нього контент (звучить як пародія на кіберпанк, але про це писали на CSS-Tricks тут і тут).
Та не так важливо, якими інструментами, важливо, що якщо у вас є великі шматки контенту, то їх можна підвантажувати потроху. Це значно поліпшує FID і LCP.
Не використовуй document.write()
Я не впевнений за всі випадки. Може, деколи й можна. Але PageSpeed Insights на це голосно матюкається, а тому краще не треба.
Кілька очевидних моментів
- Дописуйте атрибути width і height (для CLS).
- Якщо не хочете атрибути, робіть aspect ratio (теж для CLS).
- 10 разів перевірте вплив бібліотеки на performance і лише тоді починайте її використовувати.
- Застосовуйте анімації, коли посуваєте розмітку, або робіть «заглушки», щоб не посувати розмітку взагалі.
- Обирайте «дешеві» анімації.
Але це стосується best practices. І коли ви створюєте сайт з нуля, вказаних до цього кроків достатньо.
Що робити з legacy-проєктом
Я б рекомендував молитися. Для початку хоча б по 5 хвилин на день. Молитва заспокоює ще краще за медитації, і тут без неї не обійтись.
Кожен legacy-проєкт прекрасний по-своєму, і я не можу дати таких конкретних порад, як «проганяй свій код через компресор», які допомогли б усім і всюди. Усе що, я можу, — це поділитися своїм ходом мислення і підходами, які колись допомогли.
Вигнати нечисть. Маю на увазі наявні малооптимізовані бібліотеки та плагіни. У нас був плагін WidgetKit від YOOtheme. Це потужний плагін, ним можна було додавати на сайт галереї, таби тощо. Але він тягнув за собою бібліотеку UIkit і закидав у браузер тонни скриптів (більшість з яких були непотрібні).
І от проста дія: клацнувши кнопочку deactivate біля цього плагіну, оцінка сайту на мобілках зразу ж збільшувалася на 10 балів. Нам пощастило. У нас була лише одна сторінка, де він використовувався, і я переписав це вручну. Але в кожного своє, і є випадки, коли треба реально переписувати пів сайту. Деколи це того варте, деколи ні. У будь-якому разі я рекомендую старатися вимітати всяку нечисть.
Покаятись. Це означає змінити своє мислення, підхід до життя. Не все так просто і не все зразу. Але все, що з вищеописаного можна впровадити в проєкт — треба впровадити (кешування, defer для скриптів, мініфікація файлів тощо).
Якщо проєкт продовжує розвиватися і час від часу треба додати нову фічу або сторінку, потрібно тим паче каятись і починати хоч тепер писати оптимізовані під Core Web Vitals фічі.
Знов-таки в усіх своє, але відкривають тому, хто стукає. Тому вище хвіст і тільки вперед.
Якщо самі не «витягуєте», використовуйте плагіни. Навіть просто встановіть Autoptimize і потицяйте там галочки — це вже може підняти performance на
Там є і кешування, і lazy loading, і defer для скриптів (а також стилів), і preconnect, і мініфікація файлів, і ще три не згадані вище можливості:
- Парсинг стилів із .css-файлів в інлайнові стилі кожного елемента (якщо повторюваних елементів небагато, то це працює майже на рівні з Critical CSS).
- Збирання кількох файлів в один. Це зменшує кількість запитів на сервер. Деколи це може допомогти перейти із червоного в жовтий і не померти в очах Google crawler.
- Очищення вшитих і непотрібних вордпресових наворотів. Наприклад, вбудованих emoji.
На Autoptimize світ не зійшовся. Є ще купа інших плагінів. Якщо маєте час і бажання, варто погратися з ними. Там можуть бути свої фічі. І вони теж можуть допомогти.
Замість закінчення
Хочу нагадати, що є багато шляхів розв’язку однієї й тієї ж задачі. Тому можна і треба вмикати фантазію та ділитися порадами в коментах (я теж не експерт, і мені теж цікаво буде повчитись).
Web Vitals не єдина запорука вдалого SEO. Та й SEO не єдина запорука вдалого бізнесу. Більшість сайтів орієнтована на Захід, і там значно потужніші за гугловий емулятор девайси. Та й часто тих кілька секунд не такі вже й важливі.
Всюди треба мати голову на плечах і деколи вміти просто забити замість того, щоб палити шалені ресурси, щоб виграти 100ms.
Ну й хочу побажати:
- керівникам брати приклад з мого керівника і частіше надихати людей на виклики;
- дизайнерам вміти не просто думати: «Ой, туть така бусінка класіва, хоцю-хоцю-хоцю», а придумувати зручні, орієнтовані на користувачів інтерфейси (від яких у програмістів не підгорить);
- нам, інженерам, — терпіння та успіхів. Вірю, у нас все вийде.
Ну й усім нам приємного дива в новому році. Після