Как стать автором
Обновить

Комментарии 60

Всё правильно. Когда то наткнулся на похожую статью, если интересна милисекундная оптимизация, то и она будет полезна.
Спасибо за статью, не знал про margin. На счет селекторов стоит изучить эту страничку.
На собственном опыте убедился, что $(document.getElementById('foo')) гораздо лучше чем $('#foo')
Так же просто спасительным для меня решением в проекте с CSS анимацией стала такая оптимизация:
-webkit-transform: translate3d(100px, 100px, 0px);
-webkit-transition: -webkit-transform 0.5s ease;

в таком случае включается аппаратное ускорение, это в разы лучше чем анимировать любыми способами атрибуты top и left. К тому же дивы можно еще и плавно уменьшать или поворачивать.
Да, CSS анимация сама по себе работает шустрее, из-за своей нативности, так сказать. Но это лучше разбирать в теме про анимацию в целом, там очень много аспектов есть на рассмотрение
На собственном опыте убедился, что $(document.getElementById('foo')) гораздо лучше чем $('#foo')

А вот это странно, ибо на сколько я помню, конструкция $('#foo') и так выполнит document.getElementById('foo')
github.com/jquery/jquery/blob/master/src/core/init.js (67)
Выполнить то выполнит, но совершит много лишних действий, что может ударить по производительности.
На сколько я понял, «лишними действиями» будет только разбор селектора.
Но ради получения точных данных можно запустить пару тестов и проверить, действительно ли это так сказывается на производительности.
Это уже микро-оптимизация. На практике ни разу не видел в ней необходимости. Тем не менее, да, document.getElementById('ID') — всё равно самый быстрый.
var time = new Date().getTime();
var div;
for(i = 0; i < 1000000; i++){
	//div = $(document.getElementById('select_me'));
	div = $('#select_me');
	div = null;
}
var new_time = new Date().getTime();
alert(new_time - time);
//div = $(document.getElementById('select_me')) => 659
//div = $('#select_me') => 924


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

924 - 659 = 265
265 / 1000000 = 0.000265

0.000265 сэкономленных миллисекунд за 1 селект.

Но в любом случае, спасибо за метод, не знал :)
Проходя мимо, замечу, что от «new Date()» (с последующим «.getTime()» и с вычитанием) в решении таких задач пора отказываться в пользу несколько более простых методов «console.time» и «console.timeEnd».

Они поддерживаются в Сафари, в Опере, в Файерфоксе (начиная от версии 10), в Chrome (начиная от версии 2).
Спасибо, буду иметь ввиду :)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
необходимо использовать либо margin, либо padding, либо left
Быстрее всего это делать трансформациями (CSS transform translate). В старых MSIE не работает, конечно.
Недавно наткнулись на одну особенность jQuery, он добавляет временный id при выборках. Это сделано для исправления багов при работе document.querySelectorAll. В нормальных браузерах, ничего плохо не происходит, но в Opera < 15 и Safari это приводит к нежелательным reflow, поэтому мы запилили свой jquery.fn.find. А так т.к. мы не используем каскад при выборке, он ещё и быстрей.
Все хорошо, но позволю себе вставить свое слово.

Вставка JS кода в head да, «блокирует» дальнейшую обработку файлов до полной загрузки скрипта. Это верное утверждение.
Но современные браузеры стали умнее (и коварнее). Они точно знают, что можно грузить данные в несколько потоков.
Это означает, что JS файлы будут грузиться синхронно с страницей\другими файлами. Поэтому такая критичность в размещении «вставок» является попросту лишней. А размещение js в одном месте — удобство и эстетика.

Чтобы предотвратить споры как лучше — ссылочка на веб-стандарты

Таким образом, Да, скрипты лучше размещать сверху. Но огромной производительности в отрисовке не прибудет
Ссылочка вам противоречит:
Итак: для того, чтобы ваша страница могла начать отрисовку как можно быстрее, размещайте стили наверху. Чтобы избежать блокировки загружаемых ресурсов, размещайте скрипты внизу.
Заключение о расположении стилей и скриптов :)

Тем более, что Энди Дэвис в первую очередь ссылался на Chrome, который пока что не монополист…
В ссылке основное — сообщение Энди Дэвиса.

Он ссылается на Chrome, под капотом у которого Blink. А, насколько мне известно, только IE и Mozilla используют другой движок? Не уверен, но думаю, что аналогично параллельную загрузку поддерживают последние версии этих браузеров.
НЛО прилетело и опубликовало эту надпись здесь
Не думаю, что Opera в версии 12,5 не практикует многопоточную загрузку.
Во всяком случае, было бы интересно увидеть статью на хабре, в которой провели сравнение способов загрузки «тяжелых» страниц с помощью разных браузеров.
РТФМ. Пользователь не увидит страницу, пока не прогрузится скрипт из шапки. Скрипты всегда так делают если не объявлены дефер. Какой бы умный небыл браузер если он начнет грузить подругому, может сломать страницу.
IE, Mozilla, Safari, почти все смартфоны и планшеты — как бы аудитория вовсе не маргинальная.
IE (как минимум 10), Mozilla — не могут не пользоваться параллельной загрузкой (так как заметно бы уступали Chrome)
Safari работает на WebKit, не так?
Смартфоны и планшеты — здесь доминируют все те же браузеры. И опять же те же движки — WebKit, Blink. Насколько я понял и мобильная опера работает теперь на Blink — www.youtube.com/watch?v=Y70JypQCy08
Параллельная загрузка — не повод для некорректных обобщений, я больше об этом. Blink != WebKit.

По сабжу: обычно скрипты имеет смысл включать перед закрывающим body и не использовать никаких onload. Если на странице несколько блоков с непересекающимся функционалом, скрипты каждого блока включаются непосредственно после блока, опять же, не отслеживая загрузку всей страницы. Это рекомендация для веб-программистов в Google и некоторых других фирмах.

В качестве занятного исключения, иногда имеет смысл вынести в начало документа общие библиотеки.
Опять же, смотрите. Про Chrome — использование приоритетов загрузки.
Параллельная загрузка используется всеми браузерами. (опять же из письма Энди Дэвиса)
Особенно IE7 и IE8, которые до сих пор востребованы. Лично мне не хочется терять от 3% пользователей. А в случаях, когда заказчик к примеру банк, так и потерей всего проекта.
Если я буду неправ, поправьте пожалуйста.

Реализация задачи, как правило, зависит от конкретной задачи.
Нельзя найти «всегда верный» рецепт. Если целевая аудитория использует устаревшие браузеры, стоит заботится о них.
Такой сервис, например как soundCloud целевой аудиторией считает пользователей IE9+.

А говоря о скорости отрисовки страниц, то долгая отрисовка скорее всего означает «плохую» верстку, работу скриптов, и в меньшей степени порядок загрузки. Это влияет, да. Но менее критично (на порядок). Или я не прав?
НЛО прилетело и опубликовало эту надпись здесь
Особенно IE7 и IE8, которые до сих пор востребованы

Я даже на дату посмотрел. Думал, случайно попал в топик 2009-ого года.
Я тоже на дату вашего комментария посмотрел. Думал, случайно увидел коммент 2020 года. Потом глянул в гугл-аналитикс, и успокоился — как был IE8 на первом месте с 26%, так и остался.

