Вместе с ростом мобильного интернета растёт и необходимость оптимизации скорости работы мобильных сайтов. Даже самые современные смартфоны на Android, iOS, WebOS, BlackBerry OS и др. обладают процессорами с частотой не более 1Ghz, а скорости 3G можно считать достаточно медленными (скорость загрузки в 3 раза меньше DSL).
Мобильные устройства унаследовали проблемы “больших” машин: от количества http-запросов до эффективности работы JavaScript.
Кроме того, что они часто помещаются в карман и их легче потерять, существует несколько ключевых отличий мобильных устройств по отношению к десктопам:
Мобильным сайтам присуще большинство проблем производительности “больших сайтов”, поэтому многие перечисленные техники пришли из десктопной оптимизации.
Широкая поддержка HTML5 и CSS3 в мобильных браузерах позволяет использовать самые современные техники для оптимизации сайтов:
Наряду с борьбой против лишних обращений к серверу, очень важно минимизировать размеры загружаемых файлов. В этой перспективе оптимизация изображений является наиболее важным элементом.
У мобильных устройств экраны имеют значительно меньшее разрешение, чем экраны десктопов. CSS позволяет нам определять текущее разрешение экрана пользователя и в зависимости от этого передавать ему ту версию картинки, которая имеет более подходящее разрешение.
Код выше определяет, что ширина экрана пользователя больше, чем 480px и даёт указание браузеру загружать картинку header-full.png с полноценным разрешением
А вот следующий фрагмент кода, определив, что ширина экрана меньше 480px, предлагает браузеру картинку, адаптированную под маленькие экраны:
В результате такого взаимопонимания между сайтом и браузером размер загружаемых на мобильное устройство данных значительно уменьшится.
Однако прежде всего заботьтесь над удобством пользователя. Используя тот же принцип (отдельный контент для мобильных и десктоп устройств), можно сделать сайт приятным для просмотра пользователям с экранами высокого разрешения, в то же время не навредив остальным посетителям.
Например, пользователи iPhone 4 уже привыкли к тому, что на экране их телефона должны быть изображения с высоким DPI (напр. 300). И если вы хотите, чтобы ваш сайт не смотрелся убого на Retina экранах, нужно будет готовить еще один отдельный набор картинок в высоком разрешении и загружать их, используя CSS Media Queries
Это как раз тот случай, когда стоит поступиться производительностью в пользу удобству пользователей.
Начиная с версии Android 2.2 Froyo у разработчиков появилась возможность получать данные о текущем типе подключения к интернету у устройства. Реализуется это при помощи объекта navigator.connection.
Вот пример данных, получаемых с устройства, которое работает в 3G сети:
Тип соединения “4”, что соответствует CELL_3G. Используя простой скрипт можно определить тип соединения и передать эту информацию как CSS класс в HTML элементе.
В результате при определении низкоскоростного соединения мы передаём браузеру посетителя оптимизированные картинки, используя CSS:
И всё-таки не стоит лишать пользователей выбора (не будем диктаторами). Поэтому хорошим тоном будет помимо распространённого выбора:
Давать также выбор:
Пользуйтесь простыми правилами — “если пикселей не видно, их не надо загружать”, но в то же время “не стоит решать за пользователя, ему можно рекомендовать”.
Если в случае с десктопами в большинстве случаев решение будет в пользу внешних файлов, то с мобильными скорее всего наоборот. Из-за маленьких размеров кэша, говорить о большой и долгосрочной экономии не приходится. Есть ряд советов по оптимизации скорости повторной загрузки страниц:
Важным ограничение для LocalStorage и SessionStorage является то, что они могут хранить только данные типа String. Поэтому следует данные предварительно переводить в строковый формат, а впоследствии восстанавливать в оригинальном при помощи
Размеры данных которые могут храниться в этих объектах разнятся от браузера к браузеру, но 5 Mb должно хватить в большинстве.
Интересный момент — устройства на Android и BlackBerry OS умеют хранить кэш даже после включения/выключения девайса, в то же время iPhone этим похвастаться не может.
*Постоянный — это кэш, который остаётся, даже после перезапуска браузера.
**В памяти — это кэш, который хранится в оперативной памяти (напр. — при переключении между приложениями). Подробнее о кэше в мобильных устройствах можно прочесть в блоге компании Blaze.
Недостаточная мощность процессоров в мобильных устройствах, вновь делает актуальным борьбу за снижение нагрузки. Так исследования компании Google показывают, что парсинг каждого 1 КБ кода JavaScript составляет приблизительно 1 мс.
Значение оптимизации скорости работы мобильных сайтов становится важнее сейчас, когда пользователи всё больше используют смартфоны для решения повседневных задач в интернете.
Интересно, что большинство людей более нетерпимы к медленной работе сайтов именно при использовании смартфонов. Часто это связано со специфическими задачами, которые нужно решить в течении нескольких секунд (например, уточнить адрес ресторана).
Важно помнить, что наша задача — минимизировать скорость загрузки сайта с наименьшими потерями в функциональности и юзабилити.
Мобильные устройства унаследовали проблемы “больших” машин: от количества 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 предложила интересный способ “ленивой” подгрузки модулей;
Заключение
Значение оптимизации скорости работы мобильных сайтов становится важнее сейчас, когда пользователи всё больше используют смартфоны для решения повседневных задач в интернете.
Интересно, что большинство людей более нетерпимы к медленной работе сайтов именно при использовании смартфонов. Часто это связано со специфическими задачами, которые нужно решить в течении нескольких секунд (например, уточнить адрес ресторана).
Важно помнить, что наша задача — минимизировать скорость загрузки сайта с наименьшими потерями в функциональности и юзабилити.