Web Performance

Preload, prefetch и preconnect: кога всеки от тях наистина помага

Подсказките за ресурси са полезни, когато отговарят на реални тесни места в браузъра. Използвани на сляпо, те добавят шум в приоритетите и понякога правят страниците по-бавни.

The Wux Webtools Team The Wux Webtools Team 2 мин четене С подкрепа от ИИ, прегледано от човек
A simplified browser loading waterfall showing early resource hints for a web page.
Съдържание
  1. Подсказките за ресурси не са магия
  2. Какво браузърът вече прави добре
  3. Preload: за ресурси на текущата страница, открити твърде късно
  4. Preload и LCP изображения
  5. Prefetch: за следващата страница, не за тази
  6. Preconnect: за скъпи връзки към важни origin-и
  7. DNS-prefetch: по-лекият братовчед
  8. Как да решите: практичен workflow
  9. 1. Идентифицирайте тясното място
  10. 2. Добавяйте по една подсказка наведнъж
  11. 3. Проверете страничните ефекти върху приоритетите
  12. 4. Проверете headers и кеширането
  13. Чести грешки
  14. Preload на твърде много неща
  15. Използване на prefetch за задължителни ресурси
  16. Preconnect към всяка third party
  17. Забравяне на мобилните условия
  18. Проста таблица за вземане на решение
  19. Спокойното правило

Подсказките за ресурси не са магия

preload, prefetch и preconnect често се третират като списък за проверка на производителността. Добавяте няколко тага в <head>, пускате Lighthouse отново и се чувствате по-добре. Но те не работят така.

Тези подсказки са инструкции към зареждащия механизъм на браузъра. Те могат да помогнат, когато знаете нещо, което браузърът не може да открие достатъчно рано. Могат и да навредят, когато гадаете, давате прекалено висок приоритет на некритична работа или подготвяте връзки, които потребителите никога няма да използват.

Кратката версия:

  • Използвайте preload за ресурси, нужни на текущата страница, но открити твърде късно.
  • Използвайте prefetch за вероятни ресурси при бъдеща навигация, а не за съществени ресурси на текущата страница.
  • Използвайте preconnect за важни външни origin-и, при които установяването на връзка е реално забавяне.

Практичният въпрос не е „коя подсказка е най-бърза?“. Той е „какво чака браузърът и може ли тази подсказка да премахне това чакане?“

Какво браузърът вече прави добре

Съвременните браузъри не са пасивни програми за изтегляне на файлове. Те парсват HTML, сканират напред за ресурси, задават приоритети, преизползват връзки, отлагат работа, която не е видима, и се адаптират към мрежовите условия.

Това означава, че подсказките за ресурси трябва да се използват избирателно. Ако stylesheet, script, image или font вече се открива рано и получава правилния приоритет, добавянето на подсказка може да не направи нищо. Още по-лошо — може да започне да се конкурира с ресурси, които са по-важни.

Преди да добавяте подсказки, разгледайте waterfall trace в DevTools или лабораторен отчет. Ако използвате Lighthouse, започнете с диагностиките, а не с резултата; имаме отделно ръководство за четене на Lighthouse отчет без паника — но имайте предвид, че правилният URL е case-sensitive, така че при нужда използвайте свързаната статия от навигацията на сайта си.

Истинските доказателства обикновено се виждат на три места:

  1. Критичен ресурс започва късно, защото браузърът го открива късно.
  2. Връзка към важен origin отнема забележимо време преди първата заявка.
  3. Ресурс за следващата страница е силно предвидим и евтин за изтегляне в idle време.

Ако нито едно от тези неща не е вярно, подсказката вероятно е украса.

Preload: за ресурси на текущата страница, открити твърде късно

preload казва на браузъра: „Изтегли този ресурс сега, защото текущата страница ще има нужда от него.“

Типичен пример е web font, рефериран вътре в CSS. Браузърът трябва да изтегли HTML, да открие CSS, да изтегли CSS, да го парсне, да открие шрифта и чак тогава да поиска шрифта. Ако този шрифт е важен за текста във видимата част на страницата, откриването може да е достатъчно късно, за да причини layout shifts или забавено рендиране на текста.

