Chulakov Dev – Telegram
Chulakov Dev
1.15K subscribers
140 photos
5 videos
205 links
Канал команды разработки Студии Олега Чулакова.

Советы по Frontend- и Backend-разработке web-сервисов, мобильных приложений, статьи и презентации от наших разработчиков, анонсы проектов и многое другое.

Обсудить проект @YuraAndreev
Download Telegram
Следите за выражениями

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

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

Работа с кириллицей может стать корнем проблем. Вот такое регулярное выражение отказалось работать с русскими буквами на промышленном сервере заказчика:
$string = preg_replace('/[^\d\w\s\.\:-]+/u', '', $string);


Изучив проблему, мы поняли, что в старых версиях PHP-модуля pcre стандартный перечень \w не охватывает кириллические символы даже с модификатором u. Именно этот модуль реализует работу Perl-совместимых регулярных выражений в PHP.

Для того чтобы ваши регулярные выражения корректно работали с русскими символами, необходимо, чтобы версия pcre была не ниже 8.38. Проверить это можно, выполнив консольную команду
$ php -i | grep PCRE
Разметка? Нет, не слышали

Телеграм дает много возможностей для создания ботов. Часто их используют для публикации новостей в каналах. Публиковать свои сообщения очень просто: метод sendMessage принимает текст в трех форматах — text, markdown и html. А вот парсинг и отображение сообщения (например, на сайте) имеют одну большую проблему — получаемый из Телеграма текст не содержит разметки. В нем никак не обозначены ссылки, курсив и т.д.

Однако вместе с ним передается список объектов MessageEntity, в которых хранится тип, позиция и длины размеченных частей текста. Мы не нашли библиотек, которые могли бы формировать на основе этих данных, например, markdown-код. При этом любое внесение изменений в исходный текст приводит к несовпадению индексов у последующих MessageEntity. Если начать вставлять теги разметки, то текст начнет смещаться с позиций, указанных в MessageEntity, и будет размечаться не тот контент.

Как мы решили проблему?

Шаг 1: Собрать необходимые данные
Мы собрали все части в один список. В него попали входные и закрывающие индексы.
https://bitbucket.org/snippets/OlegChulakovStudio/Beok58

Шаг 2: Разрезать на части!
По существующим индексам мы порезали сообщение на части, начиная с конца. В результате получили маркированный список отрезков исходного текста.
https://bitbucket.org/snippets/OlegChulakovStudio/pey7p6

Шаг 3: Разметить
Имея маркеры и кусочки текста, можно легко преобразовать их с учетом любой верстки и смещений.
https://bitbucket.org/snippets/OlegChulakovStudio/9ekL9j

Шаг 4: Склеить
Теперь текст можно собрать обратно, уже с внесенными изменениями.
$text = implode('', $parts);
Движение вбок

Один из наших подписчиков решил наглядно показать принципы работы современных библиотек для DOM-анимаций. Для этого он написал простую библиотеку и попросил нас ею поделиться:
codepen.io/OlegChulakovStudio/pen/JpYWXX

Так, с ее помощью можно переместить блок по диагонали:
animation($block, .3, 
{
transform: "translate3d({0}px, {0}px, 0px)"
},
{
transform: "translate3d({50}px, {50}px, 0px)"
}
);


Несмотря на небольшой размер, здесь предусмотрена даже поддержка vw, % и т.д. Если вам интересна тема анимаций, рекомендуем поизучать код.

Напоминаем, что интересные идеи или вопросы вы можете присылать нам на ask@deep.digital.
Вы знаете, с какой скоростью вы ехали?

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

Сперва, разумеется, вам потребуется сделать несколько версий медиафайла разного веса/качества. Затем нужно определить скорость скачивания и на ее основе отобразить подходящий вариант.

Готовится спецификация Network Information API, которая позволит определить параметры сети, но сейчас ее еще рано использовать в production-среде.

В суровом мире кроссбраузерности порой приходится прибегать к менее изысканным решениям. Для этой задачи наиболее популярным является замер времени скачивания заранее известного объема данных (например, изображения):
https://bitbucket.org/snippets/OlegChulakovStudio/6ey8MR

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

Нам на ask@deep.digital пришел вопрос: «Как сервисы почтовой рассылки вроде MailChimp собирают статистику о прочтении писем?» Рассказываем.

Перед отправкой в HTML-код письма автоматически добавляется тэг img. Он ссылается на маленькое прозрачное GIF- или PNG-изображение. Перед отправкой backend генерирует уникальный URL этого изображения для каждого адресата. Когда пользователь откроет письмо в своем почтовом клиенте, изображение начнет скачиваться с сервера, этот запрос будет зафиксирован и факт открытия письма адресатом запишется в базу данных.

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

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

При разработке сайтов важно не забывать о том, что у посетителей могут быть заблокированы API встраиваемых сервисов. Например, виджетов VK или Facebook, скриптов Google Analytics. Если не учесть эти блокировки, то от части пользователей будут поступать сообщения о том, что в работе сайта есть ошибки.

Чаще всего причиной являются установленные в браузере AdBlock-плагины, но также проблемы бывают связаны с ограничениями доступа (например, у пользователей из Украины сейчас полностью заблокирован VK).

Что делать?

Тестировщику нужно настроить как минимум один браузер на абсолютно беспощадный режим блокировки: установить AdBlock, Ghostery и другие подобные плагины. Включить в них все преднастроенные ограничения, полностью заблокировать обращения к доменам социальных сетей и популярных сервисов.

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

Например, если вы разместили на сайте кнопку Like, а Facebook JS SDK у пользователя не скачался, то он не должен об этом узнать: верстка не должна поехать, а функционал сайта — сломаться.
Социальное чтиво

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

Эти данные VK и Facebook получают, посылая запрос на страницу и анализируя ее HTML-код. Если разработчик хочет добиться предсказуемого поведения и контролировать содержимое виджетов, то ему необходимо использовать специальные метатеги.

Например, для указания изображения используется метатег <meta property="og:image" content="URL" />. Если его не разместить, то картинки в виджете либо не будет вообще, либо краулер соцсети сам возьмет первую подходящую из кода страницы. А это может быть что угодно, даже какой-нибудь рекламный баннер, не имеющий отношения к содержимому, которым делился пользователь.

В метатеге og:image нужно указывать абсолютный URL изображения с протоколом и доменом. Чтобы картинка загрузилась, при самом первом шейре страницы нужно добавить метатеги og:image:width и og:image:height с соответствующими размерами изображения.
Все по-старому

В прошлой заметке мы говорили про публикацию ссылок в соцсетях и про то, что VK и Facebook получают метаданные страницы, посылая на нее запрос и анализируя HTML-код.

Социальные сети кэшируют метаданные, поэтому при последующих шейрах никаких запросов на сайт выполняться не будет — будет использоваться скачанная ранее информация.

Если вы обновили og:image или другие поля, то, для того чтобы пользователи начали ими делиться, нужно сбросить кэш для страницы. Для этого можно использовать специальные инструменты или методы API:
https://developers.facebook.com/tools/debug
https://vk.com/dev/pages.clearCache
Это была ошибка!

Если вы собираетесь использовать React 16, советуем обратить внимание на новую политику обработки ошибок рендера.

В 15ой версии ошибка мешала перерендериваться компоненту и всему поддереву, но оставляло его последнее состояние:
https://codepen.io/OlegChulakovStudio/pen/BYYjya

В 16ом релизе команда разработчиков приняла решение не оставлять компонент в дереве рендеринга и, более того, исключать все вышестоящие компоненты из него, пока не будет встречен компонент с новым методом жизненного цикла componentDidCatch (в 15ой версии он назывался handle_unstableError).

Таким образом, отсутствие компонентов-обработчиков теперь может привести к полному размонтированию дерева компонетов:
https://codepen.io/OlegChulakovStudio/pen/yvveyg

Мы подготовили демонстрацию применения такого компонента-обработчика (ErrorBoundary), который умеет подменять сломанный компонент другим, подготовленным заранее.
Опять то же самое?

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

Например, если вы делаете какой-нибудь посещаемый блог, главная страница которого содержит список из 50 публикаций с числом просмотров и комментариев каждой, то запросы к БД могут сильно нагрузить сервер, а рост числа посетителей может привести к увеличению времени загрузки сайта.

Один из самых простых в настройке способов серверного кэширования — nginx proxy cache:
https://bitbucket.org/snippets/OlegChulakovStudio/ae8gbz

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

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

Настроить load balancer, который будет равномерно распределять запросы, очень просто:
https://bitbucket.org/snippets/OlegChulakovStudio/7eg8eG
Порталы в React

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

Ранее подобную проблему решали с помощью компонента-обертки, где сам рендер необходимого компонента осуществлялся не в методе render, а в componentDidUpdate с помощью функции ReactDOM.unstable_renderComponentIntoSubtree().

В новой версии появился метод createPortal объекта ReactDOM, который позволяет отрендерить React-компонент в DOM-дереве, о котором React ничего не знает. Для этого ему надо передать первым аргументом сам компонент, а вторым — ссылку на нужный DOM-узел.

Мы подготовили интерактивный пример использования этого метода. В примере рассматривается случай с интерфейсом плеера Video.js, в панель которого мы добавили компонент Likes.
Полезные команды Git. Удаление из индекса

Если вы случайно закоммитили файл, который не должен был попасть в индекс репозитория (например, конфигурационный файл или лог), добавление его в .gitignore уже не поможет. Все будущие изменения этого файла будут фиксироваться Git-ом.

Чтобы убрать файл из индекса, не удаляя его из директории, можно использовать следующую команду:
git rm --cached path-to/file.txt
Полезные команды Git. Перенос коммита

Если вы сделали коммит не в той ветке, вы можете легко скопировать его в нужную, используя команду:
git cherry-pick <хэш коммита>

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

Если вы внесли изменения в файлы, а теперь хотите вернуть их в изначальное состояние, можно воспользоваться командой:
git reset --hard HEAD
Полезные команды Git. Откат коммита

Если вы сделали коммит, но забыли внести в него некоторые файлы, вы можете отменить коммит, сохранив все ваши изменения на диске:
git reset --soft HEAD~1

Чтобы удалить последний коммит вместе с изменениями в файлах, вы можете воспользоваться командой:
git reset --hard HEAD~1

Вы также можете откатить несколько последних коммитов. К примеру:
git reset --hard HEAD~3
Полезные команды Git. Revert

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

Если команда разработчиков большая, можно воспользоваться командой git revert. Это команда делает новый коммит, в котором отменяет все изменения из указанного:
git revert <хэш коммита>
Плотность пикселей в JavaScript

При разработке веб-приложения или сайта может быть необходимо учесть плотность пикселей на экране устройства пользователя. Например, для четкого отображения контента в теге canvas необходимо создавать холст, содержащий большее число точек, а затем с помощью CSS уменьшать визуальный размер этого холста обратно:
https://codepen.io/OlegChulakovStudio/pen/BrKWYE?editors=0110

Самый простой способ узнать плотность пикселей в современных браузерах — обратиться к свойству devicePixelRatio объекта window.
Retina + CSS

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

Для этого можно использовать следующий медиа-запрос:
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)

Пример использования:
https://bitbucket.org/snippets/OlegChulakovStudio/7egg9R

Если в рамках проекта требуется максимально высокая кроссбраузерность, можно воспользоваться расширенной версией медиа-запроса:
https://bitbucket.org/snippets/OlegChulakovStudio/zeaaBK
Retina + CSS-препроцессоры

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

Эти проблемы легко решить, используя возможности любого из современных CSS-препроцессоров:
https://bitbucket.org/snippets/OlegChulakovStudio/yeGxpp

Аналогично можно поступить и с любым другим более распространенным медиа-запросом, вроде (max-width: 1024px).
​​Кубическая кривая Безье и CSS

Специалисты, которые работают с анимацией, знают про easeOutCubic, easeInOutExpo, easeOutBack и другие основные функции плавности.

Те, кто копнул в принципы работы этих функцией знают, что они реализуют поведение, соответствующее различным кубическим кривым Безье.

Эта кривая строится на основе четырех точек:
P0 и P3 — начало и конец кривой;
P1 и P2 — указывают ее направление.

В CSS-реализации можно изменять только точки P1 и P2. Координаты P0 здесь всегда равны «0, 0», а P3 — «1, 1».

Кубические кривые Безье можно использовать в свойствах transition-timing-function и animation-timing-function, чтобы настроить зависимость между временем и прогрессом выполнения анимации:
transition-timing-function: cubic-bezier(x1, y1, x2, y2)