company_banner

Web Apps: быстро, дёшево, круто

    Web Apps: быстро, дёшево, круто


    Каждый Web App (веб-апп) — это маленькое и весёлое фронтенд-приключение.
    Однажды в iFunny мы устроили «веб-апп марафон», развлекли миллионы пользователей и попутно заработали много денег. А теперь готовы рассказать, как же это всё было.


    Для начала представлюсь. Меня зовут Антон, я тимлид фронтенд-команды FunCorp.
    И в этой статье я поделюсь опытом разработки интерактивных веб-приложений на базе мобильного WebView.


    WebAppView


    WebView — это встроенный в мобильное приложение браузер.
    А если есть браузер, значит, есть и обширные возможности HTML5, JS, CSS.
    Это в теории. А как же на самом деле?


    А на самом деле нас интересовали и другие вопросы:


    • как хорошо примет новый формат аудитория iFunny?
    • насколько проблемны в разработке такие приложения? Два года назад в компании отсутствовал опыт в этой части, и очень хотелось его наверстать;
    • сэкономит ли данная технология время и деньги? Цикл разработки таких приложений короче, следовательно, такая возможность есть.

    Web App #1: Hellowinner


    В те времена команда состояла из двух человек и над всеми веб-аппами работал я один. С момента моего присоединения к команде прошло два месяца, поэтому с корабля я прямиком попал на «веб-апп бал».


    Первое приложение было подготовлено к 31 октября — дню празднования Хеллоуина. С помощью мини-игры с двумя кнопками планировалось пощекотать нервы пользователям и вызвать вот такую реакцию:


    Web App #1: Hellowinner


    Само же приложение выглядело вот так:


    Web App #1: Hellowinner


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


    Технологический стек был простым:


    • генератор статичных сайтов Harp;
    • шаблонизатор Jade (ныне Pug);
    • препроцессор LESS.

    Генератор Harp предоставил полную инфраструктуру из коробки, так что я написал код, сгенерировал статичный сайт с CSS, HTML, JS, положил всё это дело на CDN, завернул в WebView и радовался. И было чему: первый опыт с веб-приложениями дал такой пик посещаемости, что позже каждый product-менеджер считал своим долгом придумать что-то интересное.


    Web App #2: Putin vs Trump


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


    В следующем веб-аппе было решено проводить опросы пользователей. Разумеется, в любимом формате — на скользкие и горячие темы. Первый опрос назывался President you want, и в нём нужно было выбрать Путина или Трампа.


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


    В качестве базы данных я использовал MongoDB: API для мобильных клиентов iFunny крутился именно на данной системе, был готовый кластер, и выбор был очевиден. Express.js был выбран в качестве серверного фреймворка. Все тот же Jade (Pug) в качестве шаблонизатора, LESS в качестве препроцессора и сборка статики с помощью Gulp.


    В первые часы после запуска нового приложения проголосовало свыше миллиона пользователей. И тут произошел курьёз: сумма процентов перевалила за 100%. Не 146% конечно, рядом.


    Вместо того чтобы использовать стандартный инкремент из базы данных, я использовал банальное «текущее значение = текущее значение + 1». А про такое понятие, как конкурентность запросов, узнал вообще только в продакшене. Ну да, пустили слона в посудную лавку.


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


    Тот самый опрос, исправленный:


    Web App #2: Putin vs Trump


    Web App #2: Putin vs Trump


    Web App #3: Booby Bird


    Web App #3: Booby Bird


    После внушительных успехов предыдущих веб-аппов было решено запустить полноценную HTML5-игру. А так как в отделе по-прежнему работало 2 человека, разработка была поручена китайскому фрилансеру, которого нашли продакт-менеджеры.


    Парень — молодец, постарался на славу:


    • собрал игру в WYSIWYG-редакторе;
    • написал серверную часть на PHP по мануалам со StackOverflow;
    • скрепил эти части с помощью известного только ему одному клея;
    • отдал результаты в виде обфусцированных файлов.

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


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


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


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


    Web App #4: Holiday Giveaway


    Web App #4: Holiday Giveaway


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


    «Под капотом» были все те же Express.js, Jade (Pug), LESS. Ожидался большой пик посещаемости, и в качестве базы данных я использовал отдельный кластер MongoDB. И даже провел нагрузочное тестирование, чтобы вот в этот раз все точно получилось как надо. Ну, вы понимаете.


    Веб-апп показал отличные результаты: около 3 миллионов участников уже в первом туре. Вот только вместе с успехом пришли и трудности.


    Сначала проблема возникла в связке NGINX и PM2, который использовался для управления инстансами приложения. Мне искренне было страшно, я вообще не понимал, что делать: HTML5, CSS, JS, а тут какие-то таймвейты в сети, озадаченные DevOps-инженеры и молчаливый требовательный взгляд технического директора. Спустя некоторое время проблема была устранена, а до следующего розыгрыша призов был запас времени. Я наивно начал полагать, что теперь всё хорошо, отмучился.


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


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


    Такие жертвы были оправданы: спустя 24 часа у веб-аппа было более 12 миллионов просмотров, тысячи комментариев и большой шум по социальным сетям. Пользователи сильно взбудоражились: им определённо понравилось приложение. Да и мне понравилось, что скрывать.


    Минусы и плюсы веб-аппов


    Минусы:


    • много слез было пролито с «Самсунгами», потому что WebView — это дефолтный браузер, а «Самсунги» очень любят все кастомизировать. И если десктопные браузеры, мобильные Chrome и Safari отображали веб-апп корректно, то у «Самсунгов» обязательно что-нибудь разносило. Эта марка очень популярна в США, приходилось чинить;
    • после того как были устранены все проблемы отображения могло оказаться, что приложение некорректно работало в боевых условиях. И причина была банальной: если при сборке мобильного приложения забыли поставить пару галочек — и раз! — скролл в WebView уже не работал как надо. А это, скорее всего, новый релиз и минимум несколько дней отложенного запуска.

    Плюсы:


    • быстро. Среднее время разработки — две недели. Первая неделя — активная разработка, вторая — тесты, фиксы и доработка;
    • дёшево. Экономия стоимости разработки огромная. Веб-апп может создать один фронтенд-разработчик для всех платформ. Дорогие мобильные девелоперы здесь не привлекаются. И даже если привлекаются, то редко и мало.
    • круто. Формат действительно можно сделать интересным для пользователей. Судя по многим показателям (количеству комментариев, регистраций, времени сессий в играх), аудитории нравится такая интерактивность. Им нравится подмечать ошибки и смаковать их, нравится ломать и улетать в баны, нравится всё это дело обсуждать. А что может быть лучше подогретого и вовлечённого сообщества для UGC-продукта?

    За период с сентября по декабрь было сделано 6 веб-аппов. И каждый из них дал хорошие результаты. «Веб-апп марафон» позволил ответить на все интересующие вопросы, в том числе на самый важный: да, это определённо стоящая тема, чтобы продолжать ей заниматься.


    Сейчас разработка веб-аппов уже поставлена на поток: за прошедший 2017 их было 94, а по количеству сессий что-то около 101 миллиона. Кстати, большую часть можно посмотреть по ссылке.


    Я же, в свою очередь, понял кое-что про работу в продуктовой компании.


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


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

    FunCorp
    287,00
    Разработка развлекательных сервисов
    Поделиться публикацией

    Похожие публикации

    Комментарии 15

      0

      Я думаю что если приложению не нужен офлайн режим, то это идеальное решение с точки зрения цена/качество.

        0
        «И причина была банальной: если при сборке мобильного приложения забыли поставить пару галочек»

        Поделитесь пожалуйста этими галочками. Как раз намедни воевал с Самсунгами и тут раз и статья в тему.
          +2
          У меня были две проблемы.
          Во-первых, мобильный клиент работал с жестами. И как следствие, частично перехватывал управление. В итоге ребята из мобильной команды внедрили в клиент механизм, который для игр вообще отключал жесты. А для всего остального проверял эту необходимость по canScrollVertically.
          Во-вторых, в самой верстке пришлось отказаться от overflow:hidden на корневых элементах. Это свойство препятствовало детектированию скролла в WebView.
            0
            Забавно, при этом весь код локально на десктопе всегда работал без запинки да? ))
              +1
              И на десктопе. И в мобильных браузерах на реальных устройствах. И в эмуляторах. Все самое интересное начиналось при открытии в WebView. Мы даже тестовые веб-аппы делали только для проверки возможностей в реальных мобильных клиентах.
                0
                Сейчас для решения своих проблем копаюсь в интернете, и тут я вспомнил, а ведь есть такая штука как Crosswalk WebView Cordova Plugin (правда она для вас не подходит, а для меня в самый раз). Плагин тянет себе в apk свою версию хрома, увеличивая размер apk на 17 Мб, а размер установленного приложения на 50 Мб. Да крутой такой оверхед, но если задумываться о цене поиска и исправления всех будущих багов и глюков, то возможно можно и пожертвовать.

                Хотя это такое себе решение, если все дружно так будут делать то общий оверхед зашкалит.

                Возглас в пустоту: Ну почему тюнинговщики Андроида такие зас***цы и что-то там химичат со встроенным браузером (( Думаешь ну вот оно наступило счастье можно быстро и дешево делать приложения для мобильных устройств и тут такая подлянка.
          0
          10к RPS? А какого рода запросы (статика? динамика)? Бэк — нода? Это пик запросов или среднее значение (медиана?)? Если это относительно постоянная нагрузка, то как долго держится и на каком железе?
            +1
            10К — это пиковое значение. Все запросы — динамические. Северная часть была написана на Node.js с использованием фреймворка Express.js. В качестве железа выступила пара инстансов Amazon EC2. Наибольшую нагрузку приложение получило сразу после публикации в основной ленте работ. Это вообще особенность всех наших веб-аппов — ощутимые нагрузки сразу же после публикации. И спокойная размеренная жизнь спустя пару часов.
              0
              А сколько длиться пик? И сколько это в RPS при размеренной жизни?
                0
                Пик длится 10-15 минут. Затем нагрузка плавно падает: пользователи смотрят контент и идут к следующему. К концу суток веб-апп стоит практически без нагрузки (менее 50 RPS).
            0
            А использовали cordova, ionic или что-то такое?
              0
              Вот как раз с cordova сейчас воюю.

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

              Непонятные глюки были на самсунгах (Android 6), приложение подгружало первый скрипт с сервера но не выполняла его, хотя стояло событие на выполнение кода после полной загрузки скрипта. Порешал поставив таймаут в 2 секунды перед запуском кода загруженного скрипта, проблема исчезла.

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

              При этом весь код без проблем работает на десктопе в браузере Хром, вообще никаких глюков.

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

              P.S. В качестве фронта использую Framework7
                0
                Нет. Для наших задач эти решения были избыточны.
                  0
                  А чем вы тогда упаковывали приложения в WebView, своими силами через нативный код стандартными средствами разработки платформы Android, iOS?
                    0
                    iFunny — нативный клиент. Поэтому все делалось стандартными средствами.

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