Size: a a a

Иван Акулов про разработку

2017 July 17
Иван Акулов про разработку
источник
2017 July 22
Иван Акулов про разработку
Если вы слушаете и обрабатываете события вроде mousemove, resize или scroll, ваша страница может тормозить. Такие события генерируются пачками по много штук в секунду. Если обработчик занимает много времени, браузер может не успевать перерисовывать страницу.

Вот что использовать, если сталкиваетесь с такой проблемой:

Throttling
По умолчанию код в обработчике события выполняется при каждой генерации события. Иногда нормально, если этот код будет выполняться не при каждом событии, а, например, раз в 100–200 мс. Чтобы «замедлить» код таким образом, можно использовать утилитный метод _.throttle (статья на CSS-Tricks).

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

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-throttling-js

passive: true
passive: true — это флаг, который передаётся в addEventListener. Он говорит браузеру, что обработчик события пассивный — то есть он никогда не вызовет event.preventDefault(). За счёт этого браузер может выполнять действие, которое обработчик мог бы отменить, сразу же — не дожидаясь, пока закончит выполняться JS-код. (Описание флага на GitHub)

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

Но в целом — думаю, можете смело использовать passive: true для всех событий, которые не вызывают event.preventDefault. Хуже не будет, лучше может быть.

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-passive-js

Оптимизировать сам код
Посмотрите — может, вместо throttle можно оптимизировать сам код, закешировав часть вычислений. Это будет лучше всего — частота обработки событий будет такая же, а тормозить ничего не будет.

Как оптимизировать — зависит от вас. Если у вас React, и в обработчике событий вы изменяете стейт, можете попробовать отрезать часть дерева рендеринга с помощью shouldComponentUpdate.

Рассчитывайте, что, чтобы не пропускать кадры, обработчик должен занимать не больше 10 мс. Бюджет каждого кадра — 16 мс, и браузеру за этот кадр нужно успеть выполнить не только JS-код. Чтобы проверить, сколько времени занимает ваш обработчик, используйте Web Performance API или вкладку Performance в Chrome DevTools.
источник
Иван Акулов про разработку
А вот что не поможет:
requestAnimationFrame. С медленными обработчиками это никак не поможет, а для быстрых бессмысленно. В общем, используйте его для JavaScript-анимаций, для всего остального он, кажется, бесполезен.

Делегация событий. Она оптимизирует потребление памяти, а не скорость.

Вот такое. Оптимизируйте.
источник
Иван Акулов про разработку
iamakulov_channel
Если вы слушаете и обрабатываете события вроде mousemove, resize или scroll, ваша страница может тормозить. Такие события генерируются пачками по много штук в секунду. Если обработчик занимает много времени, браузер может не успевать перерисовывать страницу.

Вот что использовать, если сталкиваетесь с такой проблемой:

Throttling
По умолчанию код в обработчике события выполняется при каждой генерации события. Иногда нормально, если этот код будет выполняться не при каждом событии, а, например, раз в 100–200 мс. Чтобы «замедлить» код таким образом, можно использовать утилитный метод _.throttle (статья на CSS-Tricks).

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

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-throttling-js

passive: true
passive: true — это флаг, который передаётся в addEventListener. Он говорит браузеру, что обработчик события пассивный — то есть он никогда не вызовет event.preventDefault(). За счёт этого браузер может выполнять действие, которое обработчик мог бы отменить, сразу же — не дожидаясь, пока закончит выполняться JS-код. (Описание флага на GitHub)

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

Но в целом — думаю, можете смело использовать passive: true для всех событий, которые не вызывают event.preventDefault. Хуже не будет, лучше может быть.

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-passive-js

Оптимизировать сам код
Посмотрите — может, вместо throttle можно оптимизировать сам код, закешировав часть вычислений. Это будет лучше всего — частота обработки событий будет такая же, а тормозить ничего не будет.

Как оптимизировать — зависит от вас. Если у вас React, и в обработчике событий вы изменяете стейт, можете попробовать отрезать часть дерева рендеринга с помощью shouldComponentUpdate.

Рассчитывайте, что, чтобы не пропускать кадры, обработчик должен занимать не больше 10 мс. Бюджет каждого кадра — 16 мс, и браузеру за этот кадр нужно успеть выполнить не только JS-код. Чтобы проверить, сколько времени занимает ваш обработчик, используйте Web Performance API или вкладку Performance в Chrome DevTools.
Кстати, вот как различается скроллинг без passive: true и с ним. Слева — без него. Огонь: https://www.youtube.com/watch?v=NPM6172J22g
источник
Иван Акулов про разработку
iamakulov_channel
Если вы слушаете и обрабатываете события вроде mousemove, resize или scroll, ваша страница может тормозить. Такие события генерируются пачками по много штук в секунду. Если обработчик занимает много времени, браузер может не успевать перерисовывать страницу.

Вот что использовать, если сталкиваетесь с такой проблемой:

Throttling
По умолчанию код в обработчике события выполняется при каждой генерации события. Иногда нормально, если этот код будет выполняться не при каждом событии, а, например, раз в 100–200 мс. Чтобы «замедлить» код таким образом, можно использовать утилитный метод _.throttle (статья на CSS-Tricks).

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

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-throttling-js

passive: true
passive: true — это флаг, который передаётся в addEventListener. Он говорит браузеру, что обработчик события пассивный — то есть он никогда не вызовет event.preventDefault(). За счёт этого браузер может выполнять действие, которое обработчик мог бы отменить, сразу же — не дожидаясь, пока закончит выполняться JS-код. (Описание флага на GitHub)

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

Но в целом — думаю, можете смело использовать passive: true для всех событий, которые не вызывают event.preventDefault. Хуже не будет, лучше может быть.

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-passive-js

Оптимизировать сам код
Посмотрите — может, вместо throttle можно оптимизировать сам код, закешировав часть вычислений. Это будет лучше всего — частота обработки событий будет такая же, а тормозить ничего не будет.

Как оптимизировать — зависит от вас. Если у вас React, и в обработчике событий вы изменяете стейт, можете попробовать отрезать часть дерева рендеринга с помощью shouldComponentUpdate.

Рассчитывайте, что, чтобы не пропускать кадры, обработчик должен занимать не больше 10 мс. Бюджет каждого кадра — 16 мс, и браузеру за этот кадр нужно успеть выполнить не только JS-код. Чтобы проверить, сколько времени занимает ваш обработчик, используйте Web Performance API или вкладку Performance в Chrome DevTools.
А если вы ещё вдруг знаете случаи, когда passive: true помог не только со скроллингом или когда он, наоборот, помешал, расскажите, пожалуйста: @iamakulov
источник
2017 July 24
Иван Акулов про разработку
Рубрика #TodayILearned

Вебпак давно — год точно, наверняка дольше — позволяет задавать загрузчики в строке импорта. То есть обычно, если вы хотите импортировать CSS-файл, вы создаёте файл webpack.config.js и указываете там нужный загрузчик:

module.exports = {
  module: {

    rules: [

      {

        test: /\.js$/,

        use: [

          'style-loader',

          { loader: 'css-loader', options: { modules: true }

        ]

      }

    ]

  }

}


А Вебпак позволяет задавать их ещё и в строке импорта:

import rainbow from 'style-loader!css-loader?modules=1!./skittles.js'

Загрузчики соединяются восклицательными знаками, опции передаются через query string. Прикольно, но непрактично.

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

import rainbow from '!!style-loader!css-loader?modules=1!./skittles.js'

И вот для чего это служит:
источник
Иван Акулов про разработку
источник
Иван Акулов про разработку
То есть префиксы вроде !! нужны, если для файла уже определены какие-то загрузчики, а вам нужно переопределить их совсем. Например, если у вас уже есть загрузчики для CSS, то import 'raw-loader!./file.css' не заработает, а import '!!raw-loader!./file.css' корректно проимпортирует ваш файл в строку

Ну а вообще такие импорты плохи, потому что привязывают ваш код к билд-системе. Они полезны только в исключительных случаях (у меня час назад был первый за всё время). Старайтесь использовать только конфиг
источник
2017 July 25
Иван Акулов про разработку
iamakulov_channel
Если вы слушаете и обрабатываете события вроде mousemove, resize или scroll, ваша страница может тормозить. Такие события генерируются пачками по много штук в секунду. Если обработчик занимает много времени, браузер может не успевать перерисовывать страницу.

Вот что использовать, если сталкиваетесь с такой проблемой:

Throttling
По умолчанию код в обработчике события выполняется при каждой генерации события. Иногда нормально, если этот код будет выполняться не при каждом событии, а, например, раз в 100–200 мс. Чтобы «замедлить» код таким образом, можно использовать утилитный метод _.throttle (статья на CSS-Tricks).

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

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-throttling-js

passive: true
passive: true — это флаг, который передаётся в addEventListener. Он говорит браузеру, что обработчик события пассивный — то есть он никогда не вызовет event.preventDefault(). За счёт этого браузер может выполнять действие, которое обработчик мог бы отменить, сразу же — не дожидаясь, пока закончит выполняться JS-код. (Описание флага на GitHub)

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

Но в целом — думаю, можете смело использовать passive: true для всех событий, которые не вызывают event.preventDefault. Хуже не будет, лучше может быть.

Код «до — после»: https://gist.github.com/iamakulov/9c19f872bbbc05b20904db5a2041cd36#file-passive-js

Оптимизировать сам код
Посмотрите — может, вместо throttle можно оптимизировать сам код, закешировав часть вычислений. Это будет лучше всего — частота обработки событий будет такая же, а тормозить ничего не будет.

Как оптимизировать — зависит от вас. Если у вас React, и в обработчике событий вы изменяете стейт, можете попробовать отрезать часть дерева рендеринга с помощью shouldComponentUpdate.

Рассчитывайте, что, чтобы не пропускать кадры, обработчик должен занимать не больше 10 мс. Бюджет каждого кадра — 16 мс, и браузеру за этот кадр нужно успеть выполнить не только JS-код. Чтобы проверить, сколько времени занимает ваш обработчик, используйте Web Performance API или вкладку Performance в Chrome DevTools.
Ещё пара подходов к оптимизации:
— Виталий Кузьмич на Facebook-странице (http://bit.ly/2tzmBqJ) упомянул ResizeObserver. Это API, которое позволяет отслеживать ресайзы конкретных элементов: https://developers.google.com/web/updates/2016/10/resizeobserver

API ещё нигде нормально не поддерживается, но есть какой-то полифилл: https://github.com/que-etc/resize-observer-polyfill

— А я вспомнил про window.matchMedia. С помощью этого метода можно вызывать колбеки, когда окно браузера достигает определённой ширины: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Testing_media_queries

window.matchMedia поддерживается в IE10+.

В общем, если вы слушаете событие resize только для того, чтобы делать одну из этих двух штук, можно заменить его на эти специализированные API.
источник
2017 July 26
Иван Акулов про разработку
Никита Прокопов пишет про проблему с API на естественном языке (там немного предыстории в его канале):
источник
Иван Акулов про разработку
на это даже программисты попадаются. Было такое движение про DSL и тесты на «почти естественном языке». Вот пример из Ruby нагуглился

allow(Resource).to receive(:where).with(created_from: params[:id]).and_return(false)

Все конечно классно, и предлоги согласованы и все такое, но не очень понятно, как это разобрать на кусочки и  как ими жонглировать. Также непонятно, что тут осмысленно, а что для красоты. Одна и та же вещь может в разных контекстах (разное место в предложении) выглядеть по-разному. Короче, все недостатки естественного языка там, где, вроде бы, уже давно разобрались как от них избавиться. Стабильный, однозначный, атомарный API — большая сила
источник
Иван Акулов про разработку
Собственно, эта же проблема — у expect-синтаксиса в chai. Выглядит он вот так:

expect(function () {}).to.not.throw();
expect({a: 1}).to.not.have.property('b');
expect([1, 2]).to.be.an('array').that.does.not.include(3);

Хотя читается это интересно, писать и поддерживать его очень неудобно — приходится постояно подсматривать в документацию и проверять, какое слово нужно написать и что после после него ставить: точку или скобки. И эта проблема существует именно потому, что синтаксис основан на естественном языке.

Я когда-то поддался и заиспользовал этот API, потому что в описании было написано «BDD-синтаксис», и я посчитал, что это «более правильно». Оказалось очень неудобно. Не повторяйте моих ошибок.

Если что, то взамен можно использовать, например, assert-синтаксис из chai или такой же нодовский модуль.
источник
Иван Акулов про разработку
🔥 Вышла бета Реакта 16: https://github.com/facebook/react/issues/10294

Теперь наконец-то:
— Можно возвращать массивы из render()
— Можно ловить ошибки рендера с помощью componentDidCatch. Раньше такие ошибки ломали всё приложение. Пост в блоге фейсбука
— Стектрейсы ошибок будут читабельнее (но я ещё не смотрел, в чём разница)

А в будущих версиях Фейсбук начнёт экспериментировать с асинхронным рендерингом компонентов. Идея — задерживать отрисовку компонентов, которые находятся вне экрана, чтобы приложение работало плавнее. Скорее всего, это будет в 16.x.

Всё это стало возможным благодаря полностью переписанным внутренностям фреймворка. Новая архитектура называется React Fiber. Эндрю Кларк из Фейсбука описал её основные принципы в прошлом году, почитайте: https://github.com/acdlite/react-fiber-architecture
источник
2017 July 28
Иван Акулов про разработку
iamakulov_channel
А если вы ещё вдруг знаете случаи, когда passive: true помог не только со скроллингом или когда он, наоборот, помешал, расскажите, пожалуйста: @iamakulov
Разобрался сам :–)
источник
Иван Акулов про разработку
Когда слушатели событий с passive: true действительно помогают: https://gist.github.com/iamakulov/45803e89db2eb44a7a6be33a80ffcab7
источник
Иван Акулов про разработку
Новый пост! Как оптимизировать ресайз, скролл и другие повторяющиеся события: https://iamakulov.com/notes/resize-scroll/

Основан на материалах, которыми я уже сюда делился, но улучшен и расширен.
источник
2017 July 31
Иван Акулов про разработку
источник
Иван Акулов про разработку
Ох! Вот этот ↑ стандартный паттерн сервер-сайд-рендеринга, оказывается, содержит XSS-уязвимость: https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0

(Рубрика #TodayILearned)
источник
Иван Акулов про разработку
Олег Мохов из Яндекса ведёт замечательный канал про управление разработчиками:
источник
Иван Акулов про разработку
Очень частый вопрос: как из разработчика стать управленцем? Если коротко, то ответ такой: никак.

Для начала бывают технические лидеры (или техлиды), а бывают руководители. Техлиды ведут техническую часть проекта. Они ответственны за качество кода, но не ответственны за продукт. Они управляют кодом, который пишут участники проекта, но не вмешиваются в процесс создания продукта. Технические лидеры – это старшие товарищи на проекте, с богатым багажом опыта. Во многих компаниях совершается одинаковая «классическая» ошибка – это назначение руководителем техлида (или старшего разработчика). Я называю это «убийством разработчика», но почему-то многие считают это логичным продолжением карьеры: разработчик – старший разработчик – техлид. Нет, не делайте так, техлид – это тот кто принимает технические решения, ревьюит код, менторит джунов и новеньких, но он не занимается руководством командой. Многие техлиды не хотят руководить, им нравится писать код и они эффективны именно в этом, но будут не эффективны как руководители или могут вообще уволиться через полгода, после «долгожданного повышения».

А чем же занимается руководитель? Найм, команда и процесс – вот три столпа руководителя. О каждом я подробнее расскажу в следующих постах, а сейчас надо ответить на другой вопрос: «Кто такой хороший руководитель?» или даже «Какие качества должны быть у хорошего руководителя?».

Есть много разных статей про руководство в которых подробно описан портрет хорошего руководителя, вот очень неплохую подборку совсем недавно скинул Костя Горский (кстати, подписывайтесь на его канал – https://t.me/desprod, Костя хороший) – https://medium.com/@allo/о-заметках-ce3a8bdd56af. Но я лично считаю важным одно качество –  проактивность. Именно поэтому ответ на вопрос: как стать? – Никак. Проактивность невозможно развить, она либо есть и хлещет, либо её нет. Точка. Проактивность двигает горы, потому что человека сложно остановить. Фразы вроде «так было всегда» и «мы не будем ничего менять» не действуют. Проактивный человек, а тем более руководитель, всегда задаёт вопрос: «Что я могу изменить, чтобы стало лучше?». Он задаёт его себе, задаёт своим коллегам, задаёт даже случайному прохожему на улице. И находит ответ. А дальше он пробует что-то менять, и если не получается, то снова спрашивает себя что он может изменить и далее по кругу.

Но проактивность – это необходимое, но не достаточное условие для того чтобы стать руководителем. Допустим человек обладает этим качеством и его делают руководителем. В чём здесь проблема? А она в том, что руководство – это абсолютно новые функции, которым, чаще всего, не учат. И в этом заключается ещё одна ошибка – процесс входа в должность отпускается на самотёк, вроде бы итак понятно что делать. Хотя нет, конечно бывают исключения, и если в вашей компании всё хорошо с процессами, то после назначения вам должна упасть куча встреч, объясняющих что теперь ваша работа будет совсем другой. Но если у вас не так, то (помним про проактивность) нужно пойти к своему руководителю и попросить его научить руководить. Можно не так, можно попросить его рассказать из чего состоит его день. Суть здесь очень простая – вам нужен ментор. Вы новичок в этой профессии, джун можно сказать. А к джунам всегда приставляют ментора. И уже потом я рекомендую вам закидываться кипой книжек на тему «что такое быть руководителем?»

И, наконец, третья ошибка. Руководителю придется смириться, что теперь его основная функция, KPI, хлеб и прочее – это управление. И только потом написание кода. Так, ну и в чём же ошибка? А она просто в том, что никто ничего такого не говорит новоиспечённым руководителям. Никто не объясняет, что нормально, к примеру, весь день ходить по встречам. И вот, став руководителем, у человека начинается жуткая депрессия, что он «не делает ничего полезного, а только по встречам ходит». Тут беда в том, что разработчиками эти же встречи не воспринимаются как работа, но скорее как необходимость. А тут встреч стало в 5 раз больше. И вообще, получается, не работаешь... Так вот, ребята-руководители – не писать код это нормально. Я вам говорю! 😉
источник