А если серьезно (только вы не подумайте, что шутил про первое место и проценты, все так и есть на самом деле) — то все очень сильно зависит от аудитории сайта/приложения.
Сейчас запускаем проект на Америку, хотели отказаться от IE8, но это ~10% (против ~4% у «нас») :[
Да, я тоже говорил про штаты. Плюс, довольно консервативная в IT плане аудитория, школы не часто апгрейдят свои компьютеры.
Размещаю скрипты снизу, перед </body>. Это позволяет обойтись без $(document).ready(function() { /* ... */ });, который преврашает асинхронный JS в исполняемый последовательно.
который преврашает асинхронный JS в исполняемый последовательно

Что? Это как?
Вызовы $(document).ready() встают в очередь и исполняются последовательно. Каждый последующий вызов не будет выполнен, если предыдущий не завершился (return). Если предыдущий вызов завершился, а, например, бросил исключение, последующие $(document).ready() вообще не сработают.

Кроме того, код, который не обращается к DOM, не следует оборачивать в $(document).ready(), т. к. он будет заторможен безо всякой нужды.

Пруф: github.com/jquery/jquery/blob/1.4.2/src/core.js#L243

Например, вместо:

$(document).ready(function(){
  $.ajax({
    url: 'ajax.php',
    success: function(data) {
      $('#foo').text(data);
    }
  });
});

следует делать:

$.ajax({
  url: 'ajax.php',
  success: function(data) {       
    $(document).ready(function(){
      $('#foo').text(data);  
    });
  }
});
Если уж разговор зашел об оптимизации кода, в том числе и с целью увеличения производительности, тот вот эта ссылка просто бесценна:

http://shichuan.github.io/javascript-patterns/

Многочисленные паттерны (и антипаттерны для сравнения) написания оптимальных конструкций с обоснованием.

Один из примеров:

// antipattern
// create and append your element
$(document.body).append("<div class='baaron' />");
// requery to bind stuff
$("div.baaron").click(function () {...});


// preferred
// swap to appendTo to hold your element
$("<div class='baaron' />")
    .appendTo(document.body)
    .click(function () {...});
Не вижу в какой части статьи пошла речь об оптимизации кода
В оптимизации кода на jWhatever все должно сводится к минимизации использования библиотеки.
Для выбора первых, последних или определённых элементов используйте .first(), .last(), .eq( index )

Недавно выяснил, что $('.class:first-child') работает заметно быстрей чем $('.class').first()
Когда создатель сайта помещает скрипты перед «</body>», то показывает элементы сайта быстрее, но зато дольше показывает их непроскриптованными.

Вместо того, чтобы недоумевать «чего это сайт долго грузится», читатель принуждён недоумевать «чего это кнопка не нажимается», «чего это список не разворачивается при наведении и даже тычке», «чего это в галерее картинки не крутятся», «чего это вместо AJAX срабатывает переход на другую страницу», или как-нибудь ещё в этом же роде.

Так что здесь получается не только решение проблемы (хотя и впрямь существующей), но и создание одной проблемы вместо этой. И выбор между ними надо делать трезво, в полном осознании того, какую проблему удобнее и уместнее считать для себя (для своего сайта) более существенною, чем другую.
Когда вы размещаете скрипты в <head>, вы вынуждены использовать $(document).ready(function() { /* ... */ });. Это, конечно, гарантирует, что пользователь не увидит неинтерактивного HTML, но появляется другая проблема: асинхронный JS превращается в исполняемый последовательно.
Вот поэтому нужно оптимизировать код, минифицировать CSS/JS/изображения, использовать спрайты, lazy load, сокращать количество HTTP запросов, применять nojs фолбеки, но никак не блокировать интерфейс.
Есди вы назваете блокировкой интерфейса — время, после загрузки DOM, до полной инициализации ui, то это вы зря. Человеку необходимо минимум 0.4 секунды на реакцию, а так же в добавок время до какого либо действия. Скрипты выполняются быстрее, гораздо быстрее.
На самом деле ответ на действие пользователя превыщающий 100мс уже заметен и в большинстве случаев это раздражает.
Если страница поддерживает прогрессивные улучшения (сиречь работает с выключенным JS) — это и не проблема даже, а просто вариант поведения, который увидят пользователи без JS.
В общем случае Гугл рекомендует своим разработчикам не перед закрывающим body загружать скрипты, а сразу после элемента, которому эти скрипты нужны.
> Inline JavaScript в HTML коде
> Во-первых, это некрасиво, неуклюже и со старта похоже на костыль.
Это не совсем так.
Если мы уж заговорили об оптимизации, то часто выгоднее иметь весь js код инлайном внутри страницы нежели ссылку, пусть даже на единственный агреггированный js файл. Пример — главная страница google где почти 80% кода страницы именно inline js.

>И наконец, эти скрипты не могут быть автоматически минифицированы и сжаты (gzip), что скажется на производительности продакшн сервера.
Этот тезис не очень понял. Отдаваемый html код, со всеми inline скриптами точно так же может быть сжат.

часто выгоднее иметь весь js код инлайном внутри страницы

Это чем-то обоснованно?

главная страница google где почти 80% кода страницы именно inline js

Ну, если вы заговорили про гугл… Гугл генерирует оутпут, но никак не хардкодит JS прям в шаблоне :) (это только мои догадки кончено, но код вида «google.promos.toast.cl=function(){try{window.gbar.up.sl(g,e,a.k,void 0,1)}catch(b){google.ml(b,!1,{cause:e+»_CL"})}" я бы не назвал редактируемым).
> Это чем-то обоснованно?
Безусловно. Время на установку соединения, и скачивания внешнего js файла даже самого маленького, на порядки больше чем время которое нужно потратить на скачивания html страницы с inline js

Сколько людей — столько мнений.

Я так предпочитаю упустить эту микро оптимизацию, вместо которой сделать код понятным, читабельным и редактируемым.
Эта микрооптимизация может стоить вам от 40мс и выше на открытие страницы.
Причём как в положительную, так и отрицательную сторону. От большого размера HTML некоторые браузеры имеют свойство загибаться.
>И наконец, эти скрипты не могут быть автоматически минифицированы и сжаты (gzip), что скажется на производительности продакшн сервера.

Вы неправы по поводу gzip. Обычно страница гзипуется вся, включая инлайн скрипты.
Вы отчасти неправы по поводу минифкации, потому что в шаблонах можно инклюдить уже собранный минифицированный файл.
НЛО прилетело и опубликовало эту надпись здесь
Статья будет интересна новичкам JS и jQuery

Но решать вам конечно, для кого написана статья.

В код скрипты эмбеддят

Если идти от размера проекта:
— крохотный — ваш загрузчик бесполезная штука. Легче подключить вручную 0-2 скрипта
— средний — ваш загрузчик бесполезная штука (чуть менее бесполезней чем в прошлом пункте). Если на странице до 5 скриптов, зачем догружать ещё один?
— всё что больше среднего — для таких проектов в основном используют бекенд фреймворки. Которые уже давно научились работать с CSS и с JS (ассеты). Тут ваш загрузчик вообще бесполезен.

В частных случаях может быть иначе. Но опираться на них не стоит.
НЛО прилетело и опубликовало эту надпись здесь
Тут скорее «на что» рассчитан модернайзер. По-моему так он рассчитан на своеобразные проекты, где JS преобладает над интерфейсом, без бекенд основы (либо с минимальным её использованием).
К примеру:
сайты-визитки, с разными плюшками
внешние плагины, api (ну к примеру те же гугл карты или видео плееры)
смартфонные приложения ещё можно включить в список

Если всё таки «на кого», то я так предполагаю, что на верстальщиков и скрипто-кодеров.
НЛО прилетело и опубликовало эту надпись здесь
:oops: Sorry, my fault.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории