Подписка на блог

Ещё есть Тумблер и ЖЖ.

В  Телеграме пишу обо всяком и собираю по крупицам годноту, которая потом появляется в блоге.

А в  Твиттере иногда репощу всякие смехуечки и пишу о том, как всё плохо.

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

11 заметок с тегом

разработка

Четыре вопроса про БЭМ

Последнее время меня всё чаще спрашивают про БЭМ. Потому я собрал самые частые вопросы и ответы на них в статью, чтобы было легче отвечать. Как обычно ¯\_(ツ)_/¯.

БЭМ?

Сперва стоит оговорить несколько важных моментов.

Во-первых, речь пойдёт о БЭМ в вёрстке и БЭМ на файловой системе. Основные моменты можно прочитать разделе «Быстрый старт» документации. То есть, речь не о «полном БЭМ-стеке», который вкалывают себе ребята из Яндекса. Это слишком тяжёлый наркотик для обывателя. Не пробуйте, если совсем неопытны.

Во-вторых, и это важно, каждый трактует БЭМ по-своему. И у этого есть одна очевидная причина — БЭМ почти не ограничивает. По сути вся методология — это набор советов, или, если угодно, максим, которые просто определяют границы добра и зла. А то, в каких пропорциях их смешивать (и смешивать ли) — это уже на вашей совести. Однако, это не значит, что можно воровать-убивать в коде потому что «художник так видит».

Вопрос первый, про именование сущностей и выделение блоков

Спрашивает М. из, наверное, славного города Ш.:

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

Допустим, мне нужно сделать список. Как я обычно делаю:

.list
  .list__item
  .list__item

Тут всё ок. Но что, если этот пример усложнить? Если list__item — это сложный блок, у которого есть свои элементы, то нужно создавать отдельный блок или делать это элементами list?

Я думал, что правильно именно так:

.list
  .list__item
    .list-item  // новый блок
      .list-item__title
      .list-item__button
  .list__item

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

.list
  .list__item
    .list__title
    .list__button
  .list__item

Но с другой стороны list__title говорит о том, что это заголовок листа, а не одного элемента. И вот это меня постоянно вводит в ступор.

Дорогой М.!

Давай разберём по порядку.

Во-первых, про выделение элемента в отдельный блок. Это можно сделать, но на практике нужно очень редко. Обычно это сигнал к тому, что блок в целом перегружен, что ты пытаешься сделать его очень универсальным, и скорее всего можно сделать намного проще, если позволить себе некоторое дублирование, или же введение большего количества модификаторов.

Часто такой выделенный в самостоятельный блок элемент называется «служебным» или «приватным». Когда-то так делали ребята из Яндекса, например, в своей библиотеке компонентов.

Приватным он называется потому, что в силу его истории его можно использовать только внутри блока, из которого его выделили (в твоём случае только внутри list). Формально — это нарушение методологии, которая утверждает, что блок должен быть независимым. На практике же — это сделка с совестью, которая или позволяет тебе делать так, или не позволяет. Если ты не уверен, что чётко понимаешь себе плюсы и минусы такого решения, то лучше так не делать.

Во-вторых, вот такой код не очень крут:

.list
  .list__item
    .list-item  // новый блок
      .list-item__title
      .list-item__button
  .list__item

В большинстве случаев правильнее будет сделать так:

.list
  .list-item.list__item
    .list-item__title
    .list-item__button
  .list-item.list__item

То есть, в подобных случаях удобнее смиксовать элемент item блока list с тем приватным блоком, что ты выделил. Тогда list-item будет отвечать только за внешний вид самого элемента списка, а list__item — за его позиционирование в рамках всего списка (которое может меняться в зависимости от модификаторов).

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

В-третьих, вот этот код тоже решает поставленную проблему:

.list
  .list__item
    .list__title
    .list__button
  .list__item

И тут тебя верно смущает тот факт, что list__title как бы намекает, что это «название списка». Но это зависит от того, как именно ты и твоя команда понимает БЭМ. Для меня, например, это «какое-то название внутри списка». Это вполне может быть и названием пункта, и названием целого списка и пр. Некоторые для устранения таких разночтений делают, например, list__item-title. Однако, это не всегда хорошо и если таких элементов появляется много, то это как раз звоночек о том, что list__item перегружен, и возможно стоит выделить его в отдельный приватный блок.