Preload може да изтегли тази заявка по-рано:

<link rel='preload' href='/fonts/inter-var.woff2' as='font' type='font/woff2' crossorigin>

Атрибутът as е важен. Той казва на браузъра какъв вид ресурс е това, което влияе върху приоритета, кеширането, content security policy и request headers. Шрифтовете обикновено също имат нужда от crossorigin, дори когато се сервират от същия сайт, защото извличането на шрифтове използва CORS режим.

Добри кандидати за preload включват:

  • Основният web font, използван за видим текст.
  • Hero изображение, което е Largest Contentful Paint елементът и не може да бъде открито рано.
  • Критичен CSS файл, зареждан индиректно.
  • Module или script, нужен много рано, но скрит зад друг script.

Лоши кандидати за preload включват:

  • Всяко тегло на шрифта в дизайн системата.
  • Изображения под видимата част на страницата.
  • Scripts, които не са нужни за първоначалното рендиране.
  • Ресурси, които браузърът вече открива в първия HTML chunk.

Preload е мощен, защото влияе върху приоритета на текущата страница. Точно затова е и лесен за неправилна употреба. Ако preload-нете пет големи asset-а, вече не помагате на браузъра. Спорите с него.

Шрифтовете са класическият случай. Preload на един основен font файл може да помогне. Preload на шест тегла и italic варианти обикновено влошава нещата. Ако шрифтовете са вашето тясно място, първо оправете набора от шрифтове; нашето ръководство за това защо web fonts все още са най-лесната победа за производителността на повечето сайтове разглежда това почистване по-подробно.

Preload и LCP изображения

Preload на LCP изображение може да бъде полезен, когато изображението не се вижда в първоначалния HTML. Чести причини са CSS background images, компоненти, рендирани от клиента, или responsive image логика, която се появява късно.

Но ако вашето hero изображение вече е в HTML като <img> със смислени srcset, sizes, dimensions и без lazy loading, браузърът вероятно може да го намери бързо. В този случай добавянето на fetchpriority='high' може да е по-подходящо от preload, в зависимост от страницата.

Добър тест: ако заявката за изображението започва късно във waterfall и то става LCP елементът, обмислете preload. Ако започва рано, но се изтегля бавно, проблемът е размер, формат, поведение на CDN или server latency — не откриване. За решения относно форматите на изображения вижте кога AVIF побеждава WebP и кога не.

Prefetch: за следващата страница, не за тази

prefetch казва на браузъра: „Този ресурс може скоро да е нужен, но не е необходим точно сега.“

Това разграничение е важно. Prefetch умишлено е с нисък приоритет. Браузърът може да го изтегли в idle време и да го съхрани за по-късна употреба. Може също да го пропусне при лоши връзки, режими за пестене на данни или при натиск върху паметта.

Използвайте prefetch, когато намерението на потребителя е достатъчно силно, за да направи следващия ресурс вероятен.

Добри кандидати за prefetch включват:

  • Следващата стъпка в многостраничен checkout.
  • Резултати от търсене, след като потребителят започне да въвежда заявка, ако следващият route е предвидим.
  • Страници от документация, свързани от съдържание, когато потребителят активно чете близко съдържание.
  • Route chunks в single-page app, след като потребителят hover-не или фокусира навигационен елемент.

Лоши кандидати за prefetch включват:

  • Цялото ви навигационно дърво.
  • Големи видеа или галерии с изображения.
  • Third-party scripts „за всеки случай“.
  • Страници, които потребителите рядко посещават след това.

Prefetch е мястото, където сдържаността се отплаща. Ресурс, който е изтеглен и никога не е използван, не е безплатен. Той консумира bandwidth, server capacity, енергия и евентуално потребителски данни. В мобилни мрежи спекулативното изтегляне може да бъде активно недружелюбно.

За много сайтове най-добрата prefetch стратегия е базирана на намерение. Не prefetch-вайте страницата с цени веднага щом началната страница се зареди. Prefetch-нете я, когато потребителят отвори менюто с цени, hover-не линка към цените или скролне близо до call-to-action, който силно предсказва навигация.

