Приложение VK Offline: история создания и переход в Open Source

В рамках акции для разработчиков представляем статью от автора приложения VK Offline. 

Приложение VK Offline появилось в Chrome Web Store в августе 2011 года и за прошедшие полтора года превратилось из прототипа, представленного на Chrome-хакатоне в Питере, в полноценное (и теперь уже legacy) приложение для Google Chrome. Сегодня я выпускаю VK Offline 4.7 и отдаю его в сообщество разработчиков на github как opensource продукт.

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

Этапы разработки VK Offline

Начиналось все в конце лета 2011. Я активно изучал javascript и написание расширений/приложений для Google Chrome показалось мне крайне интересным. Хакатон, организованный питерской командой GTUG пришелся как нельзя кстати, а приглашенный эксперт Mike West из Google только укрепил веру в свои возможности. Две недели после хакатона я активно пилил приложение, попутно обсуждая главные его части с друзьями.

[offtopic] Оглядываясь назад, я считаю, что этот выбор был определяюще верным. Выбирая разработку расширений/приложений для Chrome, вы получаете потрясающее и классное API, самые современные веб-технологии, а также тот самый javascript-экспириенс, который трудно получить при разработке сайтов. Не бойтесь трудностей, которые возникнут у вас на этом пути. [/offtopic]

VK Offline 1.0

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

После хакатона и конкурса я встроил функционал Google Voice Search в приложение. Мне до сих пор кажется, что это одно из самых интересных мест в приложении, хотя с точки зрения кода работает он не совсем тривиально. Затем я уже долго допиливал производительность приложения, ускорял скорость первой синхронизации, оптимизируя код внесения писем в WebDatabase.

Революцией стал выпуск 4 версии приложения, в которой полностью поменялась структура БД и пришлось писать сложную систему миграции пользователей 3 версии приложения на 4. Отлаживать это было очень тяжело, и при обновлении приложения все равно обнаружилось, что я не учел какие-то моменты, что сказалось на количестве пользователей приложения (сократилось с 30К до 22К). Главным же в 4 версии стало то, что изменился интерфейс, и по сути приложение получило свой нынешний вид с папками, real-time диалогами, вложениями с поддержкой drag-n-drop и др. Дальнейшая работа была уже над вылизыванием мелочей и исправлением утечек памяти.

Синхронизация в VK Offline

VK Offline v4

В версии 4.7 стали показываться аватарки друзей, которые исчезли после переезда статики ВКонтакте на другой домен. Также была исправлена ошибка с частым показом окон напоминания о ДР, и по просьбам стали поддерживаться emoji-картинки. Внутри же был произведен переход на шаблонизатор Hogan.js, а прототипы DOM-объектов перестали активно загрязняться, что должно улучшить производительность приложения.

Что было важно

Метрики. Когда все начиналось, была мысль только о том, что нужно фигачить код. Я рассматривал количество пользователей в Chrome Web Store как главную метрику и был доволен. Но когда приложение стало обрастать функционалом, стало интересно знать, пользуются ли люди им или нет. Так в приложении появились кастомные ивенты от Google Analytics и Яндекс.Метрики, о которых я рассказывал на DevFest. И именно по ним я стал ориентироваться при дальнейшем внедрении и изменении функциональности приложения. Для интереса: в день генерируется порядка 5М событий, по которым можно судить о работе приложения.

Статистика VK Offline

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

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

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

Обратная связь. Для обратной связи в 4 версии приложения я сделал отдельную форму, которая при отправке спрашивала разрешения пользователя к chrome.management.* API. Это позволило вместе с логом ошибок отправлять список установленных расширений. Несмотря на ограничения песочницы, за ее пределами часто возникали проблемы доступа к OAuth-авторизации.

Запрос прав в VK Offline

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

DevFest. Кстати в ноябре на DevFest 2012 я рассказывал о многих вещах, с которыми столкнулся при разработке. Я очень советую вам потратить 20 минут времени, и не повторять ошибки, которые вы повторите, если не потратите 20 минут времени... Ну вы поняли :)

Уже в процессе разработки концепция приложения переросла в "E-mail клиент и адресная книга на основе ваших данных ВКонтакте". Но на момент начала это был скорее бэкап ваших данных в приложении для Chrome. В нем не было поддержки real-time диалогов, вложений, да и многие другие вещи были написаны почти на коленке. Сейчас все стало сравнительно неплохо, хотя мне все равно стыдно за многие части кода. Но перфекционизм не всегда лучший союзник. И кстати о коде.

Техническая часть VK Offline

i18n

Локализации в приложении изначально не было и пришлось достаточно много повозиться, вставляя ее в код. В процессе допиливания я пришел к решению, когда вся локализация хранится в одном файле i18n/locales.json, а затем при сборке разносится по файлам локалей _locales/%locale%/messages.json. Сборка локалей осуществляется командой grunt i18n.

Шаблоны и шаблонизатор

Это достаточно смешно, но до версии 4.7 весь UI отрисовывался с помощью document.createElement()/element.appendChild() итд. Теперь VK Offline использует mustache-шаблоны и шаблонизатор hogan.js от Twitter. Сборка шаблонов осуществляется командой grunt templates. Шаблоны хранятся в папке templates.

DOM Traversing

Я изначально был противником встраивания jQuery в код проекта. Он достаточно большой, да и все проверки на браузер совсем не нужны. Поэтому для DOM Traversing я использую js/dom.js, который написан на основе библиотеки DOM5. Общая идея заключается в том, что в в прототип Element подмешивается кастомный объект, позволяющий манипулировать DOM-элементами более удобно и просто.

Grunt

Grunt используется для сборки локализаций, шаблонов и релизов (grunt release).

Background page (backend.js)

Это ядро приложения, его фоновая страница и постоянно работающий код. К нему обращаются табы приложения, и он рассылает им информацию о том, что что-то изменилось. Одни из самых важных объектов в нем: mailSync (синхронизация сообщений), friendsSync (синхронизация списка друзей) и longPollEventsRegistrar (real-time диалоги).

Работа с БД (databaseManager.js)

Огромная череда методов, которые экспортирует DatabaseManager. К каждому методу написан подробный jsDoc, так что при использовании проблем возникнуть не должно.

Миграция при обновлении (migrationManager.js)

Скрипты миграции находятся в массиве migrateData, который содержит названия версий и таски, которые необходимо выполнить при миграции с более низкой версии приложения на эту и выше. Таски выполняются поэтапно. Сам MigrationManager экспортирует только один метод - start, а в callback передает код результата окончания процесса миграции.

Запросы к API ВКонтакте (reqManager.js)

Все запросы к API делаются через ReqManager. Он следит за повисшей сетью, неудачными ответами и пр. Экспортируемые методы: apiMethod, forceUrlGet, abort и abortAll.

Настройки (settingsManager.js)

Настройки хранятся в LocalStorage, но для более простой работы с ними существует SettingsManager, который позволяет получить значение настройки через вызов SettingsManager[key] и записать новое значение настройки с проверкой с помощью SettingsManager[key] = value.

Работа со звуком (soundManager.js)

Звук может работать через Web Audio API, а если он недоступен, то через HTML5 Audio. SoundManager следит за доступными API и воспроизводит звук через доступный интерфейс. Единственный экспортируемый метод - play.

Работа с LocalStorage (storageManager.js)

Как известно, LocalStorage это топорный key-value, который при сохранении данных преобразует их в строки. Но поскольку разработка приложения начиналась тогда, когда chrome.storage еще не существовал, приходилось писать свою обертку над LocalStorage для более удобной работы. Экспортирует методы set, get и remove. Метод get помимо всего позволяет производить минапуляции над данными и получать их ровно в том виде, в котором предполагается их хранение.

Отрисовка (ui.js)

К сожалению, многие части ui.js остались со времен VK Offline 2/3, поэтому он достаточно объемный. Может быть стоило использовать backbone.js или что-то другое, а не городить свои велосипеды из full/partial views. С другой стороны такой подход позволяет достаточно гибко перерисовывать части интерфейса, не трогая другие.

Это еще не конец (не просолился сознания огурец)

Для пользователей все это означает, что дальнейшее развитие приложения VK Offline будет продолжаться силами сторонних разработчиков. Если вы javascript-программист и хотите продолжить развитие этого проекта, то список возможных улучшений и задач вы можете посмотреть здесь.

Чтобы быть до конца честным - я вижу развитие VK Offline в качестве не legacy packaged app, но для этого нужны или огромная куча времени, или прямое сотрудничество с ВКонтакте. К сожалению ни того, ни другого у меня нет. С другой стороны я помню о том, что знаниями нужно делиться, а не хвастаться, поэтому если кому-то пригодится мой опыт, будет круто. Это еще не конец :)

Автор: +Dmitry Sorin

P.S. Ссылка на приложение в Chrome Web Store.

  • Ну почему меньшинство? Аудиозаписи на сайте — это далеко не самый востребованный раздел.

  • stay_positive

    Еще один советчик :)
    ВК ввели важные сообщения да. Через год после того, как они появились в VK Offline. Что еще раз доказывает, что везде есть своя ниша.

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

  • Ikariam

    Собственно с пеной у рта доказывать, как круто ваше детище — это слишком. Да, вы вложили много усилий. Но вложили их в изобретение велосипеда. Почему? Потому что я захожу 1 раз в настройки вк, ставлю галочки напротив «аудиозаписи» и «диалоги». И кроме переписки и музыки меня ничего больше не отвлекает. Важные сообщения уже ввел сам вк. Перерабатывайте в нечто большее, или проект умрет :))

  • Ilya Gorokhov

    Okey glass. Take a VK message.

  • Dmitry Sorin

    Рад, что оказалось полезно.

  • edencore

    Спасибо за пост и выступление на GDG :)
    ВК не пользуюсь, но все равно прочитал с большим интересом и пользой. Получил ответы на некоторые терзающие меня вопросы.

  • hierophant

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

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

    Если свободный продукт становится хорошим — мы его просто возьмём. Выдающаяся вещь в идее открытого программного обеспечения в том, что никто не владеет им — любая компания, например, Oracle, может просто взять его забесплатно, включить в свои продукты и брать с заказчиков деньги за поддержку, что мы и делаем. И это никому не вредит — вы всего лишь должны найти способы добавления стоимости. Как только открытый продукт становится хорошим — конкурировать с ним становится безумием. Мы не должны воевать со свободным программным обеспечением, мы должны его эксплуатировать. — Интервью Financial Times, 18 апреля 2006 — Ларри Эллисон глава Oracle.

    ЗАДУМАЙТЕСЬ!

  • Сергей Марков

    Думаю, основной целевой аудиторией станут пользователи хром буков, хотя если быть честным, qip просто убожество, далеко не каждый захочет им пользоваться. А хорошие клиенты, такие, как pidgin например, не умеют синхронизировать историю с вконтактом по понятным причинам (плюс есть еще некоторые минусы и нарекания благодаря кривой реализации xmpp со стороны контакта, хотя в целом все работает сносно). Да и не уверен, что квип то умеет.

  • anton9121

    1. статистика маленькая.
    2. то что вы воткнули в bg страницу гугл аналитикс это я считаю плохо.
    3. серверная в смыле это bg страница. Которая и оповещает о нотификациях.
    4. Не джабером единым. iMessage вполне не плох, честно. Да и qip в виндах должен справиться со своей кучей плагинов.
    5. Это все не нужно. =)

  • Dmitry Sorin

    Обсуждать тут нечего — вам не нужно, 52К пользователям оказалось нужно. Статистика real-time пользователей приложения тоже говорит за себя: http://d.pr/i/dh72

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

    Если вы думаете, что вам это все не нужно, то скорее всего вы живете в центре Москвы и у вас никогда не отключалось электричество и интернет.

  • anton9121

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

  • Dmitry Sorin

    Конечно страшно, но я постараюсь не устраняться полностью и активно участвовать в разрешении и обсуждении issues проекта.

  • Migman

    читает

  • Сергей Марков

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

  • топик добра