Или же не париться и делать более абстрактные элементы, типа list__title.

Как я уже говорил выше, БЭМ накладывает не так много ограничений, и скорее лишь указывает «как было бы правильнее». А как трактовать это — это уже зависит от команды. В каждом из решений есть свои изъяны:

  • list__item-title рождает новый уровень зависимости. Потому что получается, что есть отдельные элементы, которые привязаны к другим элементам. Но это решается просто игнорированием этого факта и принятием того, что это норма. Да, бывают элементы «заголовок пункта». И что? Не написано же, что это list__title-of-list__item. Просто заголовок какого-то пункта.
  • list-item__title рождает новый блок, который получается жёстко привязан к list и не может использоваться в отрыве от него. Но это решается принятием того, что у нас есть такие блоки. Иногда бывает намного удобнее декомпозировать таким образом, ничего не поделаешь. Как только мы принимаем, что у нас бывают подобные блоки, жить становится легче. Главное определить для себя, когда они нужны, а когда они излишни.
  • list__title же рождает непонятку, о которой ты написал. Но это решается бóльшим абстрагированием от общей сути блока. Это просто какое-то название внутри списка. Зато это даёт чуть больше гибкости. Например, у тебя может быть list__title_type_main и list__title_type_item. А может и не быть.
  • list-title, кстати, тоже решение. Оно, пожалуй, наиболее далёкое по смыслу от всего того, что есть тут. Но с другой стороны, если у тебя есть разные списки, то list-title вполне может быть таким элементом, который реализовывает заголовок внутри любого списка.

Ключевой смысл БЭМ в независимости между блоками, которую мы по умолчанию определяем. Если в каких-то местах нам нужно во имя чистоты абстракции и читабельности кода пожертвовать этой независимостью, лучше это сделать. Потому что поддерживать код куда важнее, чем писать его «абсолютно правильно».

Вопрос второй, про общие ресурсы

Вопрошает И., из славного города К.:

Что делать и как быть, если нужно зашарить один объект между блоками? Например, картинку.

Дорогой И.!

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

  1. Самостоятельная единица, которая может использоваться без привязки к конкретным блокам. Например, логотип или какое-то отдельное изображение на каком-нибудь лэндинге, которое встречается там несколько раз.
  2. Обычное изображение, которое по каким-то причинам пришлось использовать в двух блоках сразу.

Теперь про каждую подробнее.

Самостоятельная единица

В общем-то, формулирование проблемы уже описывает решение. Если это изображение самостоятельное, его вполне можно выделить в блок. Проблема, с которой сталкиваются новички, обычно в том, что «Но тут же нет вёрстки!». Ну и ладно ¯\_(ツ)_/¯. БЭМ про абстрактные блоки, которые «реализуются» в различных технологиях. Условно говоря, PNG, JPEG, WEBP и пр. — это всё эти самые технологии, в которых может быть реализован блок.

Дальше только возникнет вопрос, как именно это удобнее всего подключать в какую-то иную вёрстку. В идеале у такого блока должно быть представление в виде класса. То есть, это может быть, например, что-то такое:

<img src="./block.png" class="block">

Тогда это успешно ложится на абстракцию БЭМ-дерева. Плюс это можно расширять. Например так:

<img src="./_type/_mobile/block_type_mobile.png" class="block block_type_mobile">

Т. о. мы выделили отдельное изображение для этого «блока с изображением», которое будем показывать, например, только на мобильных. Дальше ему можно добавить микс и использовать в какой-либо композиции:

<div class="parent-block">
  <img src="./_type/_mobile/block_type_mobile.png" class="block block_type_mobile parent-block__image">
</div>

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

В первом случае нужно будет оставить классы как есть, потому что БЭМ в вёрстке — он о классах. И блока не существует в БЭМ-дереве, если у него нет класса.

Во втором случае можно убрать классы, поскольку то, что это за изображение, и так понятно по пути его подключения, за счёт того, что у нас БЭМ на файловой системе. Делать так или нет, зависит только от того, насколько вы уверенно чувствуете себя в коде и методологии, и от соглашений, принятых в команде.

Внезапное дублирование

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

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

Если же нет, то можно просто положить две одинаковые картинки в разные блоки, и ничего страшного в этом нет ¯\_(ツ)_/¯.

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

Вопрос третий, про модификаторы

И., из почти славного города Ж., интересуется:

А что делать, если я создаю модификатор только с одним значением? Например,
у меня есть кнопка, у неё есть какой-то размер, но тут вдруг мне нужна кнопка побольше. И я создаю button_size_x.

Получается, что у меня есть какое-то значение по умолчанию, но есть и модификатор. Однако, у него только одно значение. Глупость же какая-то, не?

Дорогой И.!

На самом деле и правда получается глупость. Неопытный верстальщик в этом случае вообще создаёт булев модификатор, вроде button_big и успокаивается. Но это ещё бóльшая ошибка.

Во-первых, почему не булев? Потому что «размер» — это такой параметр, который может иметь разное значение. И если мы изначально делаем его булевым модификатором, мы закрываем себе возможности для расширения (тут можно было бы отослать читателя на статью про принцип открытости-закрытости, но я пока не буду). И когда завтра понадобится сделать кнопку маленького размера, придётся переписывать тот код, что уже написан. Или же придётся вводить button_small. Объяснение того, почему это неправильно, пусть будет домашним заданием для читателя.

Во-вторых, а что же делать? А решение на самом деле простое. Для того, чтобы понимать, как поступать в таких случаях, удобно представлять блок как функцию, а модификаторы — как параметры. В нашем случае получается какая-то вот такая функция:

function drawButton(size) {
  if (size) {
    // рисует кнопку указанного размера
  } else {
    // рисует кнопку какого-то иного размера
  }
}

Для упрощения понимания можно представлять, что size тут — это числовое значение. Если у читателя есть какой-то опыт программирования, он может сразу понять, что плохого в такой функции. А плохо то, что неизвестно, какого размера кнопка будет по умолчанию. Вместо явной параметризации мы получаем «параметризацию + какое-то иное поведение».

Чтобы избавиться от этого иного поведения программисты чаще всего делают просто:

function drawButton(size = 10) {
  // рисует кнопку указанного размера
}

И в таком случае по нотации функции уже понятно, что она сделает, если размер не передан — будет использовано значение 10.

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

В данном случае значением по умолчанию для модификатора size может быть, например, m. Но это уже сильно зависит от контекста.

Вопрос четвёртый, про скрипты

В редакцию пишет Л. из города-героя М.:

Вот элемент в форме, в шаблоне:

<div onclick="handleClick"></div>

В доисторические времена функция handleClick лежала рядом в этом же файле:

<script>
  function handleClick() { }
</script>

И подключалась прозрачно.

Когда на Луне обнаружился черный обелиск и в нем БЭМ, наступили наши времена, и я вынес скрипты в отдельный файл.

Файл подключается, и почти все гуд, кроме одного неудобства: он, похоже, подключается уже после всей вёрстки (или наоборот, до).

В момент, когда вёрстка парсится браузером, никакой функции handleClick он еще (или уже?) не знает. Я нашел корявый выход — у всех связанных со скриптами элементов делаю айдишники и функцию инициализации вешаю на onload событие.

Все работает, но необходимость вместо простого указания у блока в коде онклика устраивать пляски с инитами на домлоаде — какой-то адок. Нечитаемо, ошибкоемко, и громоздко, и нелаконично, и пространно, и вычурно, и многословно, и тумач букв.

Есть ли какой-то выход?

Дорогой Л.!

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

Если бы мы говорили о каких-то фреймворках, в которых компонентный подход навязывается насильно (Ангуляр, Реакт и пр.), то там бы такой проблемы не возникло, потому что там компонент — это штука, которая обмазана скриптами донельзя, и потому скрипты не нужно привязывать к вёрстке. Скорее даже наоборот.

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

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

На практике же используется, обычно, несколько иной подход. А именно:

  1. Скрипты подключаются в самом конце тега body.
  2. Скрипты пишутся с оглядкой на то, что инстансов блока может быть больше одного.

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

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

В общем случае получается что-то такое. Вёрстка:

<!-- ... -->
<body>
  <!-- ... -->
  <div class="block">
    <!-- ... -->
  </div>
  <!-- ... -->

  <script src="app.js"></script>
</body>
<!-- ... -->

JS-файл, при этом, скорее всего будет собираться как-то из других JS-файлов (из-за того, что у нас БЭМ на файловой системе), но предположим, что блок всего один. Тогда примерно вот таким будет JS-файл:

Array.from(document.querySelectorAll('.block')).forEach(initBlock);

function initBlock(node) {
  // какие-то действия над блоком 
}

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

document.addEventListener('DOMContentLoaded', () => Array.from(document.querySelectorAll('.block')).forEach(initBlock));

function initBlock(node) {
  // какие-то действия над блоком 
}

Или, если есть уверенность, что это очень нужно (не стоит так делать без чёткого понимания разницы), то он может быть и таким:

window.addEventListener('load', () => Array.from(document.querySelectorAll('.block')).forEach(initBlock));

function initBlock(node) {
  // какие-то действия над блоком 
}

Если скриптов на проекте много, то всё это можно спрятать в какую-то функцию, которая будет использоваться во всех файлах для инициализации блока. Типа такого:

// определённая где-то глобально функция
function initBlock(selector, fn) {
  Array.from(document.querySelectorAll(selector)).forEach(fn);
}

// локальное применение для конкретного блока
initBlock('.block', node => {
  // какие-то действия над блоком
});

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

∗∗∗

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

  • Описание методологии от Яндекса.
    Кажется, с каждой итерацией обновления этой документации, ребята из Яндекса всё дальше уходят от описания полного БЭМ-стека к более абстрактному описанию методологии. Это не может не радовать.
  • Принципы SOLID.
    Забавно, но в БЭМ, кажется, больше от программирования, чем от вёрстки. К слову, некоторые из этих принципов и их применение к БЭМ описаны в официальной документации.
  • Базовые понятия и принципы БЭМ.
    Мой коллега когда-то написал вот такую довольно академичную выдержку из своего доклада. Читать нужно аккуратно и вдумчиво, как будто это учебник по математике.
Блок кода, который тут только для того, чтобы Эгея подключила highlight.js, потому что иначе она не хочет этого делать. (╯°□°)╯︵ ┻━┻)
2018   бэм   вёрстка   вопросы в редакцию   разработка

Ежедневные инструменты. Браузер

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

Читатель, наверное, знает, что я пользуюсь браузером от Яндекса. Я давно уже писал о причинах, потому отдельно на этом останавливаться не будем, а перейдём сразу к расширениям.

Встроенные

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

Переводчик

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

Не скажу, что он переводит идеально, но когда при чтении статьи тебе не понятна какая-то фраза или пара слов — очень удобно перевести их прямо на месте.

Поиск в контекстном меню

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

Поиск по странице

Если предыдущие фичи я ещё представляю как отдельные расширения, то есть ли эта в качестве какого-то плагина, например, к Хрому, не знаю. Насколько я понял, Яндекс Браузер пока единственный, кто так умеет (причём, довольно давно).

Собственно, о чём я? О нечётком поиске по странице. Причём, как на английском:

Так и на русском (обратите внимание на окончания):

Это безумно удобно и не понятно, почему вообще может быть как-то иначе.

Кажется, это все наиболее важные функции Я.Браузера, которыми я пользуюсь повседневно, но аналогов которых нет в других браузерах. Помимо них ещё есть различные привязанные к сервисам Яндекса (типа Adviser, который показывает меньшие цены на аналогичные товары в других магазинах), но я ими почти не пользуюсь, так что пропустим.

Постоянные

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

Pocket

Всё, что я читаю или смотрю в интернете, я стараюсь пропускать через Покет, потому что иначе это съедает много времени (работаешь-работаешь, а потом увидел интересную статью и залип). Расширение в этом помогает: кликнул, страница улетела в список «на потом» и ты спокойно работаешь дальше, зная, что точно о ней не забудешь.

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

Яндекс.Музыка и Радио

Это крутое расширение, с помощью которого можно управлять Я.Музыкой, Я.Радио, Ютубом, музыкой из ВК и многими другими источниками. Удобно то, что сочетания клавиш устанавливаются глобальные, потому можно включить какой-то плейлист в ВК, перейти в любимую IDE, работать и в процессе переключать треки, не отвлекаясь от кода. Плюс оно умеет ставить на паузу текущий источник, если вы запустили новый (например, играла Я.Музыка, а вы вдруг открыли видео на Ютубе).

1Password

Очень удобное приложение и расширение к нему, которое хранит ваши персональные данные и умеет заполнять по требованию формы с логинами и паролями, личными данными, реквизитами карт, паспортными данными и пр. Помимо этого приучает к тому, чтобы пользоваться разными и сложными паролями на сайтах, потому что вам не нужно их самостоятельно запоминать. Пусть страдает машина. Для мобильных девайсов есть свои приложения, а на тот случай, когда вам нужно авторизоваться где-то на чужом компьютере, есть HTML-страничка, которую можно легко скинуть на флешку и пользоваться. Когда-нибудь я ещё расскажу о 1Password отдельно, а пока просто попробуйте, если ещё не.

Follow RSS

С помощью этого расширения (по ссылке их там два, не перепутайте) я добавляю РСС-ленты различных блогов, паблики ВКонтакте, аккаунты в Твиттере, каналы на Ютубе и пр. в свой аккаунт в Feedly, чтобы потом читать их в общей ленте в приложении Reeder. Если вы не пользуетесь ничем таким, то скорее всего вам и не интересно это расширение. Хотя я бы посоветовал подобную связку, потому что не нужно бегать в различные социальные сеточки, блоги и т. д., а можно получать контент по мере его выхода и читать в удобном интерфейсе (и в офлайне, конечно же, тоже). О таком же наборе инструментов когда-то писал Илья Бирман.

Octotree

Дополнение для Гитхаба. Позволяет всегда видеть дерево директорий репозитория и перемещаться по файлам намного быстрее, чем без него. Хотя это, конечно, не отменяет того факта, что у Гитхаба клёвый набор горячих клавиш, из-за которых им можно пользоваться почти без мышки.

uBlock Origin

Насколько мне известно, самый быстрый и клёвый блокировщик рекламы на данный момент. В отличие от всяких AdBlock и прочих ребят, он не продавался Гуглу, не делал белые списки для рекламы и всё прочее (но врать не буду, могу чего-то не знать). Уточню лишь, что есть две версии: uBlock и uBlock Origin. Когда-то они разделились, но в итоге uBlock Origin сейчас развивается, а uBlock загнулся.

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

Ghostery

Крутейший блокировщик всего подряд: от кнопок «Поделиться» до следящих за вами рекламных скриптов. К примеру, прямо сейчас, когда я пишу эту заметку, он блокирует Яндекс.Метрику, с помощью которой я за вами слежу. Ибо нефиг :-)

А поставил я его ещё давно из-за того, что всякие недобрые ребята промышляют кликджекингом, о чём я когда-то писал.

The Great Suspender

У меня есть не очень хорошая привычка. Я открываю вкладки «чтобы было», и потом не закрываю их, потому что они могут висеть как напоминание о чём-либо. День-два-неделю-месяц — вообще легко. Ноут перезагружается раз в месяц, браузер восстанавливает вкладки, так что, они могут висеть постоянно. Однако, это нагружает систему и отжирает память у всего остального. Потому для таких ребят как я придумали расширение, которое оставляет вкладку открытой, но выгружает из памяти всё её содержимое. То есть, вкладка вместо открытого сайта превращается просто в ссылку на этот сайт.

Video Speed Controller

Как и многие в этом диком XXI веке, я редко смотрю видео в интернете на оригинальной скорости. Чаще всего ускоренное в полтора-два раза, а иногда и ещё быстрее. Это экономит время и нисколько не убавляет смысла увиденного.

HTTPS Everywhere

Как понятно из названия, это расширение по умолчанию перенаправляет на HTTPS-версии сайтов (в том числе при загрузке ассетов и пр.), если вдруг почему-то этого не сделали авторы этих сайтов. Немного успокаивает параноика во мне.

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

Непостоянные

friGate

Это очень простое расширение для проксирования запросов к сайтам. Я пользуюсь встроенной в браузер версией, потому не скажу, какая это именно из тех, что представлены на сайте, но думаю, что они все работают примерно одним и тем же образом. В настройках создаётся список сайтов (там есть предустановленный на 200+ доменов), запросы к которым нужно проксировать. У меня мои списки разбиты по странам, чтобы было удобно переключать при пересечении границы. Работает быстро, потому в Испании, например, я без проблем пользовался Яндекс.Музыкой. Однако, есть ненулевая вероятность, что он сливает обо мне все данные куда-либо, потому я его включаю только при необходимости, и из другого браузера.

SaveFrom.net

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

Tampermonkey

Наверное, всем известное расширение для пользовательских скриптов. Помогает подхачить какой-нибудь сайт, если вдруг на нём что-то не так. Например, когда-то в InVision всё было хуже, чем сейчас, потому мы в Фанбоксе написали для себя немного скриптов для работы с ним.

RESTMan

Простенькое расширение для создания тестовых запросов. Пользуюсь им редко, потому может быть есть что-то и покруче, но меня устраивает то, что тут есть :-)

ModHeader

Полезное и простое расширение, когда нужно добавить или подменить какие-то заголовки к запросу.

React Developer Tools

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

AngularJS Batarang

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

Angular Watchers

Проще и быть не может — просто счётчик активных вотчеров для текущего состояния приложения на Ангуляре. Особенно удобен в виде графика. Ангуляром в наше время, кажется, хипстеры уже не пользуются, но когда нужно ускорить какой-то «древний» проект, прям очень помогает. Когда-нибудь я напишу «для истории» о том, куда нужно смотреть и что нужно править, чтобы заставить Ангуляр работать побыстрее. А то ведь ещё никто не написал!

Page Ruler

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

Looper for YouTube

На тот случай, когда включаю какой-нибудь музыкальный сет на Ютубе (например, этот). Удобно поставить его на повтор и не париться.

Go Fucking Work

Когда-то блокировал им различные социальные сети и прочее, что отвлекает от работы. Обычно обещает засунуть мне что-нибудь в задницу, если я не вернусь к работе. Вдруг вам такое нравится ¯\_(ツ)_/¯.

LetyShops

Это, думаю, совсем не нуждается в представлении. Кэшбэк-сервис для покупок во всяких там Алиэкспрессах. Удивительно, сколько денег может набежать от заказов всяких мелочей из Китая.

∗∗∗

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

А в прошлый раз я рассказывал о том, как устроен мой терминал.

Индикаторы загрузки

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

Например, это Гугл-карты:

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

Не забывайте про индикаторы загрузки.

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

Справедливости ради, если вручную снизить скорость соединения до каких-нибудь 50 кб/с, то можно увидеть через какое-то время индикатор загрузки и у Гугла; но только через какое-то время, а не сразу. Увы, такое решение не всегда работает.

2017   гугл   разрабатываем как могём   разработка

Годнота — 5

Видео

Статьи

2017   арзамас   видео   годнота   история   разработка

Годнота — 3

Видео

  • Он вам не Димон. Шикарное расследование ФБК. Даже если политота — это не про вас, интересно посмотреть как распутывается клубок из-за каких-то кроссовок.
  • Суперсилы Chrome Dev Tools, Роман Сальников. Клёвый доклад про то, как пользоваться инструментами разработчика в Хроме. Интерфейсы на скриншотах уже устарели, но суть не изменилось. Полезно знать, что умеет ваш браузер, и чем он может помочь.

Статьи

Курсы

  • Browser Rendering Optimization. Хороший курс от ребят из Гугла об устройстве браузера, процессе рендеринга и всём таком. Скорее всего будет полезно, даже если вы считаете, что знаете что такое DOM, CSSOM, Render Tree и всё такое. Плюс там в процессе советуют тонну статей на эту тематику.
  • Use JavaScript (ES6) generators to pause function execution. Неплохой 15-минутный ввод в генераторы в Джаваскрипте. Не лучше, чем у Кантора, но зато быстро и наглядно.
Ctrl + ↓ Ранее