Помнете също, че поведението на браузърите варира. Някои браузъри са консервативни с prefetch; някои настройки за поверителност намаляват или изключват спекулативното зареждане. Третирайте prefetch като опортюнистично подобрение, а не като механизъм за коректност.

Preconnect: за скъпи връзки към важни origin-и

preconnect казва на браузъра: „Започни да установяваш връзка към този origin сега.“

Това може да включва DNS lookup, TCP connection и TLS negotiation. За third-party origin-и тази подготовка може да отнеме стотици милисекунди, особено в мрежи с висока latency. Ако страницата скоро се нуждае от критична заявка от този origin, preconnect може да направи по-късната заявка по-бърза.

Пример:

<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>

Добри кандидати за preconnect включват:

  • Font origin, използван за render-blocking текст.
  • Критичен API origin, нужен по време на първоначално взаимодействие.
  • CDN origin, който сервира asset-и във видимата част на страницата.
  • Payments или identity provider, нужен веднага след действие на потребителя.

Лоши кандидати за preconnect включват:

  • Analytics и advertising endpoints, които не са критични за потребителя.
  • Origin-и, използвани само в някои сесии.
  • Дълги списъци с third parties.
  • Same-origin ресурси, при които браузърът вече има или скоро ще отвори връзката.

Preconnect има разход за поддържане. Отворените sockets консумират памет и мрежови ресурси. Браузърите ще затворят неизползваните връзки, но това не прави ненужните preconnect-и безвредни.

Полезно правило: правете preconnect към най-много един или два third-party origin-а с висока увереност на страница. Ако се изкушавате да добавите повече, вашата third-party архитектура вероятно има нужда от преглед повече, отколкото подсказките ви имат нужда от разширяване.

DNS-prefetch: по-лекият братовчед

Може да срещнете и dns-prefetch:

<link rel='dns-prefetch' href='https://example-cdn.com'>

Това само резолвва домейн името. Не отваря TCP или TLS връзка. По-евтино е от preconnect, но и помага по-малко.

DNS-prefetch може да е разумен за third-party origin-и с по-ниска увереност, при които пълен preconnect изглежда твърде агресивен. На практика, ако origin е критичен и със сигурност ще се използва скоро, предпочетете preconnect. Ако е само възможен, използвайте DNS-prefetch или не правете нищо.

Как да решите: практичен workflow

Започнете с измерване, не с тагове.

1. Идентифицирайте тясното място

Отворете performance trace и търсете късно откриване. Дали заявката за font, hero image или script започва едва след като друг файл е изтеглен и парснат? Това е кандидат за preload.

Ако заявка започва едва след дълга DNS/TCP/TLS подготовка към third-party origin, това е кандидат за preconnect.

Ако текущата страница е наред, но следващата навигация е предвидимо бавна, prefetch може да помогне.

2. Добавяйте по една подсказка наведнъж

Подсказките за ресурси си взаимодействат. Добавете една, тествайте я и я запазете само ако waterfall се подобри и метриките, видими за потребителите, не се влошат.

При preload наблюдавайте дали подсказаният ресурс действително се използва скоро. Chrome може да предупреди, когато preload-нат ресурс не се използва скоро след зареждането. Приемайте това предупреждение сериозно.

3. Проверете страничните ефекти върху приоритетите

Preload може да отклони bandwidth от CSS, JavaScript или изображения, които са по-важни. Preconnect може да заеме connection slot. Prefetch може да добави фонов трафик.

Правилният резултат не е „подсказаният файл започва по-рано“. Правилният резултат е „страницата става осезаемо по-добра за потребителите“. Гледайте LCP, INP, CLS и real-user monitoring, когато е възможно.

4. Проверете headers и кеширането

Подсказките могат да се изпращат в HTML или HTTP Link headers. Headers са полезни, когато сървърът знае рано от какво ще има нужда страницата, но са по-трудни за неформална проверка. Ако debug-вате дали подсказка действително присъства в production, raw headers имат значение; това е точно типът ситуация, разгледан в нашето ръководство за debugging на redirects и HTTP headers.

Кеширането също има значение. Preload на ресурс с несъответстващи credentials, грешен as или различни URL параметри може да причини двойни изтегляния. Това е един от най-честите начини добронамерен preload да се превърне в performance bug.

Чести грешки

Preload на твърде много неща

Ако всичко е критично, нищо не е. Ограничете preload до ресурси, нужни за първоначално рендиране или незабавна интерактивност. Типична страница трябва да има от нула до три preload-а, не двадесет.

Използване на prefetch за задължителни ресурси

Prefetch е с нисък приоритет и е опционален. Не го използвайте за asset-и, нужни на текущата страница. Ако страницата има нужда от него сега, обмислете preload или нормално откриване чрез HTML.

Preconnect към всяка third party

Страниците с много third-party ресурси често имат десет или повече външни origin-а. Preconnect към всички тях създава шум. Изберете един или два, които са едновременно критични и предвидимо използвани.

Забравяне на мобилните условия

Подсказките за ресурси са най-ценни при по-бавни връзки, но там са и най-опасни. Пропилян prefetch на бърза desktop връзка е пренебрежима грешка. При ограничен мобилен план това е лоша размяна.

Проста таблица за вземане на решение

| Ситуация | Най-добра подсказка | Защо | |---|---:|---| | Критичен шрифт, открит чрез CSS | preload | Текущата страница се нуждае от него, откриването е късно | | Hero изображение, скрито зад CSS или client rendering | preload | Може да подобри LCP, ако изображението започва късно | | Вероятен следващ route след потребителско намерение | prefetch | Помага на бъдеща навигация, без да блокира текущата страница | | Критичен third-party font/API origin | preconnect | Премахва установяването на връзка от критичния път | | Възможен, но несигурен third-party origin | dns-prefetch или нищо | По-нисък разход, по-ниска увереност | | Изображение под видимата част на страницата | нищо | Оставете lazy loading и приоритетите на браузъра да работят |

Спокойното правило

Подсказките за ресурси работят най-добре, когато са скучни и конкретни. Един шрифт. Едно LCP изображение. Един важен third-party origin. Един вероятен следващ route след намерение.

Те работят зле, когато се използват като оптимизъм: може би потребителят ще има нужда от това, може би браузърът трябва да изтегли онова, може би повече подсказки означават повече скорост.

Браузърите вече оптимизират агресивно. Вашата работа не е да микроменажирате всяка заявка. Вашата работа е да коригирате малкото случаи, в които на браузъра му липсва информация в правилния момент.

Често задавани въпроси

Трябва ли да preload-на всички мои шрифтове?
Не. Preload-вайте само font файловете, нужни за видимия текст рано в страницата. Preload на всяко тегло и стил обикновено хаби bandwidth и може да забави по-важни ресурси.
Безопасно ли е да използвам prefetch за всеки вътрешен линк?
Обикновено не. Това може да създаде ненужен фонов трафик и да хаби потребителски данни. Предпочитайте prefetch, базиран на намерение, например след hover, focus, отваряне на меню или предвидима следваща стъпка.
Каква е разликата между preconnect и dns-prefetch?
Preconnect извършва DNS, TCP и TLS setup за origin. DNS-prefetch само резолвва домейн името. Preconnect е по-силен, но по-скъп, затова трябва да се използва с по-голяма увереност.
Могат ли подсказките за ресурси да подобрят Core Web Vitals?
Да, особено LCP, когато коригират късно откриване или установяване на връзка за критичен ресурс. Те няма да помогнат, ако истинският проблем са прекалено големи asset-и, бавен server response, render-blocking code или лошо кеширане.
Трябва ли подсказките за ресурси да се добавят в HTML или в HTTP headers?
И двата варианта могат да работят. HTML е по-лесен за осмисляне при подсказки, специфични за страницата. HTTP Link headers могат да са полезни, когато сървърът знае критичните ресурси преди HTML да бъде парснат, но изискват внимателно тестване, за да се избегнат дубликати или остарели подсказки.

Източници и допълнително четене

  1. MDN: rel=preload
  2. MDN: Resource hints
  3. web.dev: Preconnect and DNS-prefetch
  4. W3C: Resource Hints
За автора
The Wux Webtools Team

Последно обновление:

Продължете да четете