b div>
c div>
div>
<% } %>
...берет на свой разворот примерно 1,5-2 секунды. Полностью идентичный разворот HTML на ультрасовременном ReactJS с элементами искусственного интеллекта обновления DOM занимает 12 секунд. Это с учетом того, что React разворачивает его только один раз, а остальные 99 - вообще пытается не трогать DOM. Из соображений тонкой оптимизации.
React имеет репутацию невероятно быстрого фреймворка, настолько, что отдельные коллеги вставляют его в приложение на AngularJS, "для ускорения рендеринга". Ви таки будете смеятся, да.
Из сходу плохого про бэкбон мы можем сказать то, что в своем исходном виде он не дает совсем никаких сервисов, облегчащих разработчику жизнь. Он дает правила, но почти никак не вознаграждает за следование им. Это почти голая дисциплина. И вот здесь начинается самое интересное. Что же это за сервисы такие? А я вам скажу - их отсутствие очень просто определить в любом фреймворке. Обратите внимание на две простых вещи:
- В чем люди регулярно ошибаются?
- Каким из хороших практик люди по факту предпочитают не следовать?
То есть, посмотрите на распространенные ошибки, включая ошибки дизайна, и вы сразу увидите слабые стороны фреймворка. Вы можете сказать - ну и что, эти люди просто недостаточно дисциплинированы и умны для него.
Я вам отвечу - это плохая архитектура, для следования которой надо изменять человеческую природу. Люди по природе не любят прикладывать ум для простейших бытовых ситуаций, и не любят дисциплины. Особенно, глупой дисциплины, не имеющей за собой действительно веской причины. А ваш фреймворк - это не веская причина. Смиритесь с этим.
Итак, к чему у нас склонны люди, работая с backbone.
- По разному разворачивают шаблон во View, кто куда горазд.
- По разному подключают subview, и вообще, это делается настолько тяжеловесно, что они предпочитают по возможности не делать subview, раздувая шаблон.
- В шаблоне, постоянно забывают писать model.get( 'name' ), пишут model.name.
- И не в шаблоне - тоже постоянно путаются, и делают присваивания вместо вызовов model.set( 'attr', value );
- В моделях - не пишут defaults для атрибутов. Ленятся. В итоге, понять, что на самом деле лежит в модели, и что туда попадает во время работы программы - практически невозможно.
- В атрибуте, который содержит массив или объект, меняют что-то, и удивляются, почему не обновился View. А модель не замечает глубоких изменений атрибутов. И не должна. Она замечает только model.set
- Не понимают, как им работать с атрибутами типа Date. С ними творится АД, который слишком красочен, чтобы описать его в рамках данной статьи.
Это не полный список. Я, собственно, только начал. Вопросов у команды, начавшей работать с backbone, возникает слишком много. Давайте, руководствуясь критериями, обозначенными в предыдущих статьях, выделим две главные проблемы:
- В Backbone отсутствует рекурсивный паттерн для View. Нет стандартного способа, как сделать View состоящее из других View.
- В Backbone отсутствует рекурсивный паттерн для Model. Нет стандартного способа, как включать другие модели и сложные объекты типа Date в качестве атрибутов.
Без этих двух рекурсивных паттернов, ничего сложного вы с Backbone не сделаете.
Авторы backbone честно и гордо ответят вам - парни, у нас unopinionated framework. Он дает вам свободу. Вы вольны сами решать, какие у вас будут на них ответы. И они правы. По сути, BackboneJS дает слишком слабые правила, чтобы упорядочить групповую разработку. Это конструктор, основа для конкретных фреймворков, которые вы собираете сами, из Backbone, и его расширений, дополняя это своими правилами.
То есть, Backbone сам по себе - это не ответ на вопрос, как делать браузерные приложения. С ним одним приложения сделать нельзя. Это не инструмент команды, а инструмент архитектора.
Трагизм ситуации в том, что каждый член команды, брошенный на произвол судьбы, отвечает на эти вопросы по своему. В итоге, получившийся код неподдерживаемый, и читать его совершенно невозможно.
Этого ни один вменяемый архитектор допустить не может. Поэтому, появились Chaplin и Marionette. Эти две штуковины - два варианта, как сделать из Backbone более-менее сносный фреймворк, который имеет свое мнение по части ответов на вопросы выше.
Они оба внятно отвечают на вопрос, как будет структурировано ваше приложение, а также, оба содержат в меру простой паттерн для подключения subview. Однако, оба не дают вложенных моделей и коллекций. Вам предлагается искать для них свое решение.
Год назад я был сильно удручен этими другими решениями, и поэтому мы сделали свое (Backbone.NestedTypes). Это хорошая система моделей, по своим возможностям на данный момент перекрывающая не только остальные плагины Backbone, но и системы моделей близких по идеологии фреймворков, таких как EmberJS. Кстати, знаете, например, что model.set в моделях NestedTypes в десятки раз быстрее в Chrome, в сравнении с моделями Backbone? Нет, это не NestedTypes быстр. Это Backbone-модели чудовищно тормозны.
Однако, дело сейчас не в них - давайте просто будем считать, что с моделями никаких проблем нет. И не в databinding - он для backbone также есть в виде плагинов, если вы захотите.
Сейчас я опишу комплекс проблем, нивелирующих основное преимещество Backbone, с которого мы начали - высокую скорость рендеринга UI. И с ней, в отличии от моделей, ничего поделать нельзя. Для этого нам надо будет углубиться в частные случаи, но иначе будет непонятно, в чем общая проблема. Так что приготовьтесь, оно того стоит.
Давайте предположим, что наш UI дизайнер хочет скругленные углы у элементов форм. Понятное желание, человеческое. Проблема только в том, что IE10 не откликается на соответствующий CSS-стиль. И еще, он хочет заменить уродливый скроллбар в элементе select на красивый. И чекбоксы он хочет тоже свои.
В общем, нет проблем. input надо обернуть в div, и уже этому div скруглить элементы. Сразу возникает проблема с фокусом - он хочет, чтобы элемент подсвечивался рамкой, ну ок - это делается неким глобальным скриптом. Главное для вас, как разработчика, в том, что с этого момента вы уже не можете просто писать input, а должны вставлять на его месте нетривияльный HTML.
То же самое с checkbox - вместо простого input вы должны вставлять некий непростой HTML определенной структуры.
И совсем плохо с select, в котором мы хотим подменить скроллбар и цвет фона. Это адово непростой HTML, который уже затруднительно вставлять в шаблон, и которому нужен продвинутый JS.
Если вы будете применять для каждого такого контрола backbone subview (а subview делать все еще достаточно напряжно в том числе и с Chaplin и Marionette) - вы застрелитесь на второй день. Разработчики ошибаются. Нечеловеческая дисциплина. Не вариант. И вы ищете выход.
Выход называется Web Components, позволяющий определять свои HTML-тэги. Но это новый стандарт, который браузерамм не поддерживается, и поэтому, вы находите Polymer, и чуть позже - x-tag. Та-да!
И тут вы вдруг понимаете, что ваши кастомные тэги разворачиваются асинхронно. То есть, после render, они не готовы к работе. Ну не беда, вы заменяете innerHTML на xtags.innerHTML, чтобы избежать race conditions. Та-да!
И вообще, эти Polymer - это очень модно. Вы на острие технологии. Круто. Та-да!
Только штука в том, что эти кастомные теги разворачиваются DOM-манипуляцией. И это происходит ацки медленно. На самом деле, вы получите скорость рендеринга хуже, чем в модных медленных фреймворках. Она будет настолько медленной, что вы будете замечать это невооруженным глазом. Упс.
Если проблему обобщить, то...
рекурсивный паттерн для subview в Backbone крайне неудобен на микроуровне, что не позволяет вам сделать библиотеку виджетов
А также...
применение Web Components приводит к деградации производительности, нивелируя единственное неоспоримое преимущество Backbone - скорость рендерига
И даже если бы нет, то...
работая в рамках шаблона, вы не можете передавать custom tags сложные объекты, например - модель
Только через текст. Что идиотизм, и очень сильно ограничивает вас в возможностях.
Другими словами, рекурсивный паттерн subview, в условиях того, что view состоит из текстового шаблона и подключения subview на javascipt - крайне неудобен, и значительно усложняет проектирование
Сейчас мы могли бы рассмотреть AngularJS. Но есть одно обстоятельство, которое освобождает нас от необходимости это делать. Дело в том, что уже анонсирован Angular 2.0, который будет обратно не совместим с Angular 1.x, а посему - мало кто в отважится сейчас начинать проект на Angular.
Но если вы настаиваете - в Angular ситуация чуть лучше, так как вы можете определять "директивы", однако наличествует разница между "контроллером" и "директивой", и элемент UI так же расщеплен на HTML и JS. При этом, полностью отсутствует сервис моделей. Как и принципиальное преимущество перед Backbone, которое бы заставило вас выкинуть написанный с ним код. Two-way databinding им не является, он несложно делается и в backbone.
Поэтому, мы рассмотрим Ember, ExtJS, и React. Все они решают обозначенную проблему. Каждый по своему.
архитектура ПО,
extjs,
reactjs,
javascript,
angularjs,
backbonejs