Элементы интерфейса на React
Этим выпуском мы начинаем цикл мини-уроков, посвященный созданию различных элементов интерфейса сайтов и веб-приложений (табы, аккордеоны, выпадающие списки, календари и т.д.).
Благодаря заметкам в рамках этого цикла, можно лучше разобраться в принципах создания интерфейсных компонентов, что позволит самостоятельно разрабатывать аналогичные элементы и избавит от необходимости каждый раз подключать в проект сторонние громоздкие библиотеки.
Начнем мы с такого распространенного элемента, как табы (переключение вкладок):
https://telegra.ph/EHlementy-interfejsa-na-React-Vypusk-1-Taby-10-24
Кстати, тем кто планирует заниматься разработкой интерфейсов для крупного бизнеса стоит заранее быть готовыми (и морально тоже) к ограничению на подключение зависимостей: при разработке систем для клиентов из финансовой и других подобных сфер, из соображений безопасности, в проект может быть запрещено подключать любые библиотеки и зависимости кроме проверенного минимума вроде React, Webpack и Babel.
Этим выпуском мы начинаем цикл мини-уроков, посвященный созданию различных элементов интерфейса сайтов и веб-приложений (табы, аккордеоны, выпадающие списки, календари и т.д.).
Благодаря заметкам в рамках этого цикла, можно лучше разобраться в принципах создания интерфейсных компонентов, что позволит самостоятельно разрабатывать аналогичные элементы и избавит от необходимости каждый раз подключать в проект сторонние громоздкие библиотеки.
Начнем мы с такого распространенного элемента, как табы (переключение вкладок):
https://telegra.ph/EHlementy-interfejsa-na-React-Vypusk-1-Taby-10-24
Кстати, тем кто планирует заниматься разработкой интерфейсов для крупного бизнеса стоит заранее быть готовыми (и морально тоже) к ограничению на подключение зависимостей: при разработке систем для клиентов из финансовой и других подобных сфер, из соображений безопасности, в проект может быть запрещено подключать любые библиотеки и зависимости кроме проверенного минимума вроде React, Webpack и Babel.
Canvas 2D
Для работы с 2D-графикой в
Например, если на одной из страниц сервиса нужно отобразить динамическую круговую диаграмму, то нецелесообразно ради одного блока подключать в проект тяжелый плагин для графиков или библиотеку для работы с двухмерной графикой.
Для решения подобных задач и для того, чтобы все наши разработчики имели представление о том, как «под капотом» работают все эти библиотеки, у нас есть лекция про
https://dev.chulakov.ru/chulakov.edu.canvas/
Для работы с 2D-графикой в
canvas, как правило, используют библиотеки (например, CreateJS или PixiJS). Но бывают задачи, которые лучше решать без использования сторонних решений, работая напрямую с функциями контекста.Например, если на одной из страниц сервиса нужно отобразить динамическую круговую диаграмму, то нецелесообразно ради одного блока подключать в проект тяжелый плагин для графиков или библиотеку для работы с двухмерной графикой.
Для решения подобных задач и для того, чтобы все наши разработчики имели представление о том, как «под капотом» работают все эти библиотеки, у нас есть лекция про
canvas, которую мы рассказываем начинающим Frontend-разработчикам. Чтение лекции сопровождается интерактивной презентацией, где основные возможности показаны «вживую» с примерами кода:https://dev.chulakov.ru/chulakov.edu.canvas/
Telegram как дистрибьютор контента
Простота работы, а также встроенные оповещения Telegram делают его интересным инструментом для распространения контента. К публикациям легко прикреплять различные изображения, видео и аудио, геометки, подключать самые различные расширения (голосования, лайки, опросы и тд). Однако далеко не все пользуются этим мессенджером, что значительно сужает потенциальную аудиторию. На публикацию в этом мессенджере нельзя дать общедоступную ссылку, и, следовательно, не получится добиться доступности, достаточной для ожидаемых показателей виральности.
Самым доступным форматом, не привязанным к приложениям и аккаунтам, разумеется, является веб. Поэтому вместе с Telegram-каналом желательно иметь раздел на сайте, содержащий этот контент, что позволит полноценно продвигать его и делиться публикациями во всех источниках.
Что же делать, если контент удобно публиковать в Telegram, используя при этом все его возможности, но не хочется самостоятельно копировать публикации в другие источники, например, на сайт или в соцсети?
Если вы разработчик (или у вас под рукой есть такой), то решение достаточно простое: можно сделать небольшое приложение, которое будет работать с Telegram API, получать публикации и выводить/отправлять их в нужные вам платформы.
Сперва нужно зарегистрировать своего служебного бота в Telegram с помощью @BotFather, добавить его в нужный канал или чат.
Затем создать простое веб-приложение, которое будет работать с Telegram API, используя для авторизации токен вашего бота, полученный от @BotFather.
Для любого языка есть много готовых SDK, которые значительно упрощают работу с API. Например, в PHP-стеке мы используем https://packagist.org/packages/longman/telegram-bot, а в NodeJS — https://www.npmjs.com/package/node-telegram-bot-api.
При использовании SDK работать с сообщениями из Telegram будет очень легко. Вот примеры: https://bitbucket.org/snippets/OlegChulakovStudio/84a7Xz
Получив сообщение и информацию о нем, можно переслать его, например, в социальные сети, используя их API и/или сохранить в базу данных вашего сайта для последующего отображения их в доступном всем веб-формате.
Так, например, мы сделали раздел на сайте Студии с заметками нашего арт-директора (https://chulakov.ru/notes). Ссылкой на публикацию теперь легко поделиться, в том числе используя кнопки популярных социальных сетей.
Простота работы, а также встроенные оповещения Telegram делают его интересным инструментом для распространения контента. К публикациям легко прикреплять различные изображения, видео и аудио, геометки, подключать самые различные расширения (голосования, лайки, опросы и тд). Однако далеко не все пользуются этим мессенджером, что значительно сужает потенциальную аудиторию. На публикацию в этом мессенджере нельзя дать общедоступную ссылку, и, следовательно, не получится добиться доступности, достаточной для ожидаемых показателей виральности.
Самым доступным форматом, не привязанным к приложениям и аккаунтам, разумеется, является веб. Поэтому вместе с Telegram-каналом желательно иметь раздел на сайте, содержащий этот контент, что позволит полноценно продвигать его и делиться публикациями во всех источниках.
Что же делать, если контент удобно публиковать в Telegram, используя при этом все его возможности, но не хочется самостоятельно копировать публикации в другие источники, например, на сайт или в соцсети?
Если вы разработчик (или у вас под рукой есть такой), то решение достаточно простое: можно сделать небольшое приложение, которое будет работать с Telegram API, получать публикации и выводить/отправлять их в нужные вам платформы.
Сперва нужно зарегистрировать своего служебного бота в Telegram с помощью @BotFather, добавить его в нужный канал или чат.
Затем создать простое веб-приложение, которое будет работать с Telegram API, используя для авторизации токен вашего бота, полученный от @BotFather.
Для любого языка есть много готовых SDK, которые значительно упрощают работу с API. Например, в PHP-стеке мы используем https://packagist.org/packages/longman/telegram-bot, а в NodeJS — https://www.npmjs.com/package/node-telegram-bot-api.
При использовании SDK работать с сообщениями из Telegram будет очень легко. Вот примеры: https://bitbucket.org/snippets/OlegChulakovStudio/84a7Xz
Получив сообщение и информацию о нем, можно переслать его, например, в социальные сети, используя их API и/или сохранить в базу данных вашего сайта для последующего отображения их в доступном всем веб-формате.
Так, например, мы сделали раздел на сайте Студии с заметками нашего арт-директора (https://chulakov.ru/notes). Ссылкой на публикацию теперь легко поделиться, в том числе используя кнопки популярных социальных сетей.
Микровзаимодействия 👆
Для многих веб-студий и digital-агентств результатом работы по созданию дизайна являются статичные макеты страниц или экранов.
Разработчики из нашей команды, тесно сотрудничая с дизайнерами интерфейсов Студии, прорабатывают детали, которые невозможно показать на статичных изображениях, продолжая, таким образом, работу над дизайном и на этапе его разработки.
Например, много внимания уделяется микровзаимодействиям, которые значительно повышают отзывчивость интерфейса, позволяют пользователю лучше в нем ориентироваться и эффективно работать с системой.
В качестве базовых микровзаимодействий можно назвать реакции на тапы пользователя: «вдавливание» и «затухание» элементов под «весом» курсора, волны от позиции нажатия и тд.
Много таких реакций мы проработали, например, в рамках концепции сайта для Райффайзенбанк: https://raiffeisen.chulakov.ru/home.php
Летом мы поставили себе цель максимально упростить и ускорить процесс интеграции базовых микровзаимодействий в новые продукты на React. Для этого мы разработали универсальный конфигурируемый компонент
Компонент прошел полевые испытания, и мы с радостью готовы поделиться первой публичной версией со всеми разработчиками. С помощью этого компонента добавлять базовые микровзаимодействия к любым интерактивным элементам веб-приложений и сайтов становится очень легко.
Сами посмотрите:
https://react-interactions.chulakov.ru
Инструкция по установке и подключению доступна в репозитории на GitHub:
https://github.com/OlegChulakovStudio/react-interactions
Для многих веб-студий и digital-агентств результатом работы по созданию дизайна являются статичные макеты страниц или экранов.
Разработчики из нашей команды, тесно сотрудничая с дизайнерами интерфейсов Студии, прорабатывают детали, которые невозможно показать на статичных изображениях, продолжая, таким образом, работу над дизайном и на этапе его разработки.
Например, много внимания уделяется микровзаимодействиям, которые значительно повышают отзывчивость интерфейса, позволяют пользователю лучше в нем ориентироваться и эффективно работать с системой.
В качестве базовых микровзаимодействий можно назвать реакции на тапы пользователя: «вдавливание» и «затухание» элементов под «весом» курсора, волны от позиции нажатия и тд.
Много таких реакций мы проработали, например, в рамках концепции сайта для Райффайзенбанк: https://raiffeisen.chulakov.ru/home.php
Летом мы поставили себе цель максимально упростить и ускорить процесс интеграции базовых микровзаимодействий в новые продукты на React. Для этого мы разработали универсальный конфигурируемый компонент
<Tap />, работу которого вы можете посмотреть на бете новой мобильной версии сайта онлайн-гипермаркета «Утконос», нажав на любую ссылку или кнопку: https://www.utkonos.ru (смотреть с телефона).Компонент прошел полевые испытания, и мы с радостью готовы поделиться первой публичной версией со всеми разработчиками. С помощью этого компонента добавлять базовые микровзаимодействия к любым интерактивным элементам веб-приложений и сайтов становится очень легко.
Сами посмотрите:
https://react-interactions.chulakov.ru
Инструкция по установке и подключению доступна в репозитории на GitHub:
https://github.com/OlegChulakovStudio/react-interactions
В ногу со временем
При проектировании систем, рассчитанных на использование из разных точек земного шара, архитектор приложения должен решить проблему хранения, процессинга, а также вывода даты и времени. Каждый пользователь должен видеть актуальные данные для своего часового пояса.
В разрабатываемом нами мобильном приложении для коммуникации врачей и пациентов есть много возможных взаимодействий между пользователями в разных часовых поясах. Например, есть аналитический раздел с различными графиками, который содержит как показатели пациента (артериальное давление, пульс, температура), так и указания доктора (периодичность, сроки приема лекарств). Более того, у доктора есть возможность смотреть показатели в часовом поясе своего пациента, чтобы анализировать его режим.
При работе с подобными задачами обрабатывать и пересчитывать время на стороне мобильного приложения не оптимально: приходится дублировать алгоритмы как для приложений на каждой ОС (iOS, Android), так и на стороне сервера. Кроме того, несоответствие во времени может возникнуть при разнице в версиях приложений, что, разумеется, недопустимо, когда речь идет о здоровье.
Для решения всех этих проблем мы выбрали принцип «тонкого» клиента: централизовали всю логику конвертации времени внутри backend-части системы и полностью исключили ее из мобильных приложений.
Таким образом, приложения запрашивают и отправляют данные по REST API, передавая при этом параметр с текущим часовым поясом пользователя, и получают в ответ готовые данные, соответствующие их расположению.
Вся информация о времени и датах хранится в базе данных как метки Unix Timestamp в формате UTC, который имеет нулевое часовое смещение, и с легкостью пересчитывается в дату и время любого часового пояса.
При проектировании систем, рассчитанных на использование из разных точек земного шара, архитектор приложения должен решить проблему хранения, процессинга, а также вывода даты и времени. Каждый пользователь должен видеть актуальные данные для своего часового пояса.
В разрабатываемом нами мобильном приложении для коммуникации врачей и пациентов есть много возможных взаимодействий между пользователями в разных часовых поясах. Например, есть аналитический раздел с различными графиками, который содержит как показатели пациента (артериальное давление, пульс, температура), так и указания доктора (периодичность, сроки приема лекарств). Более того, у доктора есть возможность смотреть показатели в часовом поясе своего пациента, чтобы анализировать его режим.
При работе с подобными задачами обрабатывать и пересчитывать время на стороне мобильного приложения не оптимально: приходится дублировать алгоритмы как для приложений на каждой ОС (iOS, Android), так и на стороне сервера. Кроме того, несоответствие во времени может возникнуть при разнице в версиях приложений, что, разумеется, недопустимо, когда речь идет о здоровье.
Для решения всех этих проблем мы выбрали принцип «тонкого» клиента: централизовали всю логику конвертации времени внутри backend-части системы и полностью исключили ее из мобильных приложений.
Таким образом, приложения запрашивают и отправляют данные по REST API, передавая при этом параметр с текущим часовым поясом пользователя, и получают в ответ готовые данные, соответствующие их расположению.
Вся информация о времени и датах хранится в базе данных как метки Unix Timestamp в формате UTC, который имеет нулевое часовое смещение, и с легкостью пересчитывается в дату и время любого часового пояса.
Синхронизация времени с сервером
В продолжение темы прошлой заметки давайте рассмотрим частую для веб-приложений проблему несоответствия времени на компьютере пользователя и на сервере.
Например, в нашей партнерской программе (https://partners.chulakov.ru) компании должны прислать клиенту свое коммерческое предложение в течение 24 часов с момента начала участия в тендере. Когда партнер открывает свой кабинет, из REST API приходит информация о тендере и время, при наступлении которого backend перестанет принимать предложения. Оставшееся число часов, минут и секунд отображается в таймере обратного отсчета.
Если с помощью JavaScript просто отсчитывать время до наступления момента, полученного из API, то мы получим рассинхронизацию работы frontend- и backend-логики, соответствующую тому, насколько часы в ОС пользователя спешат или отстают относительно часов сервера. Форма либо слишком рано заблокируется, либо будет доступна в то время, когда прием предложений уже закрыт в backend-части.
Самое простое решение подобных проблем — один раз запросить текущее время сервера, вычислить разницу между ним и временем пользователя, а затем использовать полученное значение для смещения всех таймеров в JavaScript.
Для удобства работы всю логику можно оформить в специальный модуль:
https://bitbucket.org/snippets/OlegChulakovStudio/9ejdXk
Или так, если предпочитаете работать с форматированным временем:
https://bitbucket.org/snippets/OlegChulakovStudio/rejKe5
В продолжение темы прошлой заметки давайте рассмотрим частую для веб-приложений проблему несоответствия времени на компьютере пользователя и на сервере.
Например, в нашей партнерской программе (https://partners.chulakov.ru) компании должны прислать клиенту свое коммерческое предложение в течение 24 часов с момента начала участия в тендере. Когда партнер открывает свой кабинет, из REST API приходит информация о тендере и время, при наступлении которого backend перестанет принимать предложения. Оставшееся число часов, минут и секунд отображается в таймере обратного отсчета.
Если с помощью JavaScript просто отсчитывать время до наступления момента, полученного из API, то мы получим рассинхронизацию работы frontend- и backend-логики, соответствующую тому, насколько часы в ОС пользователя спешат или отстают относительно часов сервера. Форма либо слишком рано заблокируется, либо будет доступна в то время, когда прием предложений уже закрыт в backend-части.
Самое простое решение подобных проблем — один раз запросить текущее время сервера, вычислить разницу между ним и временем пользователя, а затем использовать полученное значение для смещения всех таймеров в JavaScript.
Для удобства работы всю логику можно оформить в специальный модуль:
https://bitbucket.org/snippets/OlegChulakovStudio/9ejdXk
Или так, если предпочитаете работать с форматированным временем:
https://bitbucket.org/snippets/OlegChulakovStudio/rejKe5
3... 2... 1,5... 1... 0
Кстати, про обратный отсчет в JavaScript: часто в интернете можно увидеть, как разработчики делают ежесекундный
https://bitbucket.org/snippets/OlegChulakovStudio/de4q4L
Однако при таком подходе совершенно не учитывается снижение приоритета скриптов после сворачивания вкладки или всего окна браузера. Если пользователь работает с другой вкладкой, то обратный отсчет в этой будет идти медленнее, и при возвращении будет доступно неправильное значение.
Чтобы избежать таких проблем, нужно производить вычисления, опираясь на время, до которого идет отсчет:
https://bitbucket.org/snippets/OlegChulakovStudio/ae4q48
Кстати, про обратный отсчет в JavaScript: часто в интернете можно увидеть, как разработчики делают ежесекундный
setInterval, при каждом вызове которого уменьшают оставшееся время на секунду и выводят значение в интерфейсе. Одним словом, делают что-то вроде этого:https://bitbucket.org/snippets/OlegChulakovStudio/de4q4L
Однако при таком подходе совершенно не учитывается снижение приоритета скриптов после сворачивания вкладки или всего окна браузера. Если пользователь работает с другой вкладкой, то обратный отсчет в этой будет идти медленнее, и при возвращении будет доступно неправильное значение.
Чтобы избежать таких проблем, нужно производить вычисления, опираясь на время, до которого идет отсчет:
https://bitbucket.org/snippets/OlegChulakovStudio/ae4q48
Компонент, я твой отец
При разработке веб-приложений на React нередко возникает необходимость переиспользовать логику компонентов, полностью меняя их внешний вид. Чаще всего для этого используют Компоненты Высшего Порядка (Higher-Order Components), но есть и другие подходы, которые, в зависимости от решаемой задачи, могут оказаться более удобными.
Рассмотрим менее известный способ под названием «Function as Child Components» (FaCC), при котором компонент получает в качестве потомков не элементы, а функцию, что дает возможность управлять рендером из родителя.
Например, если в интерфейсе много выпадающих списков с одинаковой логикой (показать/скрыть), но выглядят они абсолютно по-разному, то решение с помощью FaCC может выглядеть вот так:
https://bitbucket.org/snippets/OlegChulakovStudio/LeEGkg
Интерактивное демо с более подробным кодом:
https://codesandbox.io/s/8x2183nj5j
Также, чтобы лучше понять ситуации, в которых может быть полезен этот подход, можно посмотреть популярные библиотеки, которые его используют: react-motion, react-media, PayPal Downshift.
При разработке веб-приложений на React нередко возникает необходимость переиспользовать логику компонентов, полностью меняя их внешний вид. Чаще всего для этого используют Компоненты Высшего Порядка (Higher-Order Components), но есть и другие подходы, которые, в зависимости от решаемой задачи, могут оказаться более удобными.
Рассмотрим менее известный способ под названием «Function as Child Components» (FaCC), при котором компонент получает в качестве потомков не элементы, а функцию, что дает возможность управлять рендером из родителя.
Например, если в интерфейсе много выпадающих списков с одинаковой логикой (показать/скрыть), но выглядят они абсолютно по-разному, то решение с помощью FaCC может выглядеть вот так:
https://bitbucket.org/snippets/OlegChulakovStudio/LeEGkg
Интерактивное демо с более подробным кодом:
https://codesandbox.io/s/8x2183nj5j
Также, чтобы лучше понять ситуации, в которых может быть полезен этот подход, можно посмотреть популярные библиотеки, которые его используют: react-motion, react-media, PayPal Downshift.
Карты, боты, GMT+2
Для корректной работы со временем многим системам необходима информация о часовом поясе клиента. В веб-приложениях эту проблему решают за счет выбора города или зоны в интерфейсе или в профиле пользователя.
При разработке PM Bot (кстати, скоро релиз) ребята из нашей Лаборатории узнали, что Telegram API не передает информацию о таймзоне собеседника, а привычные механики выбора пояса неприменимы для ботов.
Что же делать? Выводить клавиатуру с каждым вариантом? Получается слишком громоздко и неудобно. Просить отправить сообщение с названием города или пояса? Могут быть ошибки как при вводе текста, так и на этапе его обработки ботом.
Мы остановились на удобном для пользователя способе с автоматическим определением на основе геопозиции.
Не так давно в Telegram API появилась возможность расширять варианты ответов в клавиатуре действиями
После того как бот получил широту и долготу собеседника, на их основе нетрудно получить временную зону. Для этого не нужно изобретать «велосипед» и можно воспользоваться существующими сервисами вроде Google Maps Time Zone API.
Механику с определением часового пояса по координатам можно использовать не только в ботах, но и, например, в веб-приложениях (в связке с HTML5 Geolocation). Однако следует учитывать, что пользователь может отказать в предоставлении своей позиции, а устройство или приложение может не иметь такой возможности.
Для корректной работы со временем многим системам необходима информация о часовом поясе клиента. В веб-приложениях эту проблему решают за счет выбора города или зоны в интерфейсе или в профиле пользователя.
При разработке PM Bot (кстати, скоро релиз) ребята из нашей Лаборатории узнали, что Telegram API не передает информацию о таймзоне собеседника, а привычные механики выбора пояса неприменимы для ботов.
Что же делать? Выводить клавиатуру с каждым вариантом? Получается слишком громоздко и неудобно. Просить отправить сообщение с названием города или пояса? Могут быть ошибки как при вводе текста, так и на этапе его обработки ботом.
Мы остановились на удобном для пользователя способе с автоматическим определением на основе геопозиции.
Не так давно в Telegram API появилась возможность расширять варианты ответов в клавиатуре действиями
request_location и request_contact. Теперь для получения координат пользователя достаточно при отправке сообщения от бота настроить параметр reply_markup следующим образом: {
"keyboard": [[
{ "text": "Отправить мою геопозицию", "request_location": true },
{ "text": "Не сейчас" }
]],
"resize_keyboard": true,
"one_time_keyboard": true
}После того как бот получил широту и долготу собеседника, на их основе нетрудно получить временную зону. Для этого не нужно изобретать «велосипед» и можно воспользоваться существующими сервисами вроде Google Maps Time Zone API.
Механику с определением часового пояса по координатам можно использовать не только в ботах, но и, например, в веб-приложениях (в связке с HTML5 Geolocation). Однако следует учитывать, что пользователь может отказать в предоставлении своей позиции, а устройство или приложение может не иметь такой возможности.
Операция «И»
В последние годы многие Frontend-разработчики начинают использовать трендовые технологии раньше, чем изучат основы JavaScript, что порой приводит к неожиданным для них багам.
Например, для скрытия пустого списка новички в React могут использовать, казалось бы, привычный многим код:
Увы, когда
Чтобы понять причину такого поведения, следует вспомнить, как работает логический оператор
В данном примере, если массив окажется пустым, логическое И преобразует
Для избежания таких проблем, убедитесь, что выражение перед
В последние годы многие Frontend-разработчики начинают использовать трендовые технологии раньше, чем изучат основы JavaScript, что порой приводит к неожиданным для них багам.
Например, для скрытия пустого списка новички в React могут использовать, казалось бы, привычный многим код:
<div>
{props.tasks.length &&
<TaskList tasks={props.tasks} />
}
</div>
Увы, когда
props.tasks окажется пустым массивом, вместо списка будет отрисовано число 0. Особенно везучие разработчики узнают об этом, когда проект уже находится в production.Чтобы понять причину такого поведения, следует вспомнить, как работает логический оператор
&& в JavaScript: он интерпретирует значения как логические, но результат возвращает без преобразования.В данном примере, если массив окажется пустым, логическое И преобразует
0 в false и остановит вычисление, так как результат ложный и вернет 0.Для избежания таких проблем, убедитесь, что выражение перед
&& всегда является логическим (boolean).Я пришлю ее вам по кусочкам
Если для доступа к файлу требуется выполнить какие-либо проверки или он формируется сервером, необходимо организовать его динамическую передачу и при этом учесть, что работа с большими файлами может привести к переполнению памяти.
Рассмотрим два примера. Что не так с первым кодом и почему лучше использовать второй?
При использовании
Также заметим, что в современных фреймворках есть готовые методы для отправки файлов.
Если для доступа к файлу требуется выполнить какие-либо проверки или он формируется сервером, необходимо организовать его динамическую передачу и при этом учесть, что работа с большими файлами может привести к переполнению памяти.
Рассмотрим два примера. Что не так с первым кодом и почему лучше использовать второй?
При использовании
file_get_contents весь файл загружается в оперативную память, и, если он больших размеров, либо запросы на скачивание файла часто поступают на сервер, будет происходить существенное расходование ресурсов. Решение этой проблемы — частичное чтение из файла и передача клиенту.Также заметим, что в современных фреймворках есть готовые методы для отправки файлов.
Не крути мне блоки
В одной из прошлых заметок мы рассказали про микровзаимодействия, связанные с курсором пользователя, их положительное влияние на работу с интерактивными элементами интерфейса и даже поделились нашей библиотекой react-interactions.
Разумеется, микровзаимодействия не ограничиваются только грамотной работой с тапами и кликами. Например, в мобильных версиях сайтов и сервисов мы также оживляем объекты страницы за счет их наклона при изменении ориентации устройства в пространстве. Таким образом, вращаемые элементы обретают физические свойства, а пользователь получает возможность рассмотреть их с разных ракурсов.
Так, в рамках концепции сайта для Райффайзенбанк, сделанной нами год назад, мы поступили с банковскими картами — за счет их вращения посетитель понимает, что это реальный объект, а не просто фотография или фон на сайте.
При этом добавить это микровзаимодействие на сайт не так сложно: для получения текущего положения устройства в пространстве создается обработчик события
Для того чтобы вращение происходило относительно положения, в котором пользователь изначально держал устройство, можно сохранить первые полученные параметры наклона, а затем вращать элементы на разницу между ними и текущими данными.
Также родительскому блоку в CSS нужно установить
Для добавления плавности движения можно использовать обычный
Если опустить вопросы кроссбраузерности, то решение может занять не более 30 строк JavaScript-кода:
https://bitbucket.org/snippets/OlegChulakovStudio/oeoj9E
Код в действии (смотреть с мобильных устройств):
https://dev.chulakov.ru/deepdigital/rotate/
В одной из прошлых заметок мы рассказали про микровзаимодействия, связанные с курсором пользователя, их положительное влияние на работу с интерактивными элементами интерфейса и даже поделились нашей библиотекой react-interactions.
Разумеется, микровзаимодействия не ограничиваются только грамотной работой с тапами и кликами. Например, в мобильных версиях сайтов и сервисов мы также оживляем объекты страницы за счет их наклона при изменении ориентации устройства в пространстве. Таким образом, вращаемые элементы обретают физические свойства, а пользователь получает возможность рассмотреть их с разных ракурсов.
Так, в рамках концепции сайта для Райффайзенбанк, сделанной нами год назад, мы поступили с банковскими картами — за счет их вращения посетитель понимает, что это реальный объект, а не просто фотография или фон на сайте.
При этом добавить это микровзаимодействие на сайт не так сложно: для получения текущего положения устройства в пространстве создается обработчик события
deviceorientation, а полученные в нем градусы наклона используются для установки CSS-свойства transform.Для того чтобы вращение происходило относительно положения, в котором пользователь изначально держал устройство, можно сохранить первые полученные параметры наклона, а затем вращать элементы на разницу между ними и текущими данными.
Также родительскому блоку в CSS нужно установить
perspective, иначе вращения в пространстве не будет видно.Для добавления плавности движения можно использовать обычный
transition. Если опустить вопросы кроссбраузерности, то решение может занять не более 30 строк JavaScript-кода:
https://bitbucket.org/snippets/OlegChulakovStudio/oeoj9E
Код в действии (смотреть с мобильных устройств):
https://dev.chulakov.ru/deepdigital/rotate/
Вот это форма
Одной из самых тяжелых задач в разработке веб-приложений является работа с динамическими формами: большое разнообразие типов полей, их валидация, асинхронное конструирование частей формы, автозаполнение, сериализация, сохранение, обработка состояний и многое другое. Все эти проблемы можно решить за счет использования связки React, Redux и Redux Form.
Чтобы показать как она работает, мы собрали для вас интерактивное демо, содержащее код следующих решений:
1) подключение Redux с использованием Ducks-методологии упорядочивания редюсеров, экшенов и констант;
2) работа с нестандартными полями;
3) получение и сохранение состояния формы;
4) написание и подключение функций валидации;
5) отображение ошибок заполнения;
6) переинициализация формы с помощью свойства
7) переопределение значений полей.
Одной из самых тяжелых задач в разработке веб-приложений является работа с динамическими формами: большое разнообразие типов полей, их валидация, асинхронное конструирование частей формы, автозаполнение, сериализация, сохранение, обработка состояний и многое другое. Все эти проблемы можно решить за счет использования связки React, Redux и Redux Form.
Чтобы показать как она работает, мы собрали для вас интерактивное демо, содержащее код следующих решений:
1) подключение Redux с использованием Ducks-методологии упорядочивания редюсеров, экшенов и констант;
2) работа с нестандартными полями;
3) получение и сохранение состояния формы;
4) написание и подключение функций валидации;
5) отображение ошибок заполнения;
6) переинициализация формы с помощью свойства
initialValues;7) переопределение значений полей.
1 000 диджитанцев
Число подписчиков канала достигло тысячи. Для тех, кто с нами недавно, рассказываем, что мы успели рассмотреть с момента запуска.
Сперва мы поделились историей о том, как мы делали 3D-карту для сайта Гран-при Формулы-1, и информацией о том, как легко создавать объемные объекты с помощью Displacement Mapping и ThreeJS.
Рассказали про микровзаимодействия, связанные с кликами и тапами, поделились нашей библиотекой react-interactions, а также показали, как можно оживить блоки за счет их вращения вместе с устройством пользователя.
Написали много заметок про React: запустили цикл по интерфейсным элементам, рассказали про FaCC, показали наш UIKit и сделали демо про Redux Form.
Показали метод, с помощью которого легко исправить баги при прокрутке блоков в iOS Safari.
Дали ссылку на нашу образовательную презентацию про 2D в canvas.
Пробежались по теме создания Telegram-ботов: рассказали, как использовать Telegram для дистрибуции контента и как можно быстро получить часовой пояс пользователя.
Погрузились в работу со временем: рассказали, как можно централизировать расчеты при создании приложений, как синхронизировать время в браузера с часами сервера и как правильно делать обратный отсчет в JavaScript.
Рассказали про стрелочные функции в JavaScript-классах и напомнили про нюансы работы с логическим оператором И.
Поделились знаниями про то, как сохранять Emoji в базу данных и правильно организовать динамическую отдачу файлов с сервера.
Дальше больше, не переключайтесь.
Число подписчиков канала достигло тысячи. Для тех, кто с нами недавно, рассказываем, что мы успели рассмотреть с момента запуска.
Сперва мы поделились историей о том, как мы делали 3D-карту для сайта Гран-при Формулы-1, и информацией о том, как легко создавать объемные объекты с помощью Displacement Mapping и ThreeJS.
Рассказали про микровзаимодействия, связанные с кликами и тапами, поделились нашей библиотекой react-interactions, а также показали, как можно оживить блоки за счет их вращения вместе с устройством пользователя.
Написали много заметок про React: запустили цикл по интерфейсным элементам, рассказали про FaCC, показали наш UIKit и сделали демо про Redux Form.
Показали метод, с помощью которого легко исправить баги при прокрутке блоков в iOS Safari.
Дали ссылку на нашу образовательную презентацию про 2D в canvas.
Пробежались по теме создания Telegram-ботов: рассказали, как использовать Telegram для дистрибуции контента и как можно быстро получить часовой пояс пользователя.
Погрузились в работу со временем: рассказали, как можно централизировать расчеты при создании приложений, как синхронизировать время в браузера с часами сервера и как правильно делать обратный отсчет в JavaScript.
Рассказали про стрелочные функции в JavaScript-классах и напомнили про нюансы работы с логическим оператором И.
Поделились знаниями про то, как сохранять Emoji в базу данных и правильно организовать динамическую отдачу файлов с сервера.
Дальше больше, не переключайтесь.
Придержите дверь
Протокол HTTP, начиная с версии 1.1, создает постоянное соединение (HTTP keep-alive) для нескольких запросов на один и тот же хост. Это позволяет снизить загрузку процессора и расход памяти, так как открывается меньше соединений одновременно. При HTTPS-соединениях разница более заметна, так как создание защищенного соединения требует больших ресурсов и дополнительного сетевого обмена между клиентом и сервером.
Многие разработчики, которые не учитывают или не знают этой информации, в итоге обнаруживают, что их приложение работает медленней, чем они ожидали.
Давайте рассмотрим эту проблему на примере следующей задачи: получить с помощью API GitHub все репозитории GeoIP вместе с их релизами. Одним запросом это сделать нельзя: сначала нужно получить список репозиториев, а затем для каждого запросить релизы.
Рассмотрим решение двумя способами. На первый взгляд разницы между ними нет, но если мы выполним скрипты, то получим совершенно разные результаты.
Что же не так? В первом случае между сервером и клиентом создается одно соединение для всех запросов, во втором случае — каждый раз создается новый объект клиента, и, соответственно, для каждого запроса создается новое соединение, что приводит к потерям во времени.
Также можно представить следующую ситуацию — на сайте при определенных действиях пользователей происходит обращение к API какого-либо сервиса. В таком случае при запросе на ваш сервер происходит обращение на другой сервер согласно API сервиса, и для каждого такого запроса расходуются ресурсы на создание соединения. В высоконагруженных системах это может привести к существенным потерям в ресурсах и скорости работы.
Исправить это можно, например, переложив работу по созданию внешних запросов на специального демона, который сможет пользоваться возможностями keep-alive и поддерживать набор постоянных соединений.
Протокол HTTP, начиная с версии 1.1, создает постоянное соединение (HTTP keep-alive) для нескольких запросов на один и тот же хост. Это позволяет снизить загрузку процессора и расход памяти, так как открывается меньше соединений одновременно. При HTTPS-соединениях разница более заметна, так как создание защищенного соединения требует больших ресурсов и дополнительного сетевого обмена между клиентом и сервером.
Многие разработчики, которые не учитывают или не знают этой информации, в итоге обнаруживают, что их приложение работает медленней, чем они ожидали.
Давайте рассмотрим эту проблему на примере следующей задачи: получить с помощью API GitHub все репозитории GeoIP вместе с их релизами. Одним запросом это сделать нельзя: сначала нужно получить список репозиториев, а затем для каждого запросить релизы.
Рассмотрим решение двумя способами. На первый взгляд разницы между ними нет, но если мы выполним скрипты, то получим совершенно разные результаты.
Что же не так? В первом случае между сервером и клиентом создается одно соединение для всех запросов, во втором случае — каждый раз создается новый объект клиента, и, соответственно, для каждого запроса создается новое соединение, что приводит к потерям во времени.
Также можно представить следующую ситуацию — на сайте при определенных действиях пользователей происходит обращение к API какого-либо сервиса. В таком случае при запросе на ваш сервер происходит обращение на другой сервер согласно API сервиса, и для каждого такого запроса расходуются ресурсы на создание соединения. В высоконагруженных системах это может привести к существенным потерям в ресурсах и скорости работы.
Исправить это можно, например, переложив работу по созданию внешних запросов на специального демона, который сможет пользоваться возможностями keep-alive и поддерживать набор постоянных соединений.
Оно само! Я ничего не трогал
Многие компании до сих пор не используют инструменты для анализа JavaScript-кода, и, как следствие, каждый разработчик в их команде пишет код по-своему и допускает ошибки из-за невнимательности.
Сейчас стандартом в решении этих проблем стал ESLint, который очень легко настроить и подключить к проекту. Однако многих раздражает необходимость регулярно исправлять ошибки, которые находит этот инструмент. Такие разработчики считают, что траты времени на возвращение к написанным ранее строкам кода для добавления какого-нибудь пробела ничем не оправданы, и отказываются от использования ESLint, даже не узнав, что автоматизировать можно не только анализ, но и исправление.
Самый простой способ — добавить в используемую IDE плагин ESLint и включить в нем автоисправление кода на основе правил из файла
Многие компании до сих пор не используют инструменты для анализа JavaScript-кода, и, как следствие, каждый разработчик в их команде пишет код по-своему и допускает ошибки из-за невнимательности.
Сейчас стандартом в решении этих проблем стал ESLint, который очень легко настроить и подключить к проекту. Однако многих раздражает необходимость регулярно исправлять ошибки, которые находит этот инструмент. Такие разработчики считают, что траты времени на возвращение к написанным ранее строкам кода для добавления какого-нибудь пробела ничем не оправданы, и отказываются от использования ESLint, даже не узнав, что автоматизировать можно не только анализ, но и исправление.
Самый простой способ — добавить в используемую IDE плагин ESLint и включить в нем автоисправление кода на основе правил из файла
.eslintrc. Например, если вы используете Visual Studio Code, то после установки плагина ESLint и активации опции eslint.autoFixOnSave в настройках редактора большинство ошибок в коде будет исправляться автоматически при сохранении файлов.Вот мой сертификат
В последние годы большое внимание уделяется обеспечению безопасного соединения. Сейчас наличие SSL-сертификатов влияет даже на ранжирование сайтов в поисковых системах.
Зачастую работа системы без HTTPS и вовсе невозможна: например, если разрабатывать серверную часть для Telegram-бота или организовывать обмен с другим сервисом, который уже использует безопасное соединение.
Многих останавливает необходимость приобретать сертификаты, особенно если проект еще находится на этапе разработки или в рамках системы требуются сертификаты для нескольких доменов.
Но и у этой проблемы есть простое решение: с помощью консольной утилиты Certbot можно получать бесплатные SSL-сертификаты, которые будут работать до 90 дней.
Certbot легко установить: например, в случае с сервером на базе Debian, это делается буквально за секунду с помощью
Помимо получения сертификатов, эта утилита может даже самостоятельно создавать виртуальные хосты для HTTPS в настройках используемого web-сервера.
Если планируется использование сертификатов в production, то важно не забывать настраивать автообновление сертификатов, добавив в Cron сервера команду
В последние годы большое внимание уделяется обеспечению безопасного соединения. Сейчас наличие SSL-сертификатов влияет даже на ранжирование сайтов в поисковых системах.
Зачастую работа системы без HTTPS и вовсе невозможна: например, если разрабатывать серверную часть для Telegram-бота или организовывать обмен с другим сервисом, который уже использует безопасное соединение.
Многих останавливает необходимость приобретать сертификаты, особенно если проект еще находится на этапе разработки или в рамках системы требуются сертификаты для нескольких доменов.
Но и у этой проблемы есть простое решение: с помощью консольной утилиты Certbot можно получать бесплатные SSL-сертификаты, которые будут работать до 90 дней.
Certbot легко установить: например, в случае с сервером на базе Debian, это делается буквально за секунду с помощью
apt-get install.Помимо получения сертификатов, эта утилита может даже самостоятельно создавать виртуальные хосты для HTTPS в настройках используемого web-сервера.
Если планируется использование сертификатов в production, то важно не забывать настраивать автообновление сертификатов, добавив в Cron сервера команду
certbot renew.«Т» значит Типограф
На удобство использования веб-приложений и сайтов влияет не только дизайн или интерфейс, но и такая, казалось бы, простая вещь, как тексты. Если не подготавливать их с учетом норм экранной типографики, специфики и правил русского языка, то это может негативно сказаться на восприятии материалов и скорости работы пользователя с системой.
В текстах должны использоваться правильные тире и кавычки, в цифрах нужна разбивка на разряды, союзы и предлоги должны быть на одной строке со следующим словом, так же как и конструкции вида «1 кг». Правил очень много и вручную прорабатывать их все если и возможно, то неоправданно долго, но к нашему общему счастью это можно автоматизировать.
Мы разделяем работу по типографике на две части:
1) форматирование служебных и интерфейсных текстов;
2) автоматическая обработка системой динамических текстов.
Первая часть позволяет не тратить ресурсы сервера или браузера на регулярное форматирование статических текстов из интерфейса системы: разработчики во время работы над версткой веб-приложения обрабатывают нужные предложения прямо в IDE с помощью плагинов для типографики.
Вторая же служит для форматирования backend-ом текстов, добавляемых пользователями или импортируемых из других систем. Так, например, мы обрабатываем загружаемые из Telegram-канала заметки для раздела Chulakov Notes на сайте Студии. Мы рекомендуем «оттипографить» текст один раз и сохранить полученный HTML-код в базу данных, чтобы ускорить загрузку страниц. В рамках JavaScript-стека можно использовать для обработки библиотеку typograf, в PHP — «Типограф Муравьёва».
Выносить автоформатирование в браузер пользователя не стоит, поскольку это приводит к заметным задержкам в отрисовке интерфейсов.
На удобство использования веб-приложений и сайтов влияет не только дизайн или интерфейс, но и такая, казалось бы, простая вещь, как тексты. Если не подготавливать их с учетом норм экранной типографики, специфики и правил русского языка, то это может негативно сказаться на восприятии материалов и скорости работы пользователя с системой.
В текстах должны использоваться правильные тире и кавычки, в цифрах нужна разбивка на разряды, союзы и предлоги должны быть на одной строке со следующим словом, так же как и конструкции вида «1 кг». Правил очень много и вручную прорабатывать их все если и возможно, то неоправданно долго, но к нашему общему счастью это можно автоматизировать.
Мы разделяем работу по типографике на две части:
1) форматирование служебных и интерфейсных текстов;
2) автоматическая обработка системой динамических текстов.
Первая часть позволяет не тратить ресурсы сервера или браузера на регулярное форматирование статических текстов из интерфейса системы: разработчики во время работы над версткой веб-приложения обрабатывают нужные предложения прямо в IDE с помощью плагинов для типографики.
Вторая же служит для форматирования backend-ом текстов, добавляемых пользователями или импортируемых из других систем. Так, например, мы обрабатываем загружаемые из Telegram-канала заметки для раздела Chulakov Notes на сайте Студии. Мы рекомендуем «оттипографить» текст один раз и сохранить полученный HTML-код в базу данных, чтобы ускорить загрузку страниц. В рамках JavaScript-стека можно использовать для обработки библиотеку typograf, в PHP — «Типограф Муравьёва».
Выносить автоформатирование в браузер пользователя не стоит, поскольку это приводит к заметным задержкам в отрисовке интерфейсов.
Скачай меня, если сможешь
В нашей практике неоднократно возникали ситуации, когда необходимо было дать пользователю возможность скачать изображение, которое он сделал на сайте и уже видит в браузере. Например, если пользователь накладывает эффекты на фотографию или создает какую-нибудь открытку с помощью конструктора. Применять в такой ситуации backend для генерации файла для скачивания очень избыточно: даже если получится идеально продублировать логику отрисовки, все равно остается вероятность визуального несоответствия с изображением в браузере.
Ранее мы поделились с вами нашей образовательной презентацией по базовым возможностям 2D-контекста canvas, а сейчас хотим обратить внимание на то, что содержимое холста можно скачать.
Многие знают, что это делают, нажав правой кнопкой мыши на canvas-элемент и выбрав команду «Сохранить изображение как». К сожалению, тех, кто об этом не знает, значительно больше, и полагаться на такое решение нельзя. Необходима понятная всем кнопка «Скачать».
Исправить ситуацию поможет функция
Для наглядности мы собрали небольшое демо, где рисуется простой график, который можно скачать как PNG-файл:
https://codepen.io/OlegChulakovStudio/pen/KyEBEN
В нашей практике неоднократно возникали ситуации, когда необходимо было дать пользователю возможность скачать изображение, которое он сделал на сайте и уже видит в браузере. Например, если пользователь накладывает эффекты на фотографию или создает какую-нибудь открытку с помощью конструктора. Применять в такой ситуации backend для генерации файла для скачивания очень избыточно: даже если получится идеально продублировать логику отрисовки, все равно остается вероятность визуального несоответствия с изображением в браузере.
Ранее мы поделились с вами нашей образовательной презентацией по базовым возможностям 2D-контекста canvas, а сейчас хотим обратить внимание на то, что содержимое холста можно скачать.
Многие знают, что это делают, нажав правой кнопкой мыши на canvas-элемент и выбрав команду «Сохранить изображение как». К сожалению, тех, кто об этом не знает, значительно больше, и полагаться на такое решение нельзя. Необходима понятная всем кнопка «Скачать».
Исправить ситуацию поможет функция
toDataURL, переводящая изображение на холсте в base64-код, который можно использовать в качестве атрибута href для ссылки.Для наглядности мы собрали небольшое демо, где рисуется простой график, который можно скачать как PNG-файл:
https://codepen.io/OlegChulakovStudio/pen/KyEBEN
Не падай больше
Если в рамках базы данных проекта есть таблица с большим количеством строк, то во время выполнения миграции, изменяющей структуру этой таблицы, веб-приложение может быть недоступно.
Вызвано это тем, что MySQL, выполняя операцию
Для решения этой проблемы можно воспользоваться Percona Server — инструментом, значительно расширяющим возможности MySQL.
Встроенная в него утилита
Если в рамках базы данных проекта есть таблица с большим количеством строк, то во время выполнения миграции, изменяющей структуру этой таблицы, веб-приложение может быть недоступно.
Вызвано это тем, что MySQL, выполняя операцию
ALTER TABLE, перезаписывает каждую строку таблицы, и чем их больше, тем дольше будут выполняться операции добавления/удаления колонки, изменения индексов и т.д. Для решения этой проблемы можно воспользоваться Percona Server — инструментом, значительно расширяющим возможности MySQL.
Встроенная в него утилита
pt-online-schema-change позволяет изменять структуру таблиц, не вызывая блокировок и простоев. Для этого она самостоятельно создает копию изменяемой таблицы с новой структурой, копирует в нее данные из основной таблицы, обновляет структуру и заменяет старую таблицу новой. За счет этого автоматически исключаются вызываемые миграциями сбои в работе веб-приложений.