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

    Вместе с ростом мобильного интернета растёт и необходимость оптимизации скорости работы мобильных сайтов. Даже самые современные смартфоны на 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 предложила интересный способ “ленивой” подгрузки модулей;
    Суть этого способа в том, что сначала нужно разбить крупные программные модули на более мелкие и распределить, какие из их необходимо грузить на старте загрузки страницы, а какие позже. Также важно, что “отложенные” модули будут загружаться по мере их вызова действиями пользователей. Такая загрузка, действительно выглядит ленивой: пока не пнёшь — не пошевелится.

    Заключение


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

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

    Важно помнить, что наша задача — минимизировать скорость загрузки сайта с наименьшими потерями в функциональности и юзабилити.
    Share post

    Comments 38

      +5
      используйте CSS-градиенты вместо фоновых картинок — это координально сократит количество обращений к серверу;

      Размер png градиента 1x320 пикселей сравним с размером описания css-градиента. Но css градиент рендерится примерно раз в пять медленнее. Тестов не могу предоставить, он на android трубках было заметно.

      Чтобы убрать обращение к серверу можно png картинку встроить прямо в html код.
        0
        Совершенно верно, поэтому также было предложено использовать технику data URI для встраивания картинок.
        –1
        А разве Webkit не поддерживает WebSoсkets? Или имеется ввиду только мобильный Webkit?
          +1
          Спасибо. А на каком наборе устройств/браузеров нужно тестировать сайт? В статье упомянуты Andriod, iOS, Blackberry, Opera Mobile. А как насчёт Opera Mini, Symbian? Есть ли для них всех эмуляторы или лучше обзавестись реальными устройствами?
            +2
            У нокии есть неплохой сервис доступный разарботчикам бесплатно (к сожалению сейчас не могу найти ссылку)
            Там через java-апплет получаешь удаленный доступ к телефону. Моделей телефоннов там много. Время сеанса работы с телефоном ограничено несколькими десятками минут. На некоторые модели телефонов бывают «очереди». Но в GMT+3 вроде бы нечасто и не большие.
            +1
            Довольно часто сайты «затачиваются» под конкретные платформы, для них и проводятся тесты. Использовать эмуляторы для тестирования/анализа производительности не рекомендуется, немного об этом здесь.
              +1
              +5
              Еще не наступило то время, когда мобильный сайт — это сайт для Webkit браузеров. Лет через 5 — возможно.

              — Широкая поддержка HTML5 и CSS3 в мобильных браузерах

              На сегодня, пока, что 40% пользователей мобильного интернета — Symbian, 15% — Windows Mobile. Какие речи о HTML5 и CSS3 в мобильном интернете?
                0
                А можно представить источник статистики? Если верить следующей ссылке
                gs.statcounter.com/#mobile_browser-ww-monthly-201101-201106-bar

                то ситуация несколько иная.
                  0
                  Я про Россию, Матушку, в первую очередь, так как привык работать только с Российским трафиком. До сих пор жив «рувап», так сказать…
                    0
                    Так там по России тоже статистика есть:
                    Opera+Android+iPhone = 90% трафика
                    Нокиа — 6%
                    IEMobile — 0.5%

                    Вот вам и «40% симбиан, 15% винмо»…
                      +4
                      Даже согласно вашему источнику gs.statcounter.com/#mobile_browser-RU-monthly-201101-201106-bar

                      Тут 70% — Opera (а это не HTML5+CSS3), это как раз-таки Symbian, Windows Mobile и прочие телефоны, которые вообще незнают ничего про вышеописанное и имеют очень большие ограничения и работают скорее всего используя XHTML Mobile

                      iOS — 10%
                      Android — 8%

                      А не то, что вы указали. А я судил по статистике другой. У меня есть реальная статистика по проектам крупной компании, занимающийся мобильными сайтами в РФ. Графиков показать, к сожалению не смогу…

                      Подводя итог, согласно ВАШЕМУ же источнику:

                      Opera + Nokia = уже 76%, а это как раз те, кто приносит доход в мобильном интернете, как вы не затачивали бы сайты под iPhone… Таковы реалии жизни…
                        0
                        На всякий случай… Я говорю про сайты — это раз. Во 2х — топик в принципе хороший, тем более в нем есть полезная информация. Просто меня задела фраза:

                        — Широкая поддержка HTML5 и CSS3 в мобильных браузерах

                        Все. В остальном претензий не имею =)

                        «Зануда мод» выключил. Ушел работать.
                          0
                          Ну вообще это сильно от региона зависит. В Штатах например, iOS+Android+BB это больше 90% мобильного интернета. В Европе чуть другая картина, но тоже доминирует смартфоны со «взрослыми» броузерами.
                  –1
                  Только с симбиан девайсов, в отличии от нормальных смартфонов в интернет никто толком ходит, так что, по-моему, нету особых причин рассчитывать на их возможности. К тому-же Опера, без которой на таком железе будет очень грустно, такие многое из этих стандартов поддерживает.
                    +2
                    Если симбиан — это не смартфоны, то что же тогда смартфоны?

                    Я хожу встроенным браузером с Nokia 5228 на нормальные большие сайты, и никакая опера мне там не нужна.
                  +2
                  Ох, взгляд максималиста.
                    +2
                    «используйте обфускацию кода CSS и JavaScript;» — чем это поможет мобильным устройствам? Насколько я знаю, обфускация только увеличивает размер кода.

                    P.S. не «координально», а «кАрдинально».
                      0
                      Одна из основных целей обфускации как раз уменьшение размера кода.
                        0
                        да, теперь согласен, чуточку образовался.
                        Только это не основная цель, а побочный эффект запутывания кода.
                          +1
                          Обфуска́ция (от лат. obfuscare — затенять, затемнять; и англ. obfuscate — делать неочевидным, запутанным, сбивать с толку) или запутывание кода — приведение исходного текста или исполняемого кода программы к виду, сохраняющему ее функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции.

                          А уменьшение размера кода — это компрессия.
                            0
                            В любом случае, речь шла об использовании таких тулов как YUI Compressor для минимизаци и обфускации кода. Но спасибо за уточнение.
                              0
                              Ну тот же гугл кложур и обфускацию делает, и код оптимизирует и уменьшает объем.
                        +1
                        Определить возможности мобильного клиента можно при помощи WURFL, это позволит не угадывать разрешение девайса, а сразу отдавать необходимую css.
                          0
                          Интересно. а Вы пользуетесь этой базой? Как впечатления?
                            0
                            Я использовал одну инсталляцию TeraWURLF с кешированием в mysql; остальные проекты подключались к ней через REST и сохраняли результат в memcache. Мои впечатления — очень удобно, если знать как с этим работать; мне этот функционал пришлось переделывать за другими разработчиками, где был жуткий хардкод и тормоза. Если интересует, могу дать ссылку на свои классы для Zend Framework для работы с TeraWURFL
                              0
                              Спасибо, но у меня .Net проект.
                              Сначала было обрадовался, но вспомнив свою статистику посещений (подавляющее большинство ходит с Opera Mini) расстроился :-(
                              И почему бы Опере не отправлять хотя бы разрешение экрана девайса, могут ведь. IEMobile, например, отправляет в заголовках.
                                0
                                да, этим Опера конечно свинью подложило изрядную
                                у меня были европейские проекты для смартфонов, там опера (к счастью) даже не рассматривалась
                                  0
                                  эх, позор мне на мою седую голову — сегодня случайно заметил в логах следующие строчки:
                                  <serverVariables>
                                  <item name="HTTP_USER_AGENT">
                                  <value string="Opera/8.01 (J2ME/MIDP; Opera Mini/3.1.10423/1724; ru; U; ssr)"/>
                                  </item>
                                  <item name="HTTP_X_OPERAMINI_FEATURES">
                                  <value string="basic, inputhints"/>
                                  </item>
                                  <item name="HTTP_X_OPERAMINI_PHONE_UA">
                                  <value string="Nokia5070/2.0 (04.21) Profile/MIDP-2.0 Configuration/CLDC-1.1"/>
                                  </item>
                                  <item name="HTTP_X_OPERAMINI_PHONE">
                                  <value string="Nokia # 5070"/>
                                  </item>
                                  </serverVariables>
                                  

                                  Задаваясь вопросом почему я раньше не додумался загуглить «opera mini headers» нахожу на DevOpera нужный материал — Opera Mini request headers.
                                  И сейчас уже понимаю, что не могли оперовцы не передавать такую важную информацию как модель телефона, не могли :-)
                                  0
                                  ну и насчет WURFL — не нужно использовать XML файл напрямую, это будет очень долго, нужно сохранять результат в быстрый кеш и работать с ним.
                                    0
                                    Да, разумеется. В ASP.NET есть единый общедоступный кэш приложения. Туда и кэшируется WURFL, с этим проблем нет.
                            0
                            Очень правильные рекомендации. Добавлю лишь один упущенный вами, но очень важный момент:
                            — всегда используйте CACHE MANIFEST
                              0
                              Насколько я знаю, использование CSS media-queries не помогает не загружать ненужный контент.
                              0
                              Вы перепутали время жизни LocalStorage и SessionStorage.
                              Я вот localStorage пользуюсь-пользуюсь, и никак он не очистится, хотя не только браузер, но и систему перезапускал.
                                0
                                > используйте минимизацию и обфускацию кода CSS и JavaScript;

                                Если уже используется gzip, то нет смысла проводить обфускацию css или js. Выйгрыш крайне мал, если вообще есть. Разработчик Webo Site SpeedUp проводил соответствующие тесты, результаты есть в одной из его книг.

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

                                Косяк в том, что браузер не передаст, а только отобразит необходимую версию картинки. Скачает он обе версии. Цитата из книги A List Apart «Responsive Web Design»:

                                «The problem with this approach is that some small screen browsers, most notably Mobile Safari on the iPhone and the iPad, will actually download both graphics, even if only one is ultimately applied to the page. While smaller screens don’t always equate to lower bandwidth, we’re currently punishing users on smaller screens with the download of a much heavier image than they’ll ever see.»

                                Only users with full accounts can post comments. Log in, please.