Недавно мне довелось поговорить с Марком Ароном Шулёвски, одним из основателей и разработчиков Drops - красивого приложения для изучения словарного запаса.

Google назвал Drops одним из лучших приложений 2018 года. Что особенно интересно для нас, Drops был написан на React Native, который, несмотря на постоянно растущую популярность и успех, многие до сих пор не считают подходящим инструментом для создания качественных приложений. К счастью, на таких примерах, как Drops, мы видим, что важна не структура, а команда и образ мышления.

Мы решили полностью опубликовать это интервью здесь, чтобы вы могли узнать много интересного от Марка!

Интервью

Домен приложения

Войцех: Спасибо, что нашли время поговорить со мной. Я хотел начать с того, чтобы узнать больше о вас, о том, что заставило вас создать Drops и какова ваша миссия. Не могли бы вы немного поговорить об этом?

Марк: Да, конечно! Компания началась около 7 лет назад. Я тогда был дизайнером, мы создавали визуальные мелочи, это было очень весело! Затем я встретил Дэниела, моего соучредителя, и мы решили сделать дополнительный доход от визуальных загадок, чтобы попытаться сделать его более полезным и использовать в образовании.

Теория заключалась в том, что, объединив визуальные загадки с учебным содержанием, в данном конкретном случае - иностранными словами, мы сможем сделать что-то гораздо более эффективное на подсознательном уровне. Пока ваш мозг пытается собрать пазл, он помогает сформировать более сильную активную связь с иностранным словом, которое он также видит на экране. Итак, это приложение называлось Learn Invisible, и примерно шесть с половиной или семь лет назад мы начали работать в эстонском инкубаторе стартапов. Именно тогда мы фактически профинансировали компанию, поэтому компания является эстонской, хотя мы оба с моим соучредителем родом из Будапешта. Тогда исходное приложение оказалось не так хорошо, как мы думали, мы не были так опытны и, скажем так, не так много думали о том, для кого мы на самом деле создаем это приложение и чего именно мы хотим достичь. Честно говоря, мы были довольно наивны.

Войцех: Значит, это был в основном учебный опыт?

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

Затем, основываясь на этом опыте, мы еще раз попробовали обучение, мы поняли, что было не так с предыдущим приложением, как сделать его более удобным для пользователя, более интерактивным и оптимизированным для мобильных устройств. Это было в то время, когда запускались Tinder, Uber и многие другие сервисы, и эти ребята захватили мобильное пространство. Мобильные технологии набирали обороты, поэтому мы подумали, что все остальные - Duolingo, Babbel и т. Д. - немного отстают, поскольку они сделали перенос своего веб-приложения на мобильные устройства в соотношении 1: 1. Они по-прежнему были успешными, но мы чувствовали, что можем сделать что-то еще - продукт для изучения языков с мобильных устройств. Итак, это были капли. Мы выпустили его около четырех лет назад и начали набирать обороты около двух с половиной лет назад.

Войцех: четыре года назад это явно не React Native. Это было родное приложение?

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

Взаимодействие как инструмент обучения

Войцех: вы создали Drops, имея в виду сделать его «самым интерактивным приложением для изучения словарного запаса». Зачем сосредотачиваться на взаимодействиях?

Марк: Мы думали, что именно поэтому мы отличаемся от других, потому что нам удалось сделать что-то похожее на игру. У него игра ощущения. Я не уверен, что все знакомы с этим термином. Разработчики игрового процесса используют его, чтобы описать, где у вас есть самая простая версия игры, и вы добавляете к ней эффекты, которые имеют огромное значение. Думаю, мы были первыми, кто приложил к этому много усилий.

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

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

Марк: Да, определенно. То, что вы сказали, - это именно то, о чем мы все. Вы знаете, что изучение словарного запаса по умолчанию - это рутинная работа. И если мы сможем сделать что-то более интересное и более приятное, тогда мы уже выигрываем во многих отношениях. Вот почему мы посвятили себя этой области, небольшой производственной компании, которой мы придерживаемся, по крайней мере, в течение следующих нескольких лет. Здесь есть большой потенциал, которого мы еще не реализовали.

Войцех: Я видел, что вы также выпустили еще одно приложение для изучения языков: Сценарии для изучения алфавитов. Планируете ли вы охватить больше аспектов изучения языка?

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

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

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

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

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

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

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

Войцех: когда вы упоминаете Framer, их новая версия X имеет некоторые функции совместимости с React. Довелось ли вам ими воспользоваться?

Марк: Нет, не сейчас. Честно говоря, код, который мы используем во Framer, легко реализовать заново. Мы не рассматривали часть экспорта компонентов Framer X или React, но сейчас мне трудно представить, как код, который у нас есть сейчас, мог быть создан Framer. Может быть, какая-то базовая форма этого.

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

Марк: Фактически, мы дошли до того момента, когда стали более жесткими. Например, мы сказали, что каждый раз, когда мы проводим A / B-тестирование функции, когда видим, что она работает хорошо, и мы хотим развернуть ее для всех, мы добавляем анимацию ко всем страницам (или компонентам), которые мы только что добавили. Обычно это анимация появления или исчезновения, которая, как мы договорились, будет важной частью нашего процесса разработки. Это огромная часть ДНК визуального дизайна Drops.

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

Работа с анимацией в React Native

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

Марк: мы используем много Animated из библиотеки React Native и просто используем PanResponders для их перемещения. Что мы также используем, так это то, что мы сохраняем анимированные значения в состоянии, и мы пытаемся передать PanResponders нескольким представлениям, если мы можем, и мы стараемся убедиться, что мы не повторно визуализируем весь экран и все состояние Redux. каждый раз было PanResponder изменение.

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

Войцех: устройства iOS обычно более мощные.

Марк: Да, но мне кажется, что React Native был создан для iOS, и я считаю, что это правда. Android всегда был второй мыслью.

Копнув немного глубже, у нас было несколько представлений React Native в нашем родном приложении для iOS, потому что в какой-то момент мы сказали, что любое новое представление будет представлением React Native, чтобы мы могли упростить миграцию с нашей стороны. , потому что мы знали, что это скоро. И мы перестроили все приложение для Android в React Native, а затем выпустим эту кодовую базу для приложения iOS, выполнив все необходимые миграции. Это способствовало некоторому перекрестному развитию наших платформ. Это был действительно интересный опыт.

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

Войцех: Это очень хороший способ решить эту проблему. Я видел, что многие команды делают наоборот, потому что сами разработчики используют iOS, поэтому они начинают с этой версии. Гораздо разумнее сделать так, как вы с этим справились.

Марк: у нас это точно работает хорошо.

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

В частности, мы закончили тем, что передали анимированные значения в компонент, но не сохранили ссылку на него во внутреннем состоянии. Затем в родительском компоненте мы можем использовать setValue, чтобы изменить его. Таким образом, дочерний компонент не отслеживает это изменение (поскольку ссылка на значение не изменяется) и не запускает повторную визуализацию, но поскольку мы используем собственный драйвер для анимации, эти значения имеют прямую привязка к родной стороне, поэтому на экране мы можем видеть изменения. Таким образом, мы могли видеть анимацию со скоростью 60 кадров в секунду, по крайней мере, на некоторых устройствах, которые способны на это.

Каждый раз, когда мы обновляем внутреннее состояние компонента, даже не состояние Redux, на Android происходит пропадание кадра. Вы, вероятно, можете увидеть это даже на высокопроизводительном устройстве Android. Например, на экране, когда слово появляется впервые, когда мы начинаем перетаскивать слово к значку головы, в какой-то момент голова открывается. У нас есть выпадение кадра, потому что нам нужно заменить изображение другим изображением, и это произойдет в области React, поэтому часть дерева будет отображаться. Падение кадров видно даже на устройствах высшего класса.

Войцех: я вижу, что вы используете Animated и PanResponder из стандартной библиотеки. Вы рассматривали возможность использования react-native-reanimated или react-native-gesture-handler библиотек?

Марк: Мы сделали. И у нас где-то есть прототип. react-native-gesture-handler определенно дал нам лучшую производительность.

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

Но есть еще одна причина. Мы готовимся сделать что-то в Интернете, и, насколько я могу судить, значения Animated и PanResponder являются макетами, и это универсальный API, который мы можем использовать с react-native-web, и я не нашел информации об этом для react-native-reanimated или react-native-gesture-handler.

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

Марк: Хотя API может быть действительно похожим, или мы можем сделать что-то, что могло бы объединить оба этих параметра одновременно. У нас просто не было на это времени.

Войцех: Используете ли вы какие-либо другие способы отображения анимации, например, Lottie?

Марк: Да, есть. Анимация падения (когда вводится новое слово) - это анимация Лотти. Мы используем анимированное значение для запуска анимации Lottie. Для оркестровки анимаций мы используем Animated.sequence и тому подобное.

Мы также написали наш собственный компонент более высокого уровня, который включает Animate.sequence, что гарантирует отсутствие ошибок при размонтировании компонента, которые обычно возникают при вызове блока завершения.

Производительность отладки

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

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

Очевидно, что отладчик Chrome не так хорошо работает, потому что часть кода выполняется на нативной стороне, а также код JavaScript выполняется в вашем браузере, даже не на вашем телефоне. Однако отладчик Chrome и приложение отладчика React Native были действительно полезны для отладки повторных рендеров React и проблем с Redux. Вы можете профилировать производительность, процессор и память, и вы получите красивое дерево функций, которые занимают большую часть времени.

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

Войцех: мне было интересно, использовали ли вы reselect для решения этих проблем?

Марк: Да, мы используем и reselect, и re-reselect, потому что мы создаем селекторы поверх других селекторов, и нам нужно было больше контролировать, как работает мемоизация, и многое другое.

Что касается анимации, мы попробовали несколько вещей. Родные драйверы у нас работают очень красиво. Мы написали собственные оболочки и никогда не вызываем Animated.timing или spring без использования собственного драйвера. За исключением, может быть, одного или двух случаев по всей кодовой базе, когда мы не можем.

Мы так и не обнаружили проблем с анимацией в целом, проблемы, которые мы обнаружили, были связаны с повторным рендерингом, который мы ограничили, используя технику setValue, которую я описал ранее. У нас была одна проблема после обновления React Native, когда все стало очень медленно. Мы выяснили, что на Android, когда вы устанавливаете borderRadius больше, чем он может быть, он начинает рендеринг огромной текстуры, размер которой равен указанному значению. Это было действительно сложно отладить, но как только нам удалось выяснить, в чем проблема, решение оказалось довольно простым.

Создание настраиваемой навигации

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

Марк: Это спектакль. В то время, около полутора лет назад, практически не было возможности получить какую-либо из навигационных библиотек (и мы попробовали их все) только для визуализации текущего видимого экрана, а не каких-либо других, которые находятся на куча. Мы думали, что это потому, что вся система построена на тех же принципах, что и встроенная навигация iOS. Вы толкаете и выталкиваете экраны из стека, а просмотры по-прежнему сохраняются.

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

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

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

Использование React Native для сложных проектов

Войцех: ходят слава / миф / мнение, что React Native больше подходит для более простых приложений, которые не требуют взаимодействия. Очевидно, вы пошли против этого совета и создали действительно отточенное приложение, даже зашли так далеко, что переписали собственное приложение на React Native. Вы довольны этим опытом? Вы бы порекомендовали это сделать другим?

Марк: мы очень этому рады. Когда я спрашиваю своих коллег-разработчиков, с кем я это делал, они говорят, что это хорошая ставка. На тот момент это определенно была ставка. Когда мы начинали, экосистема React Native определенно была не такой зрелой, как сейчас. Было так много проблем. На самом деле, мы, вероятно, не сможем выпустить приложение до ноября, а в конце концов выпустили его в декабре, потому что так много чего не хватало, так много ошибок и т. Д.

Но примерно год назад он стал намного стабильнее. С тех пор произошли некоторые спады, но экосистема стала намного более богатой, вы можете найти привязки для всего, что захотите, даже для любого малоизвестного SDK аналитики. Примерно в декабре мы задавались вопросом, должны ли мы писать собственные привязки Zendesk, потому что их не было, и внезапно они появлялись изо дня в день, и мы могли просто использовать их. Это происходило несколько раз за те полтора года, которые мы потратили почти исключительно на React Native.

Что касается совета, я не вижу причин, по которым вы не сможете создать сложное приложение с помощью React Native. Я считаю, что с точки зрения ремонтопригодности наличие одной кодовой базы - огромный плюс. Все остальные кроссплатформенные фреймворки - отстой, за исключением, может быть, Flutter, который я никогда не пробовал. Мне это интересно, но, насколько я могу судить, Flutter - это, по сути, React Native, созданный Google.

Подход, который предлагают React и React Native, дает огромное преимущество. Если бы мы этого не сделали, наша команда разработчиков была бы как минимум в два или три раза больше, чем сейчас, и у нас было бы много проблем с согласованностью между платформами. Для Интернета нам пришлось бы переписывать все приложение с нуля, потому что мы не смогли бы повторно использовать нативный код.

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

Марк: Я думаю, что в самом начале было немного сложно использовать, но мы дошли до стадии, когда вам действительно не нужно проверять. Если вы не пишете что-то для конкретной платформы, например, получаете что-то напрямую из пакета приложения.

Если вы просто создаете пользовательский интерфейс и что-то не так, это будет обнаружено QA, а не нами. Я использую симулятор iOS и ожидаю, что по умолчанию все будет работать на Android. Если вы будете придерживаться пользовательского интерфейса, вас не будет ничего удивительного.

Может быть, когда вы начнете использовать react-native-svg и некоторые другие вещи, могут возникнуть проблемы, но, очевидно, есть человек, который проверяет это в конце, и это действительно полезно. В целом, по сравнению с обычным мобильным интерфейсом, это значительно повысило производительность. Живая перезагрузка, сверхбыстрая перекомпиляция и отсутствие открытия Android Studio или Xcode могут сделать ваш день, как бы грустно это ни звучало.

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

Заключительный совет

Войцех: Это было очень интересное и мотивирующее интервью. Я нашел в этом много вдохновения и надеюсь, что и другие люди тоже. Есть ли что-то еще, чем вы хотели бы поделиться с другими React Native или мобильными разработчиками в целом?

Отметьте: Если вы обеспокоены тем, что не можете сделать что-то в React Native, быстрое расследование, вероятно, докажет, что вы ошибались или докажет, что это будет намного проще обходите все, что, по вашему мнению, является препятствием. У нас были большие сюрпризы. То, что, как мы думали, займет у нас время, а то, что мы считали невозможным, оказалось очень легко сделать.

Вам понадобятся правильные шаблоны для решения проблем с производительностью, но я считаю, что они не относятся к JavaScript. Скорее, это общие проблемы с производительностью, с которыми вы столкнетесь также при написании нативного мобильного кода. Мы видели, как те же приемы оптимизации, которые мы использовали для iOS в нашем собственном коде, снова используются в React Native по тем же причинам.

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

Войцех: Спасибо, это было здорово!

Что будет дальше

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

Мы стремимся помочь людям создавать приложения, которые не только работают надежно, но и доставляют удовольствие при использовании и на которые приятно смотреть. Если вам это интересно, обязательно посмотрите это пространство!