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

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

Если вам кажется необходимым перевести какой-либо материал по программированию, которого ещё не было на Хабре — пишите в личку.
Присоединяюсь. Готов перевести интересный материал для Хабра (я переводчик, если что :) JS, веб-программирование, вёрстка — желательно предлагать что-нибудь из этой области.
Регулярно в дайджестах есть список статей на английском языке. Можно просто после такого дайджеста устроить голосование и статью-победителя перевести.
Так же было бы круто перевести статьи по ссылкам из данной
Ооочень полезная статья. К прочтению.
После прочтения ещё будет не лишним поглядеть доклад уже упомянутого в посте Вячеслава Егорова — www.youtube.com/watch?v=65-RbBwZQdU
Что-то я сомневаюсь, что картинка со сравнением быстродействия массивов подписана правильно. Скорее всего там всё-таки не число операций в секунду, а время выполнения и, соответственно, чем больше, тем хуже. А значит и вывод сделанный из картинки — не верен.
это jsperf.com'овые графики, он все выражает в операциях в секунду.
Я вижу, что это jsperf, поэтому не знаю, почему закралась ошибка, но предпочитаю верить своим глазам и логике. Да и любой желающий может сходить по имеющейся в тексте ссылочке на тот же jsperf и провести тесты самостоятельно, чтобы убедиться в том, что результаты противоположны. Например, у меня для chrome.39 пустой массив выдал 30 op/sec, а предзаполненный 133 op/sec. Для firefox.35 аналогично 81/87, opera.12 — 51/54, safari.5 — 45/46

Но можно и просто увидеть нелогичность картинки — если ей верить, то у всех браузеров с появлением новых версий производительность падает. Иногда так бывает, но так не может быть для всех браузеров.
Лимит про 100000 для new Array(n) стал для V8 неактуальным после codereview.chromium.org/397593008, теперь преаллокация быстрее, потому что преалоцированный массив остается быстрым. До этой правки он превращался в словарь.
Между статьёй и вами разница в 15 мажорных версий браузера и более 2 лет времени. Теперь и прототипы быстрее модулей под любым соусом, и предзаполненные массивы на полтора порядка быстрее.
«Не удаляйте элементы массивов» — а если это необходимо?
Нельзя чтоб образовывался 'пробел' в массиве, окей это понятно, но как поступить лучше? Перестроить массив через лодашевский _.without — нормальный вариант?

«Избегайте использования delete при удалении элементов объекта» — опять же, вот нужно мне по логике удалить элемент из объекта, как лучше поступить?
НЛО прилетело и опубликовало эту надпись здесь
Рекомендации про удаление относится к использованию оператора delete.

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

Если же у вас именно объект — то лучше просто сделать o.p = null.

С массивом точно также — если массив уже разреженный с кучей дырок, т.е. словарь по сути дела — то пользуйтесь delete, в противном случае либо a[i] = null или двигайте элементы вниз (тем же splice или руками)

Все эти рекомендации не следует применять в слепую — надо просто понимать потенциальные проблемы, профилировать и решать уже после профилировки как разбираться с hotspotами.
Небольшой оффтоп, недавно наткнулся на такой странный код:

function toFastProperties(obj) {
  function f() {}
  f.prototype = obj;
  return f;
  eval(obj);
}

Если не ошибаюсь, этот код — оптимизация для v8, обусловленная разницей внутреннего представления объектов-словарей и объектов-структур. Можете прокомментировать его и актуально ли подобное сейчас?
Это хак связанный с тем, что V8 старается держать прототипы объектов в fast mode. Получается, когда вы присваиваете медленный объект (dictionary/slow mode) в f.prototype он превращается в быстрый.

Сей хак актуален, если вы знаете, что у вас есть объект находящийся по какой-то причине в словарном режиме и вам хочется его превратить в быстрый объект.
a[i] = null в данном случае разве не сделает массив массивом смешанных типов? То есть какого-то однозначно рекомендуемого метода нет, и надо выбирать компромиссное решение в зависимости от ситуации?
Разумеется если массив у нас изначально состоит из чисел (для других случаев тип элементов не отслеживается), то null действительно переведёт его просто в массив «чего угодно»), в этом случае a[i] = null не подходит. Надо либо сдвигать элементы, либо писать специальный маркер в несуществующие позиции (например, a[i] = 0). Конкретный подход зависит от назначения конкретного массива и причин, по которым нужно из него удалять элементы.
А точно в Backbone есть dispose? Потому что в свежей версии такой функции нет.

Большая проблема со статьями такого рода — они все уже давно устарели. Конкретно в этой статье предлагается набор советов от 2012 года. Уже 3 года прошло, большинство из этих советов — неактуальны.

Предлагаю автору добавить вверху дату оригинальной статьи, иначе на текущий момент многие из советов можно отнести к разряду «вредных».
AFAIK в Backbone никогда не было функции/метода с таким именем. Возможно это опечатка. Не знаю, что там имел в виду Эдди, но по смыслу там подходит stopListening.
В примере с генераций таблицы и добавления евентов есть косяк кажется. Переменная frag2 должна пересоздаваться внутри цикла for потому что сейчас каждая следующая строка таблицы будет содержать все td из предыдущих рядов.
Статья хорошая, но хотелось бы побольше услышать про оптимизацию именно при работе с DOM, т.к. какой бы быстрой не была функция и какой бы эффективной не была сборка мусора и распределение памяти — всё это сходит на нет, если мы собираемся много работать с DOM. В тексте статьи по этому поводу сказано фактически лишь одно — не работайте с DOM в цикле, для этого надо использовать documentFragment. Но что, если сам по себе documentFragment является очень большим, например, таблица 1000 строк по 5 колонок? У меня встраивание такого фрагмента вызывало небольшие подвисания браузера (приблизительно 0.5 с), какие бы рекомендации вы могли дать?
НЛО прилетело и опубликовало эту надпись здесь
Я всегда думал, что браузер делает пересчет уже на следующем «тике», когда текущий фрагмент js-кода «отпустил» однопоточный интерпретатор и управление вернулось назад в ядро js. Т.е. вставите вы в DOM 1 элемент или 100 — все равно пересчет будет выполнен 1 раз, когда произойдет выход из всех запущенных вложенных функций. Я так думал. Но это, похоже, неверно в силу замечаний про DocumentFragment? Поясните, пожалуйста.

Даже метод такой был: выполнять какие-то вещи на setTimeout(..., 1), т.е. на следующем событийном цикле, когда браузер пересчитал ширины-высоты.
советую почитать про дерево перерисовки и работу селекторов, чтобы понимать про DOM лучше. Можно также соответствующую главку из книжки
speedupyourwebsite.ru/books/reactive-websites/
Есть и непонимание по поводу того, как работает null. Установка ссылки на объект в null не обнуляет объект. Писать o.x = null лучше, чем использовать delete, но смысла это не имеет.

var o = { x: 1 }; 
o = null;
o; // null
o.x // TypeError

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

Верно написано, что переменная является всего лишь ссылкою на объект. Но именно поэтому её и зануляют (обращают в null), чтобы не оставалось лишних ссылок на объект и начал работать сборщик мусора, подчистив объект. Если переменная является частью области видимости некоторого замыкания, то ссылка на объект может жить очень долго, если её не занулить — именно так и возникают «утечки памяти».
Если кратко:

1. Не используйте переменные.
2. Если очень надо их использовать, хотя бы не записывайте в них значения и нигде не используйте.
При создании таблицы, мне кажется лишним добавление ячеек во фрагмент, почему их сразу не добавлять в элемент строки, ведь элемент строки находится во фрагменте и добавление ячеек в строки не вызовет перерисовки. Так что
frag2.appendChild(td);
мне кажется лишними телодвижениями.
«простить исправить» — красиво звучит :-)
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации