Client optimization
July 2011 15

Оптимизация скорости мобильных сайтов

Вместе с ростом мобильного интернета растёт и необходимость оптимизации скорости работы мобильных сайтов. Даже самые современные смартфоны на Android, iOS, WebOS, BlackBerry OS и др. обладают процессорами с частотой не более 1Ghz, а скорости 3G можно считать достаточно медленными (скорость загрузки в 3 раза меньше DSL).

Мобильные устройства унаследовали проблемы “больших” машин: от количества http-запросов до эффективности работы JavaScript.

Особенности мобильных устройств


Кроме того, что они часто помещаются в карман и их легче потерять, существует несколько ключевых отличий мобильных устройств по отношению к десктопам:
  • маленькое разрешение экрана;
  • медленные соединения;
  • ограниченный размер кэша;
  • много различных устройств и форм-факторов;
  • низкая мощность процессоров;
  • широкая поддержка HTML5;
  • относительно новые браузеры (в этом мире не знают о IE6).


Общие рекомендации


Мобильным сайтам присуще большинство проблем производительности “больших сайтов”, поэтому многие перечисленные техники пришли из десктопной оптимизации.
  • используйте gzip для сжатия текстовых данных;
  • помещайте CSS в заголовке HTML документа, а JavaScript в нижней части страницы;
  • объединяйте файлы JavaScript и CSS, которые используются по всему сайту. Это позволит сократить количество HTTP запросов, что крайне критично для мобильных сайтов;
  • используйте минимизацию и обфускацию кода CSS и JavaScript;
  • JS и CSS которые используются только 1 раз на сайте, а также небольшие JS и CSS (до 5 kB), лучше включать прямо в страницу, т.е. не выносить в отдельные файлы;
  • многие мобильные браузеры (например, Android или Opera Mobile) имеют общее ограничение на количество соединений не более 4-6. Использование для таких браузеров доменного шардинга может только навредить скорости сайта;
  • в то же время браузер Android поддерживает конвейерную обработку HTTP, что позволяет передавать на сервер сразу 3 запроса в одном соединении. Не забудьте убедиться, что сервер также поддерживает конвейерную обработку HTTP;
  • очень важно правильно (без видимых потерь в качестве) сжимать файлы — используйте, например, Smush.it — подробнее об этом;
  • избегайте или по крайней мере делайте кэшируемыми редиректы;
  • для iOS используйте Quicktime Reference Movies, это позволяет “отдавать” посетителю разные видео-файлы, исходя из возможностей его интернет-соединения.
  • пользуйтесь преимуществами WebSockets там, где это возможно (полная поддержка есть пока только в iOS Safari 4.2-4.3, частичная в Opera Mobile 11.1).

Оптимизация HTML и CSS


Широкая поддержка HTML5 и CSS3 в мобильных браузерах позволяет использовать самые современные техники для оптимизации сайтов:
  • HTML код должен быть предельно простым. Используйте семантические элементы HTML5, указывайте <!DOCTYPE html>, исключайте необязательные атрибуты xmlns. Также старайтесь сократить количество div-ов и классов;
  • старайтесь реже использовать input, а если и использовать, то в форматах HTML5;
  • используйте CSS-градиенты вместо фоновых картинок — это кардинально сократит количество обращений к серверу;
  • CSS даёт много других полезных возможностей, применение которых более эффективно, чем картинок (тени, закруглённые границы, множественные фоны, встроенные в страницу svg и canvas).

Оптимизация изображений


Наряду с борьбой против лишних обращений к серверу, очень важно минимизировать размеры загружаемых файлов. В этой перспективе оптимизация изображений является наиболее важным элементом.
  • используйте CSS-спрайты для оптимизации логотипов и иконок ;
  • в html и css кодируйте изображения в base64 — очень эффективный способ, т.к. поддерживается большинством мобильных браузеров, а кодировка происходит на стороне сервера. Помимо PHP — base64_encode(), можно использовать HTML5 технологию из Canvas — toDataURL();
  • кодируйте в Unicode пиктограммы Emoji вместо картинок (поддерживаются начиная с iOS 2.2, а также в многими японскими телефонами);

У мобильных устройств экраны имеют значительно меньшее разрешение, чем экраны десктопов. CSS позволяет нам определять текущее разрешение экрана пользователя и в зависимости от этого передавать ему ту версию картинки, которая имеет более подходящее разрешение.

