Глава 1. Що таке клієнтська оптимізація?



  • 1.1. Цілі і завдання оптимізації
  • Основні завдання оптимізації
  • Короткий огляд технологій
  • 1.2. Психологічні аспекти продуктивності
  • Терпиме час очікування
  • Ефекти повільній швидкості завантаження
  • Як час відповіді сайту впливає на призначену для користувача психологію
  • 1.3. Стадії завантаження сторінки
  • розставляємо пріоритети
  • Вузькі місця
  • 1.4. Клієнтська і серверна оптимізація: схожість і відмінності
  • Кешування на чільне місце
  • Менше запитів - легше сервера
  • Архівувати і кешувати на сервері
  • Хто у кого на службі?
  • 1.5. Застосування в розробці додатків
  • Етап 1: Доставка інформації та оформлення
  • Етап 2: Кешування файлів оформлення і паралельні запити
  • Етап 3: Життя після завантаження сторінки
  • Етап 4: Попереджаємо дії користувача
  • Глава 1. Що таке клієнтська оптимізація?

    1.1. Цілі і завдання оптимізації

    Кожна веб-сторінка складається з основного HTML-файлу і набору зовнішніх ресурсів. Говорячи про розмір сторінки (або сайту), дуже часто мають на увазі розмір саме першого файлу, що, природно, не так. Рис.1 .1. Тенденція зміни розміру сторінки і числа об'єктів для сайтів, перевірених через Web Optimizator в 2008 році В даний час на кожній сторінці викликається кілька десятків зовнішніх об'єктів, а розмір початкового файлу складає не більше 5% від загального розміру. Як показали численні дослідження, розмір веб-сторінки за останні 5 років збільшився втричі, а кількість об'єктів на ній - майже в два рази. При цьому темпи зростання середньої пропускної здатності каналу лише трохи вище даних показників. Якщо враховувати розшарування користувачів за швидкостями доступу, то прагнення зменшити число користувачів, що перевищують допустимий поріг очікування на 1-5%, змушує застосовувати все більш складні і передові технології. Природно, що технології ці не обмежуються стисненням текстових (HTML, CSS, JavaScript) файлів на стороні сервера. Як нескладно зрозуміти, основну частину зовнішніх об'єктів на сторінці складають зображення або мультимедійні файли. І для них теж є свої методи оптимізації.

    Основні завдання оптимізації

    Якщо говорити коротко, то можна виділити 3 основних завдання клієнтської оптимізації: Оптимізація розміру файлів. Оптимізація затримок при завантаженні. Оптимізація взаємодії з користувачем.

    Короткий огляд технологій

    При цьому всі основні методи можна розбити на 6 груп (кожна з яких дозволяє вирішити одну із заявлених завдань). Зменшення розміру об'єктів. Тут фігурують стиснення і методи оптимізації зображень, докладніше про це можна прочитати у другому розділі. Особливості кешування, які здатні кардинально зменшити число запитів при повторних відвідинах, розкриваються в третьому розділі. Об'єднання об'єктів. Основними технологіями є злиття текстових файлів, застосування CSS Sprites або data: URI для зображень. Цьому присвячена четверта глава книги. Паралельне завантаження об'єктів, що впливає на ефективний час очікування кожного файлу. У п'ятому розділі крім цього наведені приклади балансування запитів з боку клієнтського додатку. Оптимізація CSS-продуктивність, що проявляється в швидкості появи первісної картинки в браузері користувача і швидкості її подальшого зміни. Про CSS-продуктивності розповідає шоста глава. Оптимізація JavaScript. Є досить багато проблемних місць в JavaScript, про які необхідно знати при проектуванні складних веб-додатків. Про все це можна прочитати в сьомому розділі. Хочеться відзначити, що, незважаючи на всю складність зачепленої теми, початкового прискорення завантаження веб-сторінки можна домогтися в кілька дуже простих кроків. При цьому можна скоротити час появи веб-сторінки в кілька (зазвичай в 2-3) разів. Всі поради в книзі впорядковані по збільшенню складності впровадження та зменшення можливого виграшу при завантаженні сторінки. Для простих веб-проектів можна обмежитися тільки включенням кешування та архівування (gzip або deflate). Більш складним знадобиться змінити верстку, використовуючи CSS Sprites або data: URI, і додати кілька хостів для завантаження зображень. Для високонавантажених проектів (деякі з них проаналізовані в кінці восьмий глави) потрібно враховувати всі аспекти клієнтської оптимізації з самого початку при проектуванні і застосовувати їх послідовно для досягнення найкращого результату.

    1.2. Психологічні аспекти продуктивності

    Згідно з численними дослідженнями призначене для користувача роздратування сильно зростає, якщо швидкість завантаження сторінки перевищує 8-10 секунд без жодного повідомлення користувача про процес завантаження. Останні роботи в цій області показали, що користувачі з широкосмуговим доступом ще менш терпимі до затримок при завантаженні веб-сторінок в порівнянні з користувачами з більш вузьким каналом.

    У проведеному в 2007 році опитуванні було встановлено, що 33% користувачів швидкісного сполучення не хочуть чекати при завантаженні сторінки більше 4 секунд, при цьому 43% користувачів не чекають понад 6 секунд. В даному випадку мається на увазі, що користувач в більшості випадків покине сайт, якщо протягом 5-10 секунд буде бачити замість нього білий екран в браузері.

    Терпиме час очікування

    При дослідженні, проведеному в 2004 році, було встановлено, що терпиме час очікування для непрацюючих посилань (без зворотного зв'язку) знаходилося між 5 і 8 секундами. З додаванням повідомлення користувача про процес завантаження (зворотного зв'язку), наприклад, індикатора завантаження, такий час очікування збільшилася до 38 секунд. Розподіл часу для повторних спроб зайти на непрацюючі посилання мало максимум в районі 23 секунд (без наявності будь-яких індикаторів, що показують, що сторінка завантажується або в даний момент недоступна).

    Таким чином, можна зробити висновок, що для 95% користувачів час очікування відповіді від непрацюючого сайту складе не більше 8 секунд. Якщо врахувати прагнення користувача відвідати сайт повторно, то дослідження продемонстрували вкрай мале (майже рівне нулю) число користувачів, що чекають більше 10 секунд.

    Ефекти повільній швидкості завантаження

    Навіть малі зміни часу завантаження можуть мати значні наслідки. Так, для Google ( http://www.google.com/ ) Збільшення часу завантаження для сторінки з 10 пошуковими результатами на 0,4 секунди і на 0,9 секунд для сторінки з 30 результатами позначилося на зменшенні трафіку і рекламних доходів на 20% (згідно з дослідженнями, проведеними в 2006 році). Коли головну сторінку Google Maps ( http://maps.google.com/ ) Зменшили в обсязі з 100 Кб до 70-80 Кб, трафік збільшився на 10% протягом першого тижня і ще на 25% в наступні три тижні (за даними 2006 року).

    Тестування в 2007 році для Amazon дало дуже близькі результати: кожні 100 мс збільшення часу завантаження для Amazon.com зменшували продажу на 1%. Експерименти Microsoft для Live Search ( http://www.live.com/ ) Показали, що при уповільненні завантаження сторінок на 1 секунду кількість скинутих пошукових запитів зросла на 1% і число кліків по рекламі зменшилася на 1,5%. При збільшенні часу завантаження сторінки з результатами ще на 2 секунди кількість скинутих пошукових запитів зросла на 2,5% і число кліків по рекламі зменшилася на 4,4%.

    Як час відповіді сайту впливає на призначену для користувача психологію

    Користувачі відчувають, що сайти, які завантажуються повільно, менш надійні і менш якісні. У разі, якщо утримувати час завантаження в межах «терпимого», користувачі будуть відчувати набагато менше незадоволеності від відвідування сайту, середнє число переглядів сторінок зросте, збільшиться конверсія відвідувачів і знизиться число відмов. Сайти, які швидко завантажуються, також здаються користувачам більш цікавими і привабливими.

    «Терпиме» час буде сильно залежати від аудиторії, але його можна досить надійно перевірити: для цього потрібно значно (наприклад, в 2-3 рази) збільшити (або зменшити) час затримки при показі сторінки і подивитися на число відмов (число користувачів, які закрили сторінку відразу після заходу на сайт) і на число постійних відвідувачів. Якщо при сильному збільшенні (або зменшенні) затримки при завантаженні сайту кількість користувачів практично не змінилося, значить, сторінка вже завантажується в допустимих межах. Якщо ж число користувачів зазнало видимі зміни, то, отже, з часом завантаження сайту потрібно щось робити.

    Користувачі широкосмугового доступу очікують більшої швидкості завантаження, при цьому користувачам з менш швидкісним доступом доводиться чекати набагато довше. У міру того як високошвидкісний доступ проникає в маси, зростає також і розмір сторінки. Користувачі відчувають психологічні і фізіологічні проблеми при взаємодії з «повільними» веб-сторінками, відчувають роздратування, якщо не можуть завершити свої завдання, і наснагу при роботі з швидкими сайтами.

    1.3. Стадії завантаження сторінки

    Мал. 1. 2. Стадії завантаження сторінки

    В якості основних проблемних місць при завантаженні сторінки будь-якого веб-ресурсу можна виділити чотири основні речі.

    Предзагрузкі - поява сторінки в браузері користувача. Після деякого часу очікування завантаження при заході на веб-ресурс у користувача в браузері відображається намальована сторінка. У цей момент, ймовірно, на сторінці відсутні малюнки і, швидше за все, в повному обсязі функціонує JavaScript-логіка.
    Інтерактивна завантаження - поява інтерактивності (і анімації) у завантаженій веб-сторінки. Зазвичай вся клієнтська логіка взаємодії доступна відразу після первинного завантаження сторінки (стадія 1), проте в деяких випадках (про них мова піде трохи далі) підтримка цієї логіки може (і повинна, на самом деле) трохи запізнюватися за часом від появи основної картинки в браузері користувача.
    Повне завантаження сторінки. Сторінка повністю з'явилася в браузері, в ній бере участь вся заявлена ​​інформація, і вона практично готова до подальших дій користувача.
    Пост-завантаження сторінки. На даній стадії повністю завантажена сторінка може (в невидимому для користувача режимі) здійснювати завантаження і кешування деяких ресурсів або компонентів. Вони можуть знадобитися користувачеві як при переході на інші сторінки даного сайту, так і для відображення будь-яких анімаційних ефектів або додавання функціоналу заради зручності використання.

    Для більшості сайтів на даний момент стоїть розрізняти тільки предзагрузкі (в яку за замовчуванням включається інтерактивна завантаження) і повне завантаження сторінки. Пост-завантаження, на жаль, зараз використовується вкрай мало.

    розставляємо пріоритети

    Оптимізація швидкості завантаження веб-сторінки зосереджена на двох ключових аспектах: прискорення предзагрузкі і прискорення основної завантаження. Всі основні методи сфокусовані саме на цьому, тому що «завантаження» веб-сторінки сприймається користувачами як щось що знаходиться посередині цих двох стадій.

    В ідеалі завантаження сторінки для користувача повинна закінчуватися відразу після предзагрузкі, однак домогтися цього досить складно, і виправдано це далеко не у всіх випадках. Детальніше про методи екстремальної оптимізації буде розказано в кінці четвертого розділу.

    Вузькі місця

    Перша і друга стадії завантаження є найбільш проблемними аспектами при аналізі продуктивності. Це цілком зрозуміло: завантаження початкового HTML-файлу, так само як і CSS- / JavaScript-файлів йде в один потік, - і на перше місце виходить зменшення числа запитів при завантаженні.

    Як тільки вузьке місце подолано (в ідеалі, у нас повинен бути один-єдиний файл, який отримує користувач) і в браузері сторінка відобразилася, ми можемо почати запитувати з сервера всі інші ресурси. Найголовніше, що це можна робити за допомогою десятків додаткових з'єднань (як цього домогтися, розповідається в п'ятому розділі), бо в браузері вже відбулася подія готовності документа до подальших дій.

    Ми можемо налаштувати логіку кешування, послідовну завантаження JavaScript-модулів або навіть пост-завантаження стильових правил. Все це вже буде слабо відбиватися на фактичної швидкості первинного завантаження: користувач бачить сторінку в браузері, може з нею взаємодіяти (нехай навіть спочатку і не в повному обсязі), для нього вона вже завантажилася (правда, тільки з психологічної, а не з технічної сторони ).

    Але всі ці прийоми можуть як прискорити завантаження наступних для користувача сторінок, так і впорядкувати саму пост-завантаження. Як досягти цього ефекту і як розподілити файли і клієнтську логіку між стадіями завантаження сторінки, розказано в четвертому розділі.

    1.4. Клієнтська і серверна оптимізація: схожість і відмінності

    Клієнтська оптимізація оперує двома основними принципами: менше даних і менше з'єднань. Але саме ці принципи допомагають зменшити навантаження на сам сервер. Давайте подивимося, як це відбувається і як перенести частину серверної навантаження на клієнтський браузер.

    Кешування на чільне місце

    Сервер може керувати станом кеша клієнтського браузера, по-перше, через заголовок Cache-Control (і його атрибути max-age, pre-check, post-check), який може вказувати на проміжок часу, протягом якого цей файл слід зберігати на диску і не запитувати з сервера. Рекомендується для всіх статичних файлів виставляти максимальний час життя кешу і форсувати його оновлення у користувача через зміну URL ресурсу (за допомогою RewriteRule або GET-параметра).

    По-друге, станом клієнтського кеша можна управляти через заголовки ETag і Last-Modified, які ставлять у відповідність кожному файлу унікальний ідентифікатор, що змінюється при зміні файлу, - своєрідна цифровий підпис або хеш. При цьому сервера потрібно не пересилати файл заново, а лише відповісти статус-кодом 304 на запит браузера, якщо файл не змінився з моменту останнього запиту. В результаті сам файл не пересилається, з'єднання (і сокет) звільняється швидше, і ресурси сервера також економляться.

    Детальніше про кешуванні розповідається в третьому розділі.

    Менше запитів - легше сервера

    Використовуючи об'єднання файлів, ми не змушуємо сервер обмінюватися з браузером заголовками для передачі, наприклад, кількох таблиць стилів - набагато економічніше буде їх об'єднати в одну. При цьому браузер швидше отримає всю необхідну інформацію і швидше звільнить такий важливий ресурс, як з'єднання.

    Поряд з об'єднанням текстових файлів не варто нехтувати і об'єднанням картинок. Якщо враховувати, що сучасні браузери можуть встановлювати кілька десятків одночасних з'єднань з сервером для отримання статичних файлів (і 80% з них - це саме картинки), то економія від використання CSS Sprites, Image Map або data: URI підходу розраховується дуже просто. У деяких випадках вдається зменшити число з'єднань браузера з сервером для завантаження однієї HTML-сторінки в 8-10 разів.

    Об'єднання файлів розглядається в четвертому розділі.

    Архівувати і кешувати на сервері

    Як показали проведені дослідження, gzip-стиснення текстового файлу «на льоту» в 95-98% випадків дозволяє скоротити час на передачу файлу браузеру. Якщо зберігати заархівовані копії файлів на сервері (в пам'яті proxy-сервера або просто на диску), то з'єднання в загальному випадку вдається звільнити в 3-4 рази швидше.

    У разі високонавантажених серверів з динамічними HTML-файлами gzip також може бути застосовний. Тут варто орієнтуватися на мінімальну ступінь стиснення, бо процесорні витрати при цьому ростуть лінійно, а розмір зменшується лише логарифмічно.

    Про стисненні розповідає наступна глава.

    Хто у кого на службі?

    Після проведеного огляду технологій може здатися, що клієнтська оптимізація є лише складовою частиною серверної. Однак це не так: при побудові високопродуктивних веб-додатків повинен бути присутнім і клієнтський, і серверний підхід. В цьому випадку можна говорити про пересічної області відповідальності, але ніяк не про превалювання однієї логіки над іншою.

    Коли справа доходить до взаємодії «клієнт-сервер», потрібно пам'ятати про всі аспекти оптимізації. І у клієнтської складової є своя, виділена область відповідальності. Вона знаходиться в вікні браузера - це веб-сторінка, яка завантажується у користувача і з якої він взаємодіє.

    1.5. Застосування в розробці додатків

    Користувачі зазвичай не знають, які підходи застосовуються при розробці, як налаштований сервер, які клієнтські і серверні кошти розробки використовуються. Для них лише важливо, наскільки сайт корисний, зручний і швидкий. Завдання ж веб-розробників полягає в тому, щоб не доставляти користувачеві зайвих незручностей, радувати його і тим самим стимулювати продажі, що йдуть через сайт, або число рекламних показів і кліків по ним. Нижче розповідається, як можна організувати створення веб-додатки, орієнтуючись на найважливіші аспекти клієнтської оптимізації.

    Етап 1: Доставка інформації та оформлення

    На цьом етапі розробник повінні сделать все можливе, Щоб не сповільніті ШВИДКІСТЬ завантаження Сторінки. Фактично йдет про прискореного Першої стадії завантаження. Найбільш важлівімі методами тут є стисненими (gzip) текстових файлів и об'єднання файлів стілів (CSS). Для CSS- і JavaScript-файлів можна використовувати статичну архівування (без необхідності архівувати кожен раз ці файли «на льоту»; цьому присвячений другий розділ). При завантаженні сторінки браузер запросить все CSS-файли, оголошені в head сторінки, послідовно. Тому кожен файл додає затримку в завантаженні, рівну часу запиту до сервера (навіть якщо припустити, що встановлюється з'єднання keep-alive та нам не потрібно здійснювати всі TCP / IP-процедури, - в іншому випадку ми економимо набагато більше). Для файлів скриптів рекомендується застосувати або також об'єднання, або взагалі винести їх в пост-завантаження (докладніше про це читайте в сьомому розділі). Підсумок першого етапу - це доставлений і оформлений HTML. І витрати на доставку JavaScript зведені до мінімуму (на цьому етапі він тільки заважає, оскільки уповільнює відображення основного вмісту сторінки). Час від початку до завершення завантаження такої сторінки при включеному і вимкненому JavaScript (при винесенні його в пост-завантаження) фактично буде однаковим. Це і буде виграшем в швидкості завантаження!

    Етап 2: Кешування файлів оформлення і паралельні запити

    На даному етапі розробники повинні забезпечити швидке завантаження інших сторінок сайту (якщо відвідувач вирішить туди перейти). Цей етап повинен проходити паралельно з першим. Налаштування кешуючих заголовків досить тривіальна. Дещо складніше налагодити процес розробки для своєчасного скидання кешу. Всі ці питання розкриваються в третьому розділі. Одне або кілька додаткових дзеркал для видачі статичних ресурсів легко налаштовуються в конфігурації, проте впровадити це в схему публікації змін набагато складніше. Зазвичай це роблять вже після розробки макетів сторінок. Число додаткових хостів слід безпосередньо з числа статичних файлів (зазвичай картинок), тому треба визначитися з ними на етапі автоматизації процесу публікації. Про паралельних запитах розповідається в п'ятому розділі. CSS Sprites досить трудомісткі в автоматичній «склейці», тому їх впроваджують зазвичай на першому етапі (при створенні макета сторінок). При використанні методу data: URI на першому етапі про них можна забути, тому що автоматизоване рішення просто в реалізації і не вимагає від верстальника окремих технологічних знань. Про це можна прочитати в четвертому розділі.

    Етап 3: Життя після завантаження сторінки

    Метою даного етапу є створення різних обробників подій, які повинні взаємодіяти з користувачем. Це можуть бути і спливаючі підказки, і подгрузка даних з сервера, і просто анімація. Все це можна назвати «пожвавленням» сторінки. Кажуть, що іноді «грам видимості важливіше кілограма суті» - це якраз про JavaScript. Адже саме на ньому можна реалізувати механізми, що спрощують дії користувача; можна зробити багато різних візуальних ефектів, що підкреслюють оформлення, зручність і корисність сайту (а фактично - посилити і сфокусувати всю роботу, яку виконали розробники на попередніх етапах). До цього моменту ми повинні мати оформлену HTML-сторінку, на якій всі посилання і форми зобов'язані працювати без JavaScript (як цього домогтися, як відокремити уявлення сторінки від її функціонування, розповідається в сьомому розділі в розділі про «ненав'язливий» JavaScript). У нас повинні бути готові серверні інтерфейси для AJAX-запитів; структура сторінки повинна бути такою, щоб для аналогічних шматків HTML-коду не доводилося реалізовувати аналогічні, але не однакові шматки JavaScript-коду. Швидше за все, повинні бути створені шаблони сторінок, де видно, як буде виглядати сторінка після якоїсь дії користувача (зазвичай фахівець по зручності використання створює макети). Щоб не зменшувати швидкість доставки контенту і оформлення, JavaScript-файли (найкраще, звичайно, один JavaScript-файл, кілька файлів повинні використовуватися тільки при великої складності клієнтського інтерфейсу) повинні бути підключені перед закриттям тега body (а в ідеалі - винесені саме в пост -Завантаження). Завдання по забезпеченню взаємодії користувача з інтерфейсом сайту зводиться до виконання наступних дій:

    знайти DOM-елементи, що вимагають «пожвавлення» (далі - компоненти);

    визначити, що це за компонент;

    забезпечити підключення необхідного коду JavaScipt;

    стежити за черговістю підключення файлів;

    не дозволяти декількох завантажень одного файлу.

    Все це безпосередньо випливає з концепції «ненав'язливого» JavaScript, яка описана в сьомому розділі. Пошук необхідних DOM-елементів повинен нам дати список назв JavaScript-компонентів. Назви компонентів повинні однозначно відповідати назвам файлів на сервері, в яких міститься код для них. Також нам може знадобитися завантажити деякі додаткові CSS-правила для знайдених компонентів (в разі невеликої кількості CSS-коду розумно буде включити його в основний файл) заради якихось візуальних ефектів, які можна пропустити на першому етапі завантаження. Наприклад, всі ефекти зі зміни зображення при наведенні миші забезпечуються через CSS-правила і техніку CSS Sprites. Список назв компонент можна об'єднати в один запит до сервера. У підсумку на стадії пост-завантаження повинні здійснюватися запити до файлів виду static.site.net/jas/componentName1.css;componentName2.css і static.site.net/jas/componentName1.js; c omponentName2.js. У даного підходу є два недоліки: В папці / jas / (яку ми, наприклад, використовуємо для кешування найбільш частих варіантів підключення модулів) через деякий час може виявитися дуже багато файлів, що теоретично може зменшити час доступу до них на сервері. Іноді на сторінці може виявитися дуже багато компонент, причому так багато, що довжина імені запитуваного об'єднаного файлу перевалить за можливості файлової системи (наприклад, 255 символів у Ext3) - в цьому випадку буде потрібно розбити один запит на кілька послідовних.

    Етап 4: Попереджаємо дії користувача

    Якщо після відвідування головної сторінки більшість користувачів потрапляють всередину сайту, то логічно буде після повного завантаження головної сторінки запитувати стилі і скрипти, що застосовуються на інших сторінках сайту. Для користувача це виллється в невелике збільшення трафіку (при використанні стиснення текстова інформація становить 10-20% від обсягу графіки), однак у цілком помітне прискорення завантаження наступних сторінок. Аналогічно можна розглянути і предзагрузкі деяких найбільш часто використовуваних картинок, які відсутні на головній сторінці, і додаткових JavaScript-модулів, які застосовуються на поточній сторінці для додаткового функціоналу і не запитуються при першому завантаженні сторінки (наприклад, відповідають за спочатку приховані блоки). Природно, що за балансування третьої і четвертої стадій відповідає вже JavaScript-розробник і фронтенд-архітектор - адже саме в зоні відповідальності останнього знаходиться швидкість завантаження сторінки.


1. Що таке клієнтська оптимізація?
Хто у кого на службі?