Пользователь
0,0
рейтинг
6 мая 2013 в 07:58

Разработка → Лёгкий сайт или как посадить браузер на диету перевод

А что если объединить профессионалов, работавших над крупными web проектами, чтобы создать исчерпывающее руководство по оптимизации front-end разработки?
И получить в результате не скучную инструкцию, а что то поинтереснее? А если позвать Briza Bueno (Americanas.com), Davidson Fellipe (Globo.com), Giovanni Keppelen (ex-Peixe Urbano), Jaydson Gomes (Terra), Marcel Duran (Twitter), Mike Taylor (Opera), Renato Mangini (Google), и Sérgio Lopes (Caelum) чтобы собрать лучшие практики?

Именно это мы и сделали! Мы научим вас создавать быстрые сайты.

Zeno Rocha, руководитель проекта.

Неужели важно то, насколько быстро загружается сайт?
Несомненно! И не надо говорить, что это не так. Так почему же до сих пор появляются медленные сайты, оставляющие неприятный осадок на душе пользователя, который на них побывал? Соблюдая правила, описанные тут, можно заставить сайт загружаться быстрее. Не будем останавливаться на влиянии скорости загрузки у WEB гигантов, перейдем сразу к делу!

HTML


25. Избегайте использование inline и вложенного кода

Подключить CSS и JavaScript код можно тремя простыми способами:
  1. Inline: Код пишется непосредственно в теге элемента. Для CSS в атрибуте style, а для JavaScript в атрибуте onclick.
  2. Вложенный: CSS и JavaScript код пишутся в блоках и соответственно.
    Внешний: Используя тег для CSS файла , или же с указанием атрибута src для JavaScript.

    Первые два варианта, несмотря на то, что уменьшают количество HTTP запросов, увеличивают объем самого HTML файла. Если объемы включаемых скриптов и файла не большие, первые два варианта могут оказаться быстрее третьего. Чтобы проверить так ли это, можно провести тесты. Так же, нужно учитывать назначение странички. Если вы уверены, что пользователь зайдет только единожды, то первые два варианта окажутся предпочтительнее, т.к. сократят количество HTTP запросов.

    Старайтесь не включать CSS/JS в середине HTML файла. (Используйте инструменты для автоматизации этого процесса)

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

    Полезные инструменты и ссылки

    24. Стили сверху, скрипты снизу

    Если объявить стили в блоке
    , то страница будет оформляться по мере загрузки стилей и пользователю будет казаться что всё грузится быстро.
    <head> <meta charset="UTF-8"> <title>Сажаем браузер на диету</title> <!-- CSS --> <link rel="stylesheet" href="style.css" media="all"> </head>

    Но если объявить их в конце страницы, то она останется в неглиже, пока стили не загрузятся.
    С другой стороны, лучше подключать JavaScript в конце, т.к. время загрузки скриптов можно потратить с пользой на оформление страницы.
    
    <body>
      <p>Lorem ipsum dolor sit amet.</p>
       <!-- JS -->
      <script src="script.js"></script>
    </body>
    

    Полезные ссылки

    23. Сжимайте HTML код

    Конечно же, для поддержки кода, лучше оставлять комментарии и расставлять отступы в нем.
    
    <p>Lorem ipsum dolor sit amet.</p>
    <!-- Это лист -->
    <ul>
      <li><a href="#"></a></li>
      <li><a href="#"></a></li>
      <li><a href="#"></a></li>
    </ul>
    

    Но браузеру они совершенно не нужны. Поэтому лучше cжать HTML код.
    
    <p>Lorem ipsum dolor sit amet.</p><ul><li><a href="#"></a></li><li><a href="#"></a></li><li><a href="#"></a></li></ul>
    

    Это сократит размер страницы, а пользователи насладятся быстрой загрузкой сайта.
    Несколько примеров работы HTML Compressor с настройками по умолчанию:
    Название сайта Исходный размер В сжатом виде Процент сжатия
    BBC 77,054b 55,324b 28.2%
    CNet 86,492b 61,896b 28.4%
    FOX News 75,266b 64,221b 14.7%
    GameTrailers 112,199b 92,851b 17.2%
    Kotaku 134,938b 116,280b 13.8%
    National Post 75,006b 55,628b 25.8%
    SlashDot 158,137b 142,346b 10.0%
    StackOverflow 116,032b 100,478b 13.4%

    Полезные инструменты и ссылки

    22. Включайте асинхронно

    Чтобы понять, как этот атрибут ускоряет загрузку, легче посмотреть, что происходит, если его не использовать.
    
    <script src="example.js"></script>
    

    В этом случае, браузер будет ждать полной загрузки скрипта, прежде чем начнет обрабатывать последующий HTML код. Это может серьезно увеличить время загрузки сайта. Но иногда такое поведение браузера оправдано.
    
    <script async src="example.js"></script>
    

    Здесь же, скрипт будет скачиваться асинхронно, не мешая обработке HTML разметки страницы. Скрипт запустится как только полностью скачается. Главное помнить, что если асинхронных скриптов несколько, то они запустятся не обязательно в том же порядке что были объявлены.

    Полезные ссылки



    CSS


    21. Сжимайте стили

    Как и в случае с HTML кодом, браузер не оценит ваши комментарии и отступы в стилях:
    .center {
      width: 960px;
      margin: 0 auto;
    }
    /* --- Структура --- */
    .intro {
      margin: 100px;
      position: relative;
    }
    

    Поэтому сжимайте их с помощью инструментов, для этого предназначенных.
    .center{width:960px;margin:0 auto}.intro{margin:100px;position:relative}
    

    Если вы использует динамические языки стилей Sass, Less, Stylus и т.п., их можно настроить так, чтобы на выходе получать уже сжатые файлы.

    Полезные инструменты и ссылки

    20. Объединяйте CSS файлы

    Для поддержки и разработки сайта удобно, чтобы стили хранились в разных файлах:
    
    <link rel="stylesheet" href="structure.css" media="all">
    <link rel="stylesheet" href="banner.css" media="all">
    <link rel="stylesheet" href="layout.css" media="all">
    <link rel="stylesheet" href="component.css" media="all">
    <link rel="stylesheet" href="plugin.css" media="all">
    

    Но это отдельные HTTP запросы на загрузку каждого файла (так же у браузеров есть ограничение на количество параллельных загрузок).
    
    <link rel="stylesheet" href="main.css" media="all">
    

    Если объединить CSS файлы, они загрузятся быстрее.
    Этот процесс можно автоматизировать при помощи различный инструментов.

    Полезные инструменты и ссылки

    19. Используйте вместо @import
    Подключить внешние стили можно двумя способами. Либо с помощью тега
    :
    <link rel="stylesheet" href="style.css">

    Либо используя директиву @import (внутри внешних стилей или вложенных тегах
    ):
    @import url('style.css');

    Если использовать второй способ внутри внешних стилей, браузер не может параллельно загружать этот файл, что может помешать загрузке остальных вложений.

    Полезные ссылки



    JavaScript


    18. Загружайте сторонний контент асинхронно

    Вряд ли найдутся те, кто не использовал у себя на страницах Youtube видео или кнопки like/tweet.

    Проблема в том, что мы не знаем как будут загружаться эти данные и загрузятся ли они вообще. Причины этому могут быть разные: интернет пользователя, сервер с которого эти данные поступают или же не дружелюбно настроенный корпоративный firewall.

    Чтобы не допустить блокировки загрузки сайта из за проблем с внешними ресурсами, загружайте их асинхронно (или используйте Friendly iFrame)
    var script = document.createElement('script'),
        scripts = document.getElementsByTagName('script')[0];
    script.async = true;
    script.src = url;
    scripts.parentNode.insertBefore(script, scripts);
    

    Как вариант, вы можете асинхронно загружать сторонние виджеты с помощью этого скрипта.

    Полезные ссылки и видео

    17. Храните размер массива

    Циклы играют важную роль в производительности JavaScript. Старайтесь оптимизировать каждую итерацию.

    Например, можно запоминать размер обходимого массива, чтобы не вычислять его при каждой итерации.
    var arr = new Array(1000),
        len, i;
    
    for (i = 0; i < arr.length; i++) {
      // Плохой цикл, будет считать размер массива 1000 раз
    }
    
    for (i = 0, len = arr.length; i < len; i++) {
      // Так лучше, размер массива посчитается только один раз
    }
    

    Тесты в JSPerf

    Примечание: Большинство браузеров проделывают эти махинации сами.

    Особенно это важно при обходе массивов данных DOM, таких как Node(NodeList), возвращаемых, например, функцией document.getElementsByTagName('a'). Они собираются "на лету", т.к. при изменениях в разметке они так же меняются.
    var links = document.getElementsByTagName('a'),
        len, i;
    for (i = 0; i < links.length; i++) {
      // При каждой итерации список ссылок будет пересчитываться, что есть плохо
    }
    
    for (i = 0, len = links.length; i < len; i++) {
      // Список ссылок считается единожды
    }
    
    // А это ужасный бесконечный цикл
    for (i = 0; i < links.length; i++) {
      document.body.appendChild(document.createElement('a'));
      // Каждую итерацию добавляется еще одна ссылка, при этом условие останова никогда не будет выполнено
      // Если сохранять длину массива в переменной, этого не произойдет.
    }
    

    Полезные ссылки

    16. Избегайте использование document.write

    При вызове document.write страница не будет полностью загружена, пока функция не завершит своё выполнение.

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

    HTML5 Boilerplate, например, подключает с помощью этой функции локальный jQuery если Google не отвечает на запрос.
    
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.0.min.js"><\/script>')</script>
    

    Важно: Если вызвать document.write во время или после события window.onload, она заменит всё содержимое страницы.
    
    <span>foo</span>
    <script>
      window.onload = function() {
        document.write('<span>bar</span>');
      };
    </script>
    

    В результате на странице будет только bar, а не foobar. Тоже самое произойдет, если сделать это после window.onload
    Такое же поведение будет, если вызвать функцию ДО, но с задержкой во времени.
    
    <span>foo</span>
    <script>
      setTimeout(function() {
        document.write('<span>bar</span>');
      }, 1000);
      window.onload = function() {
        // ...
      };
    </script>
    

    Полезные ссылки

    15. Избегайте излишнего перерисовывания элементов

    Каждый раз, когда изменяются определенные свойства элемента DOM, запускается процесс перерисовывания.

    Это может быть изменение только внешнего вида элемента. Nicole Sullivan приводит в пример редактирование стиля элемента параметром background-color.

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

    Без сомнений, излишнее использование таких вмешательств не допустимо. Поэтому, вместо этого:
    var div = document.getElementById("to-measure"),
        lis = document.getElementsByTagName('li'),
        i, len;
    
    for (i = 0, len = lis.length; i < len; i++) {
      lis[i].style.width = div.offsetWidth + 'px';
    }
    

    Делайте так:
    var div = document.getElementById("to-measure"),
        lis = document.getElementsByTagName('li'),
        widthToSet = div.offsetWidth,
        i, len;
    
    for (i = 0, len = lis.length; i < len; i++) {
      lis[i].style.width = widthToSet + 'px';
    }
    

    При изменении style.width, браузер лезет в разметку страницы. Обычно, изменения в стилях многих элементов происходит при одном перерисовывании, т.к. браузер делает это один раз при обновлении вида страницы. Но, в первом примере, в цикле идёт обращение к свойству offsetWidth, которая является частью внешнего вида, поэтому браузеру приходится каждый раз пересматривать разметку страницы.

    Сохраняйте все необходимые данные о разметке страницы до того, как собираетесь менять её, как во втором примере.

    Полезные ссылки и демо

    14. Избегайте излишних манипуляций с DOM

    При каждом не обоснованном обращении к DOM, погибает панда.

    Серьезно, браузеру дорого обходится эта операция. Несмотря на то, что движки JavaScript становятся всё быстрее, предпочтительно оптимизировать обращения к дереву DOM.

    Одно из простых правил: если к элементу надо обратиться несколько раз, то старайтесь это сделать одним обращением к DOM. Например, используя переменные:
    // Очень и очень плохо!
    for (var i = 0; i < 100; i++) {
      document.getElementById("myList").innerHTML += "<span>" + i + "</span>";
    }
    // А так гораздо лучше :)
    var myList = "";
    
    for (var i = 0; i < 100; i++) {
      myList += "<span>" + i + "</span>";
    }
    
    document.getElementById("myList").innerHTML = myList;
    

    Тесты в JSPerf

    13. Сжимайте скрипты

    Так же как и в случае с CSS и HTML, браузеру совершенно безразличны комментарии и пробелы в скриптах.
    Вместо этого:
    BrowserDiet.app = function() {
    
      var foo = true;
    
      return {
        bar: function() {
          // тут что то происходит...
        }
      };
    
    };
    

    Браузеру легче обработать это:
    BrowserDiet.app=function(){var a=!0;return{bar:function(){}}}
    


    Полезные инструменты и ссылки

    12. Объединяйте несколько js файлов в один

    Так же, как и в случае с CSS, чтобы сократить HTTP запросы, объединяйте файлы скриптов в один.
    
    <script src="navbar.js"></script>
    <script src="component.js"></script>
    <script src="page.js"></script>
    <script src="framework.js"></script>
    <script src="plugin.js"></script>
    

    А если делать так, загрузка ускорится:
    
    <script src="main.js"></script>
    

    Хотите быть царём DOMа? Автоматизируйте и этот процесс.

    Полезные инструменты и ссылки



    jQuery


    11. Всегда используйте последнюю версию jQuery

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

    Для локального подключения jQuery, можно взять последнюю версию библиотеки отсюда:
    
    http://code.jquery.com/jquery-latest.js
    

    Но не подключайте этот файл напрямую через тэг
    . На вашем сайте могут возникнуть проблемы с обратной совместимостью, т.к. вы не успеете внести изменения для работы с новой версией библиотеки. Подключайте версию библиотеки, которая у вас поддерживается.
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    Как говорил легендарный Барни Стинсон: "Новое всегда лучше" :P

    Полезные ссылки

    10. Селекторы

    Как правило, при работе с jQuery, всегда возникают вопросы при выборе того или иного селектора. Их в библиотеке достаточно много. И не все они работают одинаково быстро. Например, можно выбрать элемент по классу, ID или же использовав такие методы как find() или children().

    Среди всех селекторов, выбор элемента по ID работает быстрее всего, т.к. использует нативные методы DOM:
    $("#foo");
    

    Тесты в JSPerf

    9. Используйте for вместо each

    Почти всегда функции самого JavaScript работают быстрее, чем аналогичные в библиотеке jQuery. Поэтому вместо перебора с помощью jQuery.each оптимальнее использовать циклы JavaScript.

    Но важно отметить, что это так не всегда. Во многих случаях for in уступает по скорости jQuery.each.

    И как уже говорилось, запоминайте размер массива, чтобы совершить обход быстрее.
    for ( var i = 0, len = a.length; i < len; i++ ) {
        e = a[i];
    }
    

    Многие считают, что использование циклов for и while с обратными счетчиками работают быстрее традиционных. Эта тема горячо обсуждается сообществом. Но такие циклы не используют ввиду того, что код становится менее понятным.

    Тесты в JSPerf и полезные ссылки

    8. И не используйте jQuery...

    ...пока в этом нет необходимости :)

    Иногда обычный JavaScript выглядит проще jQuery.

    Зачем использовать метод attr() чтобы узнать ID элемента?
    $('a').on('click', function() {
      console.log( $(this).attr('id') );
    });
    

    Когда его можно достать средствами самого языка:
    $('a').on('click', function() {
      console.log( this.id );
    });
    

    И это работает намного быстрее.

    Тесты в JSPerf и полезные ссылки



    Изображения


    7. Используйте CSS спрайты

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



    А затем указывать картинку с помощью позиции в CSS.
    .icon-foo {
      background-image: url('mySprite.png');
      background-position: -10px -10px;
    }
    
    .icon-bar {
      background-image: url('mySprite.png');
      background-position: -5px -5px;
    }
    

    Таким образом, вы сократите количество HTTP запросов к серверу и задержек загрузки остальных ресурсов.

    Между изображениями в спрайте, оставляйте минимум свободного места. Это не сильно отразится на размере файла, но сократит потребление памяти.

    Даже не смотря на то, что все знают о спрайтах, эта техника не используется повсеместно. Разработчики зачастую забывают автоматизировать процесс создания спрайтов. В ссылках ниже, есть несколько таких инструментов.

    Полезные инструменты и ссылки

    6. Data URI

    Эта техника - альтернатива CSS спрайтам.

    Data-URI это способ включения данных, как кода картинки в строку, нежели как ссылку на него. В этом примере показано как использовать Data-URI для указания фонового изображения одного из элементов.
    До:
    .icon-foo {
      background-image: url('foo.png');
    }
    

    После:
    .icon-foo {
      background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII%3D');
    }
    

    Все браузеры начиная с IE8 поддерживают технологию кодирования base64.

    Для обоих методов, нужны дополнительные инструменты для поддержки кода. Но у метода Data-URI преимущество в том, что каждый файл по сути хранится отдельно, что облегчает разработку. Тем не менее, из за того что код картинки включается непосредственно в CSS, размер файла увеличивается. Такой подход не стоит использовать без gzip сжатия ответов сервера, т.к. выигрыш в количестве HTTP запросов может увеличить время загрузки самого файла.

    Полезные инструменты и ссылки

    5. Не меняйте масштаб изображений

    Указывайте атрибуты width и height для картинок, чтобы избежать лишних процессов обрисовки.
    
    <img width="100" height="100" src="logo.jpg" alt="Logo">
    

    Зная это, верстальщик Джон Ку отображает изображение 700x700px как иконку размером 50х50px.
    Но господин Ку и думать не хочет о дюжинах лишних килобайт, проносящихся в сети.

    Запомните: Не надо изменять масштаб изображения, только потому что это можно сделать

    Полезные ссылки

    4. Оптимизируйте

    Файлы изображений часто включают в себя много бесполезной для Web информации. Например, в файле JPEG могут быть метаданные Exif камеры(дата, модель камеры, местоположение и т.п). А PNG может содержать информацию про цветовую палитру, метаданные и даже миниатюру изображения. Ничто из этого браузером не используется, а свой небольшой вес в размер файла вносит.

    Существуют инструменты для такого рода оптимизации изображений. Это называется сжатием без потерь.

    Другой способ оптимизации это редактирование качества картинки. Это называется сжатием с потерями. При создании JPEG, можно указать уровень качества (от 0 до 100). Для лучшей скорости загрузки, нужно выбирать наименее низкий позволительный уровень. А для PNG файла можно уменьшить цветовую палитру, например преобразовав PNG-24 в PNG-8.

    Так же для увеличения скорости загрузки можно преобразовать JPEG файлы в прогрессивные. Прогрессивный JPEG поддерживается большинством браузеров и их очень просто создавать без значительной потери производительности. Такие изображения отображаются на странице быстрее (демо).

    Полезные инструменты и ссылки



    Сервер


    3. Используйте умное кэширование

    Лучший способ оптимизировать запросы к серверу - вообще их не делать. И один из самых действенных методов избавиться от лишних обращений к серверу - кэширование. По умолчанию, браузер сам решает, сколько времени хранить кэш. Но это можно контролировать.

    Эта оптимизация выполняется на сервере (и зависит от типа сервера, на котором лежит сайт). В случае, например, с Apache, можно добавить следующие строки в файл .htaccess:
    ExpiresActive On
    ExpiresByType image/gif "access plus 6 months"
    ExpiresByType image/jpeg "access plus 6 months"
    ExpiresByType image/png "access plus 6 months"
    ExpiresByType text/css "access plus 6 months"
    ExpiresByType text/javascript "access plus 6 months"
    ExpiresByType application/javascript "access plus 6 months"
    

    При такой конфигурации, браузер будет хранить изображения, CSS и JS файлы 6 месяцев - рекомендуется хранить их хотя бы месяц. Подобным образом конфигурируются и остальные типы серверов.

    Важно: Если файл закэширован, браузер больше не будет загружать его, даже если содержимое файла поменяется. Один из способов загрузки измененного закэшированного файла, это переименовать его. Можно добавить к имени файла версию, либо timestamp. Например, вместо home.js, можно использовать home-v1.js, а когда файл изменится, переименовать в home-v2.js и т.д.

    Другой способ заменить загрузку закэшированного файла это добавление параметра GET к URL. Например, home.js?v=1 и home.js?v=2, но некоторые прокси игнорируют GET параметры.

    Полезные ссылки

    2. gzip

    Большая часть контента сайта приходится на текстовые данные (HTML, CSS, JavaScript, JSON, XML и т.п.). Такие данные легко сжимаются на стороне сервера при помощью GZIP и считается хорошим тоном это делать.

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

    Технология включается на стороне сервера. Например, для сервера Apache, достаточно указать в файле .htaccess какие типы файлов нужно сжимать:
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/javascript
    

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

    Полезные ссылки



    Дополнительно


    1. Инструмент диагностики - ваш верный друг

    Если после всего прочитанного, вы решитесь окунуться в мир быстрых сайтов, то для вас будет полезно установить расширения для браузера YSlow и PageSpeed. Они станут для вас неотъемлемым инструментом.

    А если вы предпочитаете онлайн сервисы, то WebPageTest, HTTP Archive или PageSpeed.

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

    0. На этом пока всё

    Надеемся, после прочтения руководства, вы приведете сайт в атлетическую форму :)

    И запомните: В оптимизации, как и в жизни, нет панацеи. Повышение скорости загрузки - это кропотливая работа, всегда придётся взвешивать все за и против прежде чем ускорять какой либо процесс в структуре сайта.

    Тут вы найдете ссылки на материалы, которые были использованы при написании этого руководства.

    Давайте уже начнём создавать быстрые сайты \o/

    -1. От себя

    Это перевод статьи/сайта http://browserdiet.com/.
    25 советов, которые даются тут, действительно будут полезны как новичкам веб-разработки, так и матёрым акулам интернет пространства. Многие забывают, что несмотря на то, что каналы интернета расширяются, а скорости всё растут, очень важно чтобы сайт загружался быстро.
Перевод: Zeno Rocha's team
Азат Хузияхметов @A3a
карма
70,0
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (79)

  • 0
    Про селекторы я бы расписал подробнее. Очень многие делают так: $('.class')… Но поиск идет по всему документу, я обычно указываю сначала родительский элемент. При большом DOM дереве даже визуально можно заметить разницу
    • 0
      Согласен, оптимизация при использовании селекторов и вообще jQuery в целом, тянет на отельную статью. На хабре есть это и это
      • 0
        Понял, теперь на хабре нельзя открыто говорить про jquery. <sacrasm>Давайте же писать\читать только про asm!</sacrasm>
  • –1
    Жаль что ничегоне сказано об labjs.com/ — сам не пробовал, но один крупный магазин был замечен в использовании.
    Про то что не очень хорошо обращаться к DOM элементам не через классы или id а вот так
     .header > a 
    
    не сказано.
    Лично я конечно все равно использую этот метод ради минимизации html кода, и за некой мифической оптимизацией не гонюсь.
    Но жаль все же что такие статьи выходят забугром, потому что это означает — не читают самих отцов, а ведь большинство отсюда:
    developers.google.com/speed/articles/
    help.yandex.ru/webmaster/?id=1108938
    • +1
      «Забугром» не читают хелп яндекса? В самом деле?:)
      • 0
        Да яндекс для нас скорее, этож ясно) Все уже понаписано по оптимизации в достаточной степени у отцов.
    • 0
      Я правильно понимаю, что запись $(".header > a") медленнее чем $(".header").find(«a»)?
      Но по сути они эквивалентны. Я прав?
      • 0
        я скорее про обращение из css к dom.
      • 0
        Первая $(".header > a") будет быстрее потому, что будет использоваться нативный метод для выборки, где он есть. Но вторая $(".header").find("a") строго говоря не эквивалентна первой: find находит все дочерние элементы, а селектор > — только непосредственно вложенные (в данном случае, поскольку <a> не могут быть вложенными друг в друга, результаты будут одинаковые).
        • 0
          Просто я слышал что селекторы обрабатываются справа налево. То есть получается сначала будут выбраны все <a> на странице, а потом только являющиеся прямым чайлдом .header.

          Поэтому и спрашиваю…
  • –3
    > 11. Всегда используйте последнюю версию jQuery

    Профессионализм прям за версту видать. Ничего, что jQuery ломает обратную совместимость даже в минорных релизах?
    • 0
      Тоже про это писать хотел а потом бац и перешел по ссылке:
      code.jquery.com/jquery-latest.js
      Версия 1.9.1 но не ясно… на долго ли…
    • +4
      Прочитайте пункт 11 до конца, пожалуйста.
      • –1
        «Подключайте версию библиотеки, которая у вас поддерживается.»

        Круто. Я бы даже сказал, гениально. Можно даже развить. «Всегда используйте последние версии любого программного обеспечения, но только ту последнюю версию, что у вас поддерживается, что бы не сломать обратную совместимость.»
        • +3
          Имелось ввиду, что при начале разработки нового проекта(или же при рефакторинге), нужно использовать новую версию библиотеки. И там же советы, где их брать и как подключать.
          • +2
            Это определенно выглядит как тот случай, когда совет вышел слишком общим, слишком лаконичным. Если необходимы пояснения, что «автор имел ввиду, что» — автор поработал не очень хорошо.

            При очевидной полезности остальных советов, конечно.
  • 0
    а по-моему самого главного правила нет. Насчет того, что сначала нужно 10 раз попробовать обойтись без каждой отдельной строчки яваскрипта или стиля и все-таки использовать эту строчку только если не получилось :)
  • 0
    Я бы еще добавил пункт про то, что при выполнении сложных вычислений можно их разбивать с помощью setTimeout(function(){},0); И, таким образом, предотвращать блокировку отрисовки страницы браузером.
    • +1
      • 0
        Да, сам жду с нетерпением, когда можно будет использовать Workers повсеместно. Пока что IE 8-9 в сумме это 10% процентов веба, а они их не поддерживают.
  • +4
    Немного дополню:
    — Желательно подключать jQuery с гугловых серверов, т.к. для большинства пользователей она возьмется из кеша.
    — Если на странице нужно следить за 100500 элементами, лучше навесить обработчик на их контейнер и пользоваться всплытием событий.
    — $("#foo") на все случаи жизни может не хватить, а вот вместе $(".bar"), который эквивалентен getElementsByClassName, получается минимальный боекомплект для очень быстрого доступа к DOM, конечно если скорость критична. Лично мое мнение, что лучше добавить к элементу лишний id-ик или класс, чем подключать XPath.
    • +12
      — Желательно подключать jQuery с гугловых серверов, т.к. для большинства пользователей она возьмется из кеша.
      Не 100%-ое добро. Когда в прошлом году несколько серверов гугла попали в говнореестр, некоторые сайты, использующие этот подход, не работали. Тут правильнее использовать комплексный подход, как например делает lingualeo.ru:
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
      <script>
          window.jQuery || document.write('<scr'+'ipt src="//OUR_SITE/js/jquery-1.8.1.min.js"><\/scr'+'ipt>');
      </script>
      <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
      <script>
          window.jQuery.ui || document.write('<scr'+'ipt src="//OUR_SITE/js/jquery-ui-1.8.23.custom.min.js"><\/scr'+'ipt>')
      </script>

      Это позволит в случае недоступоности у посетителя гугловских серверов, всё равно подгрузить jQuery но с вашего сайта.
      • НЛО прилетело и опубликовало эту надпись здесь
        • 0
          Если вы действительно не поняли пример:
          Сначала идет попытка подключения jquery с гуглового сервера, затем идет проверка удачно ли, и если нет то js-ом прописывается подключение локальной версии.
          • 0
            >> '<scr'+'ipt…

            Я думаю, вопрос про это
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Возможно, автор побоялся, что хабрапарсер скушает тег script.

              UPD: А вот протестирую

              <script>
              alert("Hello!");
              document.write("<script>alert('Hello!');</script>");
              </script>
              
            • +2
        • 0
          Этот код я взял с лингволео, самому интересно почему так.
          • 0
            связано с некоторыми ограничениями IE, какие точно уже навскид не помню.
    • +2
      Кеш у современного юзера дико переполнен даже на десктопе (спасибо толстым сайтам, которые всю свою статику научились метить как кешируемую), не говоря уже про iPad-ы. В сумме получаем, что если только человек не ходит только по сайтам, у которых jQuery открывается с Гугла, почти наверняка загрузка с Гугла окажется дольше, чем с сервера самого сайта — минимум на dns lookup, да и то не факт, если сервер сайта все же быстрый и доступный (что, вообще, достижимо).

      Не писал бы, но много раз мерял — с Гуглом часто получается не быстрее, и в кеше этого добра не оказывается :(
      • +2
        Плюс еще часто jquery можно слепить с кучей других скриптов, сжать, и отдать все одним куском. В таком случае не вижу особо смысла юзать CDN.
  • 0
    18. Загружайте сторонний контент асинхронно
    И
    … например, подключает с помощью этой функции локальный jQuery если Google не отвечает на запрос.


    Совершенно не совместимы. В пункте 18 боремся за быстроту загрузки, подключая асинхронно скрипты. А тут «если Google не отвечает на запрос» (но это врятли конечно), в общем противоречие.

    Думаю стоит надеется на работоспособность CDN
  • +14
    $('a').on('click', function() {
      console.log( this.id );
    });
    


    Прелестный пример неиспользования jQuery.
    • 0
      Да, сложно совсем от него отказаться :)
  • 0
    Илья Кантор негодует, прочитав 13 пункт (про сжатие скриптов). Его код данной оптимизации не подлежит, ибо не будет работать и требует дополнительного времени на расстановку запятых.

    На мой взгляд лучше сразу писать код, соблюдая синтаксическую пунктуацию. То количество недостающий запятых занимает всяко меньше памяти, чем количество пробельных символов «украшенного» кода.
  • +4
    Насчет «5. Не меняйте масштаб изображений» — если только это не целенаправленная оптимизация изображений для Retina-экранов.

    Пусть у нас есть изображение размером 1024x640 и 99 Кб, а делать его в более высоком качестве слишком дорого, оно будет больше весить. Поэтому возьмем такое же изображение, но с размером 2048x1280 и 75 Кб. Так вот, если второму изображению принудительно задать размер в CSS 1024x640, то изображение будет выглядеть качественнее, чем первое.

    Минус этой техники, что заставляем браузер делать лишнюю работу. Поэтому эту технику следует применять, когда на странице не очень много изображений. Источник — pepelsbey.net/pres/clear-and-sharp/.
    • 0
      Пережатое изображение (2048x1280 и 75 Кб) ужасно выглядит как на обычном экране так и на ретине. Надо всё-таки сжимать адекватно качеству. Если у вас изображения оптимизируются, это в любом случае куда лучше неоптимизированных.
      • 0
        Конечно, чудес не бывает, 99 Кб и 75 Кб выбраны только для примера. Надо было это подчеркнуть.
        В формате Jpeg особенно сильно видны размытия на границах объектов. Когда мы делаем картинку в два раза большего размера, сжимаем в Jpeg-формате, а потом искусственно уменьшаем в два раза, то как раз вот эти самые размытия на границах становятся менее видны. По ссылке это хорошо видно на 49-ом и на 52-ом слайдах.
        • –1
          На самом деле это не так: никаких «менее видны», всё прекрасно видно.
  • +2
    > Используя тег script, с указанием атрибута link для CSS файла или же src для JavaScript.
    WAT?
    • +2
      исправил
  • +10
    > Между изображениями в спрайте, оставляйте минимум свободного места.

    Не согласен. По своему опыту знаю, что между спрайтами нужно оставлять отступы хотя бы в 10px. Если отступы не сделать, то в webkit-браузерах при увеличении масштаба страницы картинка внутри спрайта размоется и по бокам проступят размытые края соседних элементов спрайта.
  • +1
    Думаю, основным правилом должно быть «думай», вторым — «ничего не забывай», третьим — «проверь еще раз в самом конце» и четвертым — «не переусердствуй».

    К последнему — отдельное замечание: например, то, что из кода страницы будут выкинуты переводы строки, вряд ли уменьшит количество пакетов для загрузки этой страницы, разве что на единицу. Кроме для как совсем частных случаев, экономия 0-1 пакетов никак заметно не повлияет на загрузку, зато повлияет на читаемость кода, случись кому-то его хотя бы просмотреть, если даже не отлаживать.

    По опыту возни с большими сайтами, где «исторически наслаиваются» много разных улучшений страниц, могу сказать, что куда важнее, когда после каждого улучшения и добавления не забывают заново хотя бы собрать в один файл те же css- или js-файлы, не просто добавляют чужие скрипты, а добавляют с умом… Так что куда важнее не просто сделать страницу, а не забывать ее поддерживать в хорошей форме.
  • +23
    Ожидал большего от статьи, а получил список банальных и, в некоторых случаях, даже вредных советов для совсем уже новичков в веб-разработке.

    HTML
    0. Изучай инструменты, с которыми ты работаешь
    Меньше размер документа — меньше размер ответа с сервера. Меньше тегов — меньше DOM. Меньше DOM — быстрее грузится страница, быстрее работают манипуляции скриптами, быстрее применяются стили. Это основное правило!

    0.a кешируй все, что только можно Кешируй куски страницы, кешируй всю страницу, почитай про ETag наконец.

    CSS
    0. Изучай инструменты, с которыми ты работаешь
    Меньше правил — быстрее они применяются. Меньше глобальных правил, больше специфических, с умом. Не будь онанистом на размер файла, он важен, конечно, но у кого на сервере gzip не настроен еще? Никакой алгоритм сжатия не поможет, если твои правила написаны коряво.

    20. Объединяйте CSS файлы
    Во-первых, объеденять нужно с умом. Грохнуть все в один кусок имеет смысл только тогда, когда вам не жалко при малейшем изменении стилей каждый раз раздавать полмегабайта стилей всем клиентам. Лучше подумать головой и выделить основные части (например: основные правила, формы и админка) и отдавать их по отдельности с тем, что бы клиент кешировал как можно больше из них.

    Во-вторых, объединение CSS файлов в один может вызвать забавные баги в ИЕ, вполть до девятой версии.
    Приятной отладки!

    JavaScript
    0. Изучай инструменты, с которыми ты работаешь
    Изучи язык, черт возьми, почитай про оптимизации для разных движков.

    Перестань читать дурацкие советы вида «используй for вместо each, храни размер массива, используй одинарные кавычки вместо двойных». Черт, да в твоих массивах в среднем 10 элементов, о какой экономии идет речь?!.. Это экономия на спичках, один ajax запрос на сервер или вставка в сложный DOM перекроют эти «микропотимизации» на три порядка. Если ты используешь библиотеку, не читай такие статьи, читай документацию на официальном сайте, смотри примеры, загляни в исходники. Включи мозг.

    13. Сжимайте скрипты если у вас 100% покрытие js-кода тестами. Сжатие, а особенно «умные» алгоритмы типа advanced режима у Closure Compiler предназначены либо для людей, которые понимают, что делают (такие не читают статьи для новичков), либо для владельцев целой индийской деревни, полной спецов по QA, либо для смелых духом. У тебя и правда четыре мегабайта скриптов и ты правда не слышал про техники, вроде AMD?

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

    Когда его можно достать средствами самого языка:
    $('a').on('click', function() {
    console.log( this.id );
    });


    Средставми языка, это как-то так:
    var links = document.getElementsByTagName('a');
    var onclick = function(e) {e.preventDefault(); console.log(this.id, e.target.id); };
    for(var i = 0; i < links.length; i++) { links[i].addEventListener('click', onclick, false); }
    
    • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    17. Храните размер массива


    Не согласен. Это экономия на спичках.
    • 0
      Это не так, если речь идет о массивах, в которых лежат DOM элементы.
      • 0
        то есть?

        var arr = [document.createElement('div'), ..., document.createElement('div')];  
        


        так? :)
        • 0
          Почти, если в темноте и со зрением -3. Возьмите хотя бы более приближенный к реальности пример из статьи.
          • 0
            А это не массив

            >>> document.getElementsByTagName('a') instanceof Array
            false
            


            Это правило справедливо вприниципе для любого значения, которое можно посчитать один раз заранее, а не конкретно для массивов. Так что автор только частично прав.
            • +1
              Не правильно выразился в комментариях. Под «массивами с DOM элементами», которые я упоминал, стоит подразумевать NodeList.
    • 0
      а ещё бывает вот так joxi.ru/ZMSIUdg5CbCabVw6N_w
      отчего становится совсем грустно…
      • 0
        Не уверен, что этот код что-то корректно замеряет. Браузеры могут просто оптимизировать «мёртвый код», результаты работы которого нигде не используются.
  • –1
    Хм… Объединить все скрипты и css в один? И браузер при малейшем изменении будет снова тягивать ВЕСЬ(!) файл. Я бы озанокимлся с двумя докладами с последнего Я.Субботника про фриз и инкрементальные обновления (http://events.yandex.ru/events/yasubbotnik/kiev-apr-2013/)
  • 0
    Мы позвали кучу страшных имен, чтобы они пересказали то что написано в любом хауту по запросу «оптимизация»
  • 0
    В пункте 17 у меня «плохой» вариант работает быстрее «хорошего»
    • +1
      Где «у вас»? Они работают приблизительно одинаково, но все же «хороший» вариант должен прорабатывать чуточку быстрее, а если массив DOMов то намного быстрее.
      • 0
        Вы уже второй раз говорите про какой-то массив DOMов. Чем этот массив так отличается от массива других объектов? Может быть, правильный ответ — ничем, а вам пора перестать вводить людей в заблуждение?

        В js возможны два варианта массивов: собственно Array и «array-like» объект (вроде arguments или написанного руками {0: 'a', lenght: 1}) и ни один из них не накладывает ограничений на итерирование в цикле for (и с чего бы стал?).
        • 0
          Честно, не могу сказать точно в чём тут дело. Но возьмите в пример результаты, полученные по примеру из статьи. Рискну предположить, что jQuery сам кэширует размер своего массива, поправьте меня, если я не прав.
          • 0
            Извините, я вас не понял в первый раз. При вызове getElementsByTagName вы получаете не совсем массив, а array-like-объект (NodeList), который содержит ссылки на все теги 'a' и будет автоматически обновлен при манипуляциях с DOM. В этом случае кеширование действительно помогает работать с такими объектами быстрее, но ценой отказа от актуального состояния коллекции.
    • 0
      Дайте угадаю. У вас Firefox 20- или же Safari 6.0.3+. Внизу теста в jsPerf интересная статистика. Firefox выше 20ой версии работает быстрее с хранением размера массива. А Safari начиная с версии 6.0.3 работает, наоборот, медленнее при тех же условиях.
      • 0
        Угадали =) В гуглохроме действительно всё как в статье на той же машине, а в лисе вот так.
  • 0
    Статья для новичков конечно нужная, так как объединяет в себе почти все по клиентской оптимизации. Однако наличие Apache only кусков конфигов смущает. Серьезно, сейчас кто-то еще отдает статику апачем?
    • 0
      это западная статья, на западе еще к Nginx не привыкли. Если нужны оптимизированные конфиги для Nginx, то мы их выложили здесь
      code.google.com/p/web-optimizator/wiki/IntegrationWithWebsite#Changes_for_nginx_configuration_file
      • 0
        Не говорите ерунды, там можно подумать никто не заботится об оптимизации и память по цене картошки.
        • 0
          Мегабайт за картофелину, как везде :)
  • +3
    Читал года три назад статью, в которой было показано с помощью примеров, что при ВКЛЮЧЕННОМ gzip разница минимизированных js и ccs файлов с обычными — незначительна. Зато затрудняет отладку.
    • 0
      С обычным форматированием, пожалуй, да, а вот вырезание комментариев весьма может сказаться.
  • +4
    Дополняя: недавно на Веб-стандартах мы опубликовали перевод большой статьи Быстродействие фронтенда для дизайнеров и разработчиков, которая рассматривает лёгкость фронтенда с ещё одной стороны.
  • 0
    > 6. Data URI

    Это, насколько я понимаю, очень актуально для svg?
    jsfiddle.net/estelle/SJjJb/

    Знал, что его можно напрямую вставлять в HTML, но не в CSS.
    • 0
      Вообще-то специальные символы в адресах надо экранировать: jsfiddle.net/SJjJb/824/ или просто кодировать в base64, так как экранированный вариант ещё длиннее.
      • 0
        Спасибо, но пример не мой.

        С другой стороны, при непосредственной вставке кода нельзя одну и ту-же картинку использовать для нескольких классов. Нет, конечно можно объединить правила, но, как по мне, получится черти что. (А если еще использовать несколько картинок).
        • 0
          Можно вместо спрайта сделать отдельный CSS-файл с картинками. При gzip-сжатии размер тот же, а на выходе вся гибкость использования картинок. Вдобавок, легко мержится при изменениях, не надо редактировать картинку-спрайт каждый раз.
          • 0
            Честно говоря, не понял как. Я просто не профи) Например, если одна картинка под один класс — все просто, прописываем ее, но если нужно что-то такое:

            .foo {
                background-image: url(a.svg);
            }
            
            .bar {
                background-image: url(a.svg), url(b.svg);
            }
            


            Можно ли это сделать непосредственной вставкой кода svg в css файл без дублирования кода svg?
            • 0
              Не, боюсь так не выйдет. В этом, конечно, беда с перечислениями через запятую. Но разве gzip, который просто обязан быть в таком случае, не хорошо сжимает такие повторения?
              • 0
                Я не в курсе. С версткой более-менее знаком, а с работай с серверами — нет.
  • 0
    в п.14 опечатка, должно быть

    document.getElementById("myList").innerHTML += myList;
    
  • 0
    Все браузеры начиная с IE8 поддерживают технологию кодирования base64.
    Совсем забыли сказать что в IE8 32кб лимит на uri.

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