/* Screens bigger than 480px */
@media only screen and (min-device-width: 481px) {
#header { background-image: url(header-full.png); }
}

Код выше определяет, что ширина экрана пользователя больше, чем 480px и даёт указание браузеру загружать картинку header-full.png с полноценным разрешением
А вот следующий фрагмент кода, определив, что ширина экрана меньше 480px, предлагает браузеру картинку, адаптированную под маленькие экраны:

/* Screens smaller than 480px */
@media only screen and (max-device-width: 480px) {
#header { background-image: url(header-small.png); }
}

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

Однако прежде всего заботьтесь над удобством пользователя. Используя тот же принцип (отдельный контент для мобильных и десктоп устройств), можно сделать сайт приятным для просмотра пользователям с экранами высокого разрешения, в то же время не навредив остальным посетителям.
Например, пользователи iPhone 4 уже привыкли к тому, что на экране их телефона должны быть изображения с высоким DPI (напр. 300). И если вы хотите, чтобы ваш сайт не смотрелся убого на Retina экранах, нужно будет готовить еще один отдельный набор картинок в высоком разрешении и загружать их, используя CSS Media Queries

/* High dpi */
@media only screen and (min-resolution: 300dpi),
  only screen and (-webkit-min-device-pixel-ratio: 1.5),
  only screen and (min--moz-device-pixel-ratio: 1.5) {
#header { background-image: url(header-300dpi.png); }
}

/* Low dpi */
@media only screen and (max-resolution: 299dpi),
  only screen and (-webkit-max-device-pixel-ratio: 1.5),
  only screen and (max--moz-device-pixel-ratio: 1.5) {
#header { background-image: url(header-72dpi.png); }
}

Это как раз тот случай, когда стоит поступиться производительностью в пользу удобству пользователей.

Оптимизация в зависимости от скорости соединения


Начиная с версии Android 2.2 Froyo у разработчиков появилась возможность получать данные о текущем типе подключения к интернету у устройства. Реализуется это при помощи объекта navigator.connection.

Вот пример данных, получаемых с устройства, которое работает в 3G сети:

navigator = {
connection: {
"type": "4",
"UNKNOWN": "0",
"ETHERNET": "1",
"WIFI": "2",
"CELL_2G": "3",
"CELL_3G": "4"
}
};

Тип соединения “4”, что соответствует CELL_3G. Используя простой скрипт можно определить тип соединения и передать эту информацию как CSS класс в HTML элементе.

// Initialize variables
var connection, connectionSpeed, htmlNode, htmlClass;

// Create a custom object fallback if navigator.connection isn't available
connection = navigator.connection || {'type':'0'};

// Set connectionSpeed
switch(connection.type) {
case connection.CELL_3G:
  // 3G
  connectionSpeed = 'mediumbandwidth';
break;
case connection.CELL_2G:
  // 2G
  connectionSpeed = 'lowbandwidth';
break;
default:
  // WIFI, ETHERNET, UNKNOWN
  connectionSpeed = 'highbandwidth';
}

// set the connection speed on the html element, i.e. <html class="lowbandwidth">
htmlNode = document.body.parentNode;
htmlClass = htmlNode.getAttribute('class') || '';
htmlNode.setAttribute('class', htmlClass + ' ' + connectionSpeed);

В результате при определении низкоскоростного соединения мы передаём браузеру посетителя оптимизированные картинки, используя CSS:

.highbandwidth .logo   { background-image:url('logo-high.jpg'); }
.mediumbandwidth .logo { background-image:url('logo-medium.jpg'); }
.lowbandwidth .logo    { background-image:url('logo-low.jpg'); }


И всё-таки не стоит лишать пользователей выбора (не будем диктаторами). Поэтому хорошим тоном будет помимо распространённого выбора:
  • версия сайта desktop | mobile

Давать также выбор:
  • скорость соединения: High | Medium | Low

Пользуйтесь простыми правилами — “если пикселей не видно, их не надо загружать”, но в то же время “не стоит решать за пользователя, ему можно рекомендовать”.

Кэширование


Если в случае с десктопами в большинстве случаев решение будет в пользу внешних файлов, то с мобильными скорее всего наоборот. Из-за маленьких размеров кэша, говорить о большой и долгосрочной экономии не приходится. Есть ряд советов по оптимизации скорости повторной загрузки страниц:
  • кэшируйте ajax;
  • устанавливайте заголовки актуальности файлов на далёкое будущее (far-future cache expiration headers);
  • избегайте cookies, вместо этого используйте localStorage (cookies передаются http-запросами, значительно увеличивая размер передаваемых данных). LocalStorage и SessionStorage — это технологии HTML5, которые являются более эффективной альтернативой cookies. Там же можно хранить и внешние CSS и JavaScript;

Важным ограничение для LocalStorage и SessionStorage является то, что они могут хранить только данные типа String. Поэтому следует данные предварительно переводить в строковый формат, а впоследствии восстанавливать в оригинальном при помощи JSON.stringify() и JSON.parse():

var user = {
  firstName: 'Joe',
  lastName: 'Schmoe',
  age: 40
}

// Store the object
localStorage.userInfo = JSON.stringify(user);

// Retrieve the object
var user = JSON.parse(localStorage.userInfo);

Размеры данных которые могут храниться в этих объектах разнятся от браузера к браузеру, но 5 Mb должно хватить в большинстве.
Интересный момент — устройства на Android и BlackBerry OS умеют хранить кэш даже после включения/выключения девайса, в то же время iPhone этим похвастаться не может.
Смартфоны iPhone 4 Galaxy S Nexus S Blackberry Torch
OS / Ver iOS/4.3 Android 2.2 Android 2.3 Blackberry 6
Постоянный* 0 4 4 25
В памяти** 100 4 4 25
Планшеты iPad 1 iPad 2 XOOM
OS / Ver iOS/4.3 iOS/4.3 Android 3.0
Постоянный* 0 0 20
В памяти** 20 50 20
*Постоянный — это кэш, который остаётся, даже после перезапуска браузера.
**В памяти — это кэш, который хранится в оперативной памяти (напр. — при переключении между приложениями). Подробнее о кэше в мобильных устройствах можно прочесть в блоге компании Blaze.

Оптимизация javascript


Недостаточная мощность процессоров в мобильных устройствах, вновь делает актуальным борьбу за снижение нагрузки. Так исследования компании Google показывают, что парсинг каждого 1 КБ кода JavaScript составляет приблизительно 1 мс.
  • избегайте javascript timeout анимации, вместо этого лучше использовать CSS3 переходы (но не все браузеры полностью поддерживают эту технологию, поэтому стоит иметь “запасной” олдскульный вариант на этот случай)
  • на touch-устройствах обработчики кликов приводят к задержке в 300-500 мс, что достаточно много, поэтому для таких девайсов лучше использовать “родные” обработчики — ontouchend;
  • используйте только необходимые части больших фрэймворков (напр. jQuery), а не их целиком. Ещё оптимальнее будет применять маленькие фрэймворки (XUI, zepto.js, microjs);
  • стремитесь к минимизации javascript в формах, лучше использовать HTML5, там, где это возможно;
  • ещё одним полезным достижением HTML5 является использование баз данных, которые хранятся на стороне клиента. Среди существующих решений наибольшую популярность получила indexedDB (надеемся, что в скором времени данная технология начнёт поддерживаться мобильными браузерами);
  • используйте ajax (onhashchange — для управления историей) и запрашивайте только то, что нужно изменить;
  • загружайте JS асинхронно основному содержанию;
  • уменьшайте стартовые задержки. Например, команда Gmail Mobile предложила интересный способ “ленивой” подгрузки модулей;
Суть этого способа в том, что сначала нужно разбить крупные программные модули на более мелкие и распределить, какие из их необходимо грузить на старте загрузки страницы, а какие позже. Также важно, что “отложенные” модули будут загружаться по мере их вызова действиями пользователей. Такая загрузка, действительно выглядит ленивой: пока не пнёшь — не пошевелится.

Заключение


Значение оптимизации скорости работы мобильных сайтов становится важнее сейчас, когда пользователи всё больше используют смартфоны для решения повседневных задач в интернете.

Интересно, что большинство людей более нетерпимы к медленной работе сайтов именно при использовании смартфонов. Часто это связано со специфическими задачами, которые нужно решить в течении нескольких секунд (например, уточнить адрес ресторана).

Важно помнить, что наша задача — минимизировать скорость загрузки сайта с наименьшими потерями в функциональности и юзабилити.
+53
8.1k 185
Comments 38
Top of the day