Pull to refresh

Comments 387

AngularJS с его замысловатым способо организовывать директивы (за него уже извинились) — это меньшее из зол на сегодня.

В сложных приложениях, как раз при помощи DI главным образом, датабиндингами (не нравятся двусторонние — используетй one-time) количество проблем сокращается драматически по сравнению с классикой в виде jQuery. ReactJS упрощает биндинг не касаясь другого.

Все якобы недостаки говорят только о том, что «вы просто не умеете его готовить» =)

> ЭТО ПЕРЕСТАЕТ РАБОТАТЬ ПРИ МИНИФИКАЦИИ КОДА.
npm install ng-annotate

>УБРАВ ВОЗМОЖНОСТЬ НАСЛЕДОВАНИЯ СКОПОВ
Не доконца ясно зачем, но хочется не наследовать — создайте изолированный scope.

>ОШИБКИ В БИНДИНГАХ ВООБЩЕ НЕ ВЫЛЕТАЮТ
Это позволяет в большинстве случаев игнорировать undefined и null — меньше кода — лучше читаемость.
Если очень хочется и у вас почему-то сложные выражание — отлаживайте

>Проблемы с людьми
Нужен только человек с хорошим Javascript — остальное налаживается за пару недель интенсива.

И далее по списку.
ng-annotate — это не решение проблемы, это чистой воды костыль. Вместо того, что бы сделать так, что бы все работало без плагинов (и это легко выполнимо), придумывается плагин, который исправляет косяки.

Наследование скопов — катастрофически вредно для юнит-тестирования, и порождает большие сложности из-за прототипного наследования. Плюсов от наследования скопов никаких не вижу.

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

function.$inject = ['$scope']? На практике ng-annotate справляется с этим наура самостоятельно. Меньше кода — лучше читаемость.

Плюсов от прототипного наследования никаких не вижу.

Зачем теоретизировать. Вы постройте нормальное приложение то со вложенными контроллерами, директивами и далее. И увидите.
UFO just landed and posted this here
UFO just landed and posted this here
Хм, а что именно в ангуляре требует сервера на ноде? Всё работает и без неё. Примеров полно даже в официальной страничке примеров, если по ним погулять, можно найти много на руби или просто статике, есть даже на c#.
Человек имеет ввиду: как сборка фронтенда относится непосредственно к реализации бэкенда. Ответ — никак. Просто в ноде больше всего инструментов для этого было разработано.
Большая часть всяких шаблонизаторов, препроцессоров и систем сборки фронтенда была реализована на node.js и ruby. Так просто исторически сложилось. Я тоже хотел бы прикрутить сборку к своему Play2 или golang'у (python не годится для масштабируемых реактивных приложений с push-нотификациями, и без костылей типа celery или микросервисных архитектур, а «прости-Господи» РНР вообще ужасен), к сожалению сущесвтующие решения на ноде очень сильно обгоняют всё остальное по функционалу. Вот мой немного кривой gulp-seed для примера. В случае с ангуляром так ещё есть перепаковка всех шаблонов в один большой js файлик который сразу ложится в кэш браузера при загрузке приложения, и другие довольно полезные вещи. А ещё я люблю писать шаблоны под Angular на jade, а вёрстку в Stylus, и получается целая вязка бубликов. В принципе фронтэнд, есть фронтенд — он просто кушает RESTful API и на сервере ничего не рендерится, и абсолютно всеравно на чём этот сервер будет написан — сборка фронта нам просто отдаст кучу больших файликов с ещё большей кучи мелких, и спрайты упакует, и векторные иконочные шрифты соберёт, и вектор под каждую плотность экрана растерезирует. Для того что бы не было проблем с SEO — просто прикручивают prerender.io, но я не поощряю такого подхода. Гораздо проще гонять тот же react прямо в node.js без каких либо заморочек с webkit'ом. Также gulp асинхронен без лишних побочных эффектов если его правильно готовить, и в нём есть возможность LiveReload'a.
UFO just landed and posted this here
Ну вот далеко не всегда
UFO just landed and posted this here
Gulp с Livereload'ом и асинхронным building pipeline'ом намного веселее. И в него тоже можно интегрировать YUI.
А как вы предлагаете сделать так, чтобы все работало без «плагинов»?
Если не хочется наследования — существует «controller as» синтаксис. А плюсом является доступ из контроллера к scope парентовых контроллеров без директив и всяческих $parent
Извините, но ваша статья похожа на «заметки белок истеричек». Невозможно читать.

что это как не помещение логики в представление

Вы говорите как должны выглядеть данные, которые передали в слой view. Это логика отображения, а не бизнес логика, все на своих местах.
Кстати, если она становится сложной, то её всегда можно поместить в функции.
Кстати да, так часто люди принимают за любой код в представлении — бизнес-логику, что страшно.

Позволю дополнить примером:

<div onclick="DB.query('update table1 set field1 = 1 where field2=2')"></div>


Вот это смешение бизнес-логики и представления.

<div onclick="this.style.top='1px;'"></div>


Это смешение императивного и декларативного кода, но все это касается только представления.
Приведу пример типичного шаблона для twig/jinja2 и такой же для angular.

{% for item in list %}
<div class="item {% if item.draft %} item--draft {%endif %}">
    {{ item }}
</div>
{% endfor %}


и

<div class="item"
        ng-repeat="item in letter.list"
        ng-class="{'item--draft': item.draft}"
>
    {{ item }}
</div>


Мне порой кажется просто что люди не понимают что это не HTML а XML-based синтаксис шаблонов и только. Там нет никакой ереси типа onclick и т.д. Так же согласен что люди частенько любую логику воспринимают именно как бизнес-логику.

Вообще порекомендую автору статьи подышать свежим воздухом и вглянуть на Angular2 где уже даже сейчас видно что была проделана неплохая работа над ошибками. Да даже если брать Angular1.3 и Angular 1.1 разница чувствуется.
Они очень много переделали в Angular2 как я посмотрю. Это означает, что даже разработчики фреймворка в какой-то степени понимают что были большие ошибки.
UFO just landed and posted this here
Нужно понимать, что React хранит и предполагает получение View-Model состояния с сторонних источников, с последующим вызовом обработчиков для перестройки VirtualDom дерева, и по другому это просто нереализуемо. Другие шаблонизаторы будут тупо оперерировать пустым HTML — создавать бешеный overhead на перерисовки и его разбор, и Angular тоже не исключение. Поэтому появляются такие странные вещи как ngReact :x Вьюхи не генерятся кусками — они формируют дерево компонент со своими состояниями, это может быть и непривычно и я сам не поощряю такой дизайн, но сделано чисто для реюзабельности и простоты работы с DOM деревом.
UFO just landed and posted this here
Адепты гуглополимеров с вами не согласны.
Не дизайнер, а верстальщик… дизайнерам вообще не положено лезть в вёрстку.
Верстальщику не составит особо проблем разобраться с компонентами, да и кто сказал что он увидит слишком большую разницу между HTML и JS с React компонентами. Эт только заядлые ригидные фанатики будут материться, а для всех остальных — обучится чему-то новому счастье.
Причем тут дизайнер и HTML? Пусть фронтендом занимается фронтенд-разработчик, который умеет все, что нужно.

Вообще react все правильно делает, используя pure js. Они не создают лишних сущностей в виде yet another template language, в отличие от всех остальных. Свой язык шаблонов — это дичайший оверхед на всех уровнях, и, что самое смешное, в итоге он скомпилируется в тот самый JS.
И к тому же, вот вы задумайтесь, долго вы учили директивы angular-а, отдельный кривой и убогий язык? А тут уже всем знакомый JS, отвратительный, но знакомый, более того, прекрасно отлаживаемый на лету.
Как ни странно — все как раз наоборот. Это по собственному опыту где-то на 150 KOC с помощью React+Backbone.

React отвечает только за представление. Используется JSX (с препроцессором, понятно), который похож на HTML, но не совсем. Так как все бьется по компонентам, в большинстве случаев получается древовидная иерархия (а не граф), что хорошо влияет на структуру проекта. Ну а поскольку все в изолированных компонентах — их легко тестировать. Очень легко.

Добавляем backbone (модели+роутинг), require для зависимостей, etc и получаем отличный фреймворк под свои задачи.

У нас есть верстальщик, который максимум что может это подключить плагинчик jQuery. Т.е. не программист вообще. Но вот HTML пишет хорошо. И его получилось очень быстро обучить следующему алгоритму:

1. Делает обычную HTML верстку для страницы включая CSS
2. Он связывается с фронтендщиком, они обговаривают логическую иерархию компонент (как бить кусок HTML на части)
3. Разбивает свою же верстку на компоненты в соответствии с иерархией и отдает фронтендщику без логики
4. Фронтендщик добавлет логику

Так вот, я хочу сказать что конвеер отлично работает. Код остается читабельный — находить ошибки очень легко, учитывая доступный плагин для Chrome Dev Tools. Из за иерархии компонент можно легко найти что за что отвечает. Без каши из scope, без отдельного DSL для шаблонов (JSX не считается — он только теги оборачивает, все остальное в JS). И самое главное — приложение все же пишет программист, который понимает что такое производительность, качество кода и тестируемость.

Думаю следующий вопрос — а как это все поддерживать? Да очень просто. Если изменения небольшие (CSS класс добавить, например) — это может сделать и верстальщик. Если что-то больше, то смотри пункты выше.

И что я хочу добавить, после 50 KLOC проекта на AngularJS — React это просто чудо.
Расскажите про опыт: как оно React + backbone. Как правильно разделять их, что бы потом не плакать?

Какие есть практики для динамического апдейта данных с сервера?

Вот мне приезжают данные из вебсокета: мне правильнее на уровне бекбона вмерживать апдейты в имеющуюся структуру или просто пересоздавать всё и отдавать потом результат на рендеринг в реакт?

Если вопросы некорректные, то буду рад, если поправите.
Там автор начал за здравие (о различиях интерактивного и реактивного программирования), а кончил как обычно (написал интерактивный велосипед, обозвав его внезапно реактивным)
Backbone и React живут параллельно. От Backbone мы используем Collection, Model и Router.

Архитектура приложения типовая three-tier: сверху у нас UI, по середине слой Business Logic, снизу Data Access). Компоненты React просят что-то у BL, тот считает или просит у DA.

Да, у нас тоже есть realtime update — сервер может что-то пушнуть. Сделано через обычный shared state (который спрятан в BL). Компонента React подписывается и когда что-то приходит — ее уведомляют. Построено поверх событий Backbone. В нашем конкретном случае модели для обновлений не используются — сообщения обрабатываются в BL и передаются отдельными объектами.

А вот если нужно хранить историю (например список текущих уведомлений, который глобален для клиента) — то коллекция как синглтон и подписка на ее события. Как только добавляется новое событие (будь то результат AJAX запроса или пришло из вебсокета или кто-то из UI убрал) — подписчики об этом узнают. И да, детали спрятаны в BL и для этого всего есть нормальный API.

Для всяких AJAX запросов — обычные коллекции и модели Backbone. Для React написан небольшой mixin, который умеет слушать .change() события для моделей (и автоматически отписываться если уходит из Virtual DOM) за счет чего получается реактивность.

Ну и насчет вопроса про пересоздавать. Если кратко — React вообще все равно что за данные и откуда они приходят. Если более развернуто: React ожидает что метод render() вернет дерево компонент. Каждый раз — целое дерево компонент. В идеале, render() это чистая функция от аргументов компоненты и внутреннего состояния компоненты.

В связи с этим, если надо отрисовать массив из 10 элементов, внутри которого меняется только 1 элемент, render() каждый раз будет возвращать все 10. И React уже сравнивает что именно поменялось, по сравнению с предидущей версией DOM и обновляет только то что нужно. А, поскольку, виртуальный DOM это просто структуры данных JS, то работает это все достаточно быстро. Это совершенно не отличается от подхода в том-же AngularJS, разве что более явно (с соответствующими плюсами, так как можно оптимизировать).
Слушайте, а если есть о чем написать, может, сможете поделиться опытом в виде поста на Хабр? Очень интересны нюансы реализации.
Дополнил немного статью: это невозможно тестировать юнит-тестами, невозможно продебажить, оттуда не кидаются ошибки и при добавлении большего количества логики в onclick он значительно усложнится для чтения.

По поводу ошибки в термине — суть не в том, какой термин используется, а в том, что под ним подразумевается.
UFO just landed and posted this here
UFO just landed and posted this here
Ты просто слишком не конструктивно настроен. Я пишу эмоционально, но подкрепляю фактами, ты выдираешь что-либо из контекста, и агрессивно просишь меня, что-то тебе доказать. Если бы ты был более конструктивен и привел весомые доводы, я бы тебе ответил.
UFO just landed and posted this here
Вместо того чтобы друг-друга обкидывать «нубасами», грамарнаци и неконструтивом — давайте аргументы, почему тестируется/не тестируется — вас тут слушают внимательно, вы не в привате общаетесь :)
UFO just landed and posted this here
А пока что в каждом Вашем жирном капсе читается фанатичная истерика

Ага
Фактов по поводу unit-тестов Вы не привели. Необходимость дебага выражений в шаблонах больше говорит о программисте, чем об AngularJS.
Судя по статье, он совсем не полный ноль.

У нас ангуляр используется в нескольких проектах последние полтора года и в целом мы им недовольны. Сейчас новый проект переводится на Backbone и разница просто чумовая. На простейшем коде ангуляровский проект подтупливает и подлагивает.

Под подлагивает я имею ввиду ситуацю, когда на полупустом экране, в хроме страница меняется не во время нажатия мышкой, а ощутимо после отпускания мышки.

С backbone страничка меняется до того, как отпускаешь мышку.

Нет, спасибо, что-то дальше ангуляр с его скрытыми глобальными переменными в виде наследованных скоупов не очень хочется.
Да-да, я подобные аргументы видел до перехода с jQuery на ангуляр.

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


Ну вы бы что ли ссылку дали или use-case подробнее описали. Если бы такое имело место сколько-нибудь широко, Angular бы вообще никто не использовал.
Дать ссылку я вам на админку у пользователей я по понятным причинам не могу, могу дать триальный ключ к нашему стриминговому серверу и могу пояснить, как добавить 800 тестовых потоков, что бы вы увидели, как оно перестает работать на таком небольшом количестве строк.
Да вобщем-то хватит и описания: правильно я понял, что Вы одновременно отрисовываете 800 progress bar-ов с какой-то информацией для каждого элемента?
не, не прогресс бары. 800 строк в таблице, в каждой информация о потоке: время жизни, количество клиентов, битрейт и т.п.

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

В общем это как раз те случаи «100500 элементов на одной странице». Везет мне как-то на клиентов — они такое плохим UX считают. Но проблема не является непреодолимой. Причём вариантов решения больше одного. Хотя если у Вас большинство страниц такие, то AngularJS вам, похоже, ни к чему. Выбор инструмента под задачу, все же, никто не отменял.
такая страница ровно одна. Разбить эти строки как-то по-другому (постранично) не очень то получается.
В концепцию реакта отлично ложится:

1. Компонент для потока. Рисует информацию об одном потоке.
2. Нужен какой-то простой маршрутизатор сообщений. Компоненты потоков подписываются на события из этого роутера и получают «свои» обновления
3. Вебсокет клиент кидает входящие данные в роутер
4. Компоненты получают новые данные, обновляют свое состояние
5. Обновление состояния автоматически запускает render() для компоненты
6.…
7. Профит
То же самое — пришлось переписать приложение с AngularJS на Backbone+MarionetteJS. В форме с 50-100 полей получились более 7000-10000 watcher'ов, после попыток оптимизации число сократилось до 3000. При этом реакция на нажатия клавиш запаздывала на 0.5-1 секунду. Переписал на BB — всё летает, никаких тормозов. Конечно больше ручной работы, надо следить за утечками памяти.
Какие антипаттерны приводят к утечкам?
Да там не антипаттерны, просто в Backbone нужно закрывать свои view.
А для биндингов данных в полях форм вы что использовали? Расскажите пожалуйста!
Я попробовал Stickit, но он оказался не очень гибким. Перешел на Rivets.
Использовал stickit там, где он мог, сложные вещи руками. Rivets вроде смотрел, но не помню почему отказался от него.
Извините, но ваша статья похожа на «заметки белок истеричек».

Нет, не похожа. Автор выразил свое мнение. С тезисами, с аргументами, с доказательствами.
Со всем тем, чего нет у вас в комментарии.
UFO just landed and posted this here
Лучше раскажите почему вы считаете, что он неправ. И как бы вы решили эти проблемы.
UFO just landed and posted this here
Тратить своё время, чтобы рассказать ему обо всех его ошибках в Angular?

Ну вы же тратите свое время, сидя на хабре и постя неаргументированные комментарии. Комментарии (в частности) для того и нужны, чтобы указывать автору поста на его ошибки, разве нет?
UFO just landed and posted this here
Уже перелопатил и отписал ниже.
я давно ищу человека, который помог бы нам с неработающим куском кода на ангуляре, но вам я бы не хотел платить деньги.
1. Data-binding и его возможные тормоза. Простой ответ — за удобство приходится платить. Нефиг всю логику на него завязывать. Понятно, что watchCollection на тысячи элементов будет тормозить. Поэтому никого не должно удивлять, что особо критические места, возможно, придется оптимизировать ручками и без байндинга (гриды/чарты/etc). Вообще напоминает недавний пост про сборщик мусора в C#, который якобы течет и тормозит — а у автора просто-напросто объекты во второе поколение и LOH попадали очень быстро
2. DI. В JS невозможно его реализовать с использованием типов аргументов, как в нормальных языках, поэтому приходится использовать алиасы. Есть три возможных варианта использования, один из которых не дружит с минификацией или, например, с неймспейсами. Проблем с двумя другими нет. Автору только считает синтаксис уродливым. Срочно всем перестать использовать ангуляр! По поводу 5 «новых» сущностей и мучающихся людей. Тут просто сказать нечего, у некоторых этих сущностей вообще-то даже разный жизненный цикл
3. Дебагинг. Не самое приятное дело, да. Но дебагинг в среде, построенной на асинхронных событиях от браузера, вообще штука печальная
4. Наследование scope'ов. Нужно. Все в сервисы не понапихаешь, хотя бы потому, что они синглтоны. И да, 'Controller As' синтаксис. Хотфикс примера на fiddle — jsfiddle.net/1op3L9yo/253/. Вообще пример хороший, заберу в качестве задачки на собеседования с вопросом «почему так?» :)
5. Синтаксис директивы довольно сложный, да. Но как правило сокращается до scope, restrict и link. Остальное иногда пригождается. Пункт аналогичен — не пишите на Java, там стопиццот различных ключей в командной строке.
6. Проблемы с людьми — так на любой технологии эти проблемы, сильные разработчики работу долго не ищут :) Адекватные разработчики основы понимают довольно быстро, а структурированность ангуляра сильно помогает, особенно тем кто имеет опыт в бэкенде. Если лабать визитки на JQuery последние лет 5, то да, есть опасность разрыва шаблона. Но черт возьми, это же не C++!
7. Серверная шаблонизация — наверное единственный стоящий пункт здесь. Никто не мешает генерить HTML template на сервере тем же .NET'ом или каким-нибудь шаблонизатором, но мне кажется имелось в виду нечто типа isomorphic js раз уже SEO помянут. Мы эту проблему не решаем, у нас немного иной класс приложений :)
8. Документации достаточно. Если есть проблемы с тем, как и почему использовать — это не в документацию, а на амазон за литературой
Остальное по 10 раз объяснено в других комментариях.

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

Отходя от темы на 100%. Почему печальная?
Если не использовать паттерн «коллбэк в коллбэке, коллбэк погоняет» то даже как-то очень просто.
Или вы про что-то конкретное?
ну человек жалуется на то что у него стэк-трейс режется до digest-loop'а. Но он всегда будет резаться, потому что колбеки всегда будут, даже при использовании promise'ов, которые их по сути всего лишь прячут. На ответ от сервера, на банальный setTimeout чтобы отдать управление браузеру, и т.д. Пример, где «не печально» — async/await шарповые
К слову по поводу этого, есть чудная библиотечка под названием zone.js, одной из возможностью которых является построение нормальных стактрейсов.

p.s. Эта библиотечка будет использоваться в Angular2 для запуска $digest циклов (если браузер не поддерживает Object.observer то используется старый добрый дирти-чекинг)
Точку зрения понял. Что до шарпа, то нет нормального опыта и понимания, поэтому ничего не скажу.
До сих пор отсутствуют директивы для Drag and Drop событий

github.com/angular-dragdrop/angular-dragdrop
github.com/fatlinesofcode/ngDraggable

Или вы хотите сказать что такие вещи должны быть вшиты в фреймворк и быть доступны из коробки?

Когда вы пишите на ангуляре вы помещаете логику в ваш HTML

Логику представления, заметьте, где ей самое место. Если там что-то сложное то это проблема разработчика а не фреймворка. И коль уж вздумалось вам тестить UI так и пишите UI тесты (e2e тесты если быть точнее). Ну или сложную логику можно опять же инкапсулировать в директиву и покрывать быстрыми юнит тестами уже оные штуки.

Гугл не использует AngularJs для своих основных продуктов

Гугл много чего не использует из того, что было сделано его сотрудниками в свободное от работы время. И таки гугл использует на паре мелких в масштабе гугла проектов (youtube 4 psp, DoubleClick Digital Marketing)

Гугл может передумать и закрыть этот проект.

Это не проект гугла, угомонитесь. И в конце концов это не продукт. Это инструмент для разработки продуктов. Гугл поддерживает такие штуки что бы ВЫ реализовали клевый продукт, Гугл купил бы его и закрыл по вашей же логике.

UFO just landed and posted this here
Например при первой загрузке пользователь видит {{ выражения в скобочках }}

У меня создалось впечатление что автор лукавит по поводу своего опыта работы с AngularJs. Если бы вы прошли хотя бы официальный tutorial, вы бы знали как это решается. Или же вы намеренно не упомянули о директиве ng-bind и ng-bind-template, что указывает на ваше предвзятое отношение к фреймворку, и на то что вы искали к чему бы докапаться.

Конечно существует множество спорных моментов и недоработок, но технология новая и активно развивается. Писать большими буквами «НЕ ИСПОЛЬЗУЙТЕ АНГУЛЯР» выгладит глупо и по-детски. Мне эта технология помогла решить много проблем в сложных приложениях и она мне действительно очень нравится, но я не стану кричать всем «ИСПОЛЬЗУЙТЕ AngularJs, {{ваш_фреймворк}} отстой».
Если бы вы прошли хотя бы официальный tutorial, вы бы знали как это решается.
Автор пишет что решение есть, но есть один большой нюанс… Могли бы обойтись и без решения. Т.е. мы сначала создаём проблему, потом создаем её решение, и так много где в ангуляре => что-то не так в архитектуре даже если это помогает что-то решить. Собственно весь пост к этому и сводится, пусть немного истерично, но всё же. И, судя по второй версии ангуляра, разработчики angularjs об этом знают и идут верным путем, но не торопясь(по причинам описанным вами же)
Автор пишет что решение есть

Покажите мне где автор пишет о решении? Если вы имеете ввиду директиву ng-cloak, которую он упомянул, то это не решение, а затычка. Костыль, если хотите, как автор его и назвал. И если вы его используете, то с большой уверенностью могу сказать что вы уже пошли не по той дорожке. Bad practice, как говорится. Это, как я уже говорил, показывает что у автора просто недостаточный опыт.
В любом фреймворке вы найдете инструменты, которые использовать не желательно, и использование которых сигнализирует о том что вы неправильно его (фреймворк) используете.
Вполне обоснованно, а значит уместно. Для расширения кругозора и во избежании «зашеренности». Идеальных инструментов нет и все мы должны это понимать и принимать. И делать выбор в соответствии с задачей. Спасибо!
Это вы еще не пытались быть умнее фреймворка при работе с knockout.js
А поделитесь пожалуйста, с какими проблемами вы столкнулись при работе с knockout.js и как их решали?
Все беды, в общем-то, из-за желания заниматься велосипедизмом.

1. Начнем с того, что все KnockoutObservable<T>.subscribe(t => any) и KnockoutComputed имеют dispose(). Таким образом, если создавать SPA с кучей представлений, то рано или поздно память начнет течь. Поэтому приходится делать отдельно функцию, вызывающую .dispose() для всех локальных подписок и вычисляемых значений. Код начинает походить на C# или C++, где на каждый конструктор пишешь деструктор.

2. В knockout поддержка асинхронной загрузки шаблонов появилась только в версии 3.3 и, насколько мне известно, только для knockout components. Естественно, что в большом приложении грузить все .html разом файлы смысла нет. Пришлось писать свой враппер поверх template, который учитывал бы все возможные варианты(шаблон уже есть в разметке, шаблон загружается, шаблон следует загрузить, работу с with, as, data, foreach)

3. Любой более-менее сложный контрол требует простыни описания для конкретного случая. Писать в разметке по 5-10 строчек в data-bind было неинтересно, тем более, что typescript там не поддерживается, да и intellisense работает, мягко говоря, через раз. Я решил решить эту проблему возможностью вынесения кода из data-bind в отдельный файл с общим ключом привязки по строке. То есть <div data-bind=«bindId: 'myKey'» ></div>. Проблема начинается, когда через этот bindId проходит привязка, контролирующая дочерние элементы DOM. По логике, казалось бы, ты привязал данные, инициализатор привязки вернул { controlsDescendantBindings: true }, но это осталось в коде. Как только код добавляет (да через тот же foreach) элемент в документ, заболтивый нокаут бежит по всем data-bind указанным в разметке, и не найдя там привязки, вернувшей controlsDescendantBindings, начинает повторную привязку. Самое ужасное, что во время первой инициализации все нормально и глюк может иногда не воспроизводиться. Таким образом для слишком умных привязок или приходилось добавлять привязку-пустышку data-bind=«stopBinding: true», все тело которой controlsDescendantBindings: true, или отдельно учитывать эти моменты в инициализаторе bindId.

Кстати с новыми pureComputed я тоже не очень хорошо подружился, так что катить бочку раньше времени на них не стану
С вашими аргументами я соглашусь, по этой и описанным уже тут причинам я стараюсь делать ui как можно проще, да и пользователям намного лучше, когда не приходится совершать кучи лишних действий. А вообще я использую фабрику виджетов — jquery ui widget (виджеты пишу свои или юзаю плагины для jquery) вместе с нокаутом и пока эта связка меня не разочаровала, может быть и вам стоит обратить на это внимание. Если проект нормально разбит по папкам, то проблем нет. И конечно же, нужно управлять загрузкой этих виджетов, но это уже другая история.

Инструменты не совершенны, да.
А расскажите, как вы решаете следующую проблему: в разметке есть один div для popup. Биндинг к данным сделан в Knockout. Хочется через knockout открывать и закрывать (уничтожать) несколько попапов с разными данными. Есть ли красивое решение для этого?
Что я делаю сейчас — делаю div невидимым, пишу обертку, которая при открытии попапа клонирует html и делает клону ko.applyBindings(). Имхо, это дичайший костыль.

tl;dr Как в Knockout жить с моделями, которые могут быть дуплицированы и привязаны к разным данным?
Первой проблемы у меня не появляется, потому что я использую jquery виджеты и там логика у меня немного другая, можно попап написать свой и вешать его на любой элемент. Конечно, div попапа будет создаваться на каждый попап, но зато сразу решается ваша проблема. Вообще с этой фабрикой виджетов и нокаутом получается как в веб-компонентах — есть шаблон html файл отдельно, есть js код отдельно (виджет и есть модель), подгружаем два этих файла и всё хорошо (можно сделать простой загрузчик виджетов на 150 строк).

Вторая проблема с моделями. Последнее время я использую централизованное хранилище (можно сделать очень простое, а можно покруче). Так получилось, что нам в компании для упрощения работы понадобилась реализация схем данных mongoose (node.js) на клиенте и пришлось реализовать этот механизм — в результате получился хороший storage со схемами данных, с валидацией, работающий с knockout + es5 (https://github.com/SteveSanderson/knockout-es5) + еще несколько других фишек из mongoose. Так вот, если использовать его, то получается, что все данные у вас в одном месте и вы просто запрашиваете их для конкретного виджета (в нашем случае). Пока, при таком подходе, я проблем не заметил.

Если вам интересно, я могу сделать демку, поделиться своими наработками в плане нокаута.
Полагаю вам необходимо написать собственную привязку (binding) или компонент, который будет инициализровать разметку или еще чего, когда вам надо.
Как я уже выше подмечал, можно указать, что bindingHandler будет сам обрабатывать дочерние привязки или вообще вручную работать с DOM.
Ну есть проблемы да, ну а где их нет? Половина статьи описывает проблемы в духе нужно хорошо изучить фрэймворк, чтобы его использовать на полную катушку.

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

>либо jQuery
Лол, что? Надо было сразу прочесть конец и не читать статью.
Да, читал про лечение, но хочется попробовать реакт. Он судя по тестам работает намного быстрее.
Реакт с ангуляром нельзя сравнивать, реакт это просто вид и загрузка дынных без контроллеров или сервисов.
В ангуляр React спокойно интегрируется через ngReact.
Собственно по этому Ganesh и говорил про «возможно в связке с angular».
> Гугл не использует AngularJs для своих основных продуктов (gmail, google+). И это вызывает подозрения, если это такой хороший фрейворк и они сами его создали, что тогда сами и не используют?

Nowadays, the framework is used by more than 100 projects just at Google, and it is maintained by its own internal team, in which Miško takes part.
У гугла просто море проектов (видимо из-за того самого «правила о скольки-то там процентах рабочего времени на свой прожект» чуть ли не у каждого сотрудника))) Естественно, большинство из них никому не нужны, а иногда они становятся огромными, но все равно умирают. Покажите в каких действительно _рабочих_ проектах гугл используется этот фреймворк? Похоже, что автор прав.
Автор немножко переборщил с эмоциями, но в целом первое впечатление от ангуляра передал верно.

Я после просмотра туториала по дурости решил, что смогу склепать ui на ангуляре самостоятельно. В результате целую неделю собирал все возможные грабли и косяки (вот какого дьявола в диалоге автоматически создаётся лишний scope, например?) — а потом забил на это дело, и передал доводку UI фронтэндщикам. Дальше было чистейшее шаманство: ребята говорили, что «вот тут надо написать именно вот так, потому что только этот способ работающий, а тот, который я углядел в доке — он именно здесь не подходит, потому что такая магия», и это надо тупо выучить. Я серверный программист, я привык к тому, что всякие там фреймворки пляшут под мою дудку, а не заставляют учить заклинания.

Ну, и если уж быть до конца честным, с годами ситуация с web-based ui как-то качественно лучше не становится. 6 лет назад я писал на ExtJS, и это было ужасно, потом мне здорово покушал нервов проект на JSF, теперь вот появился ангуляр — годы идут, а сложность, противность, и незрелость используемых инструментов никак не уменьшается. Печально это.
Лишь отчасти соглашусь с некоторыми суждениями, но СЛИШКОМ МНОГО BOLD'оВОГО КАПСА НИКОГДА НЕ БЫВАЕТ МНОГО.

Во многом согласен с комментариями о дилетантстве — все описанные проблемы достаточно просто решаются при наличии желания и гугла.

Ограничения $digest цикла можно легко преодолеть, об этом уже было написано тут и о результатах в 1200ms -> 35ms тут.

DI не работает после минификации — в офф доках ангуляра прямо говорят (раздел Note on minification): используйте $inject, или аннотации. Опять же, не стоит ныть по поводу «мне влом написать 5-6 слов со знаком $ — этого не должно быть, это проблема фреймворка !». Указать минификатору наличие сторонних глобальных переменных не составляет особого труда, и это никак не относится к дизайну самого фреймворка.

По поводу «нетестированности» самого фреймворка, а автор пробовал Protractor с ngMock'ом? Есть $exceptionHandler и им вполне так удобно перехватывать любые ошибки. Хватит ныть — читайте документацию.

Наследование скоупов не имеет прямого отношения к ангуляру непосредтсвенного — это просто заморочка прототипного наследования в JS'e. Немного гугломагии подтверждает, и такого уже было написано очень много. Опять же, сами ангуляровцы в доках советуют не использовать глубокое вложение объектов внутри $scope потому что там будут глюки с $watch'ерами и $digest циклом. Использование нескольких уровней вложения в рамках одной директивы не поощряется, по тем же причинам что и указанны в статье… и это не является проблемой — ничего не мешает писать $scope.btnCaption вместо $scope.btn.caption.

Синтаксис
ng-controller="SomeController as OtherName"
не более чем синтаксический сахар для избежания путаницы в описаниях контроллеров, и никакого отношения к проблеме не имеет.

Понимание или непонимание работы директив зависит от каждого конкретного разработчика — проще чем есть сделать не получится. Если для вас это сложно — это ваши проблемы.

По сравнению с тем же backbone или ember — Angular совсем не сложный, и в нём ничего не протекает. Конечно после jQuery у людей странное выражение лица, но качественный богатый фронтенд не подразумевает место для поиска «плагина завоевания мира нажатием одной кнопки». Учитесь, и не нойте!

Невозможность серверной шаблонизации… хм, ну это зависит как посмотреть на проблему — берём prerender.io, прикручиваем рендер страниц при изменении моделей, кэшируем нормально в Nginx'e и отдаём поисковым роботам. Не то что бы это было изящно, но и писать серверный рендер ангуляра под каждую платформу бессмысленно. Тем более такой подход при небольших нагрузках на запись вполне нормально работает. Для прозрачной клиент-серверной шаблонизации нужна трансляция OT-патчей в CQRS-ES'e — это довольно сложные подходы которые используются в корпоративных приложениях с незапамятных времён (привет vaadin, привет gwt, давно не виделись).

А кто сказал что гугол не использует у себя Angular?

В общем все проблемы которые описанны в статье — вполне решаемы.
Было бы желание погуглить, и не постить на хабр всякую ерунду из-за собственной лени.

Я не говорю что React плох, но сравнивать React с Angular'ом НЕЛЬЗЯ. React это лишь View и View-Model из MVVM, а Angular — чистое MVC. У ангуляра рендер реально слоупочный, и появляются такие странные вещи как ngReact (чую запах жареных мозгов). Я и сам спокойно гоняю React + rx.js в браузере, и на node.js, и вполне так доволен производительностью для средних проектов.

Я надеюсь что во втором ангуляре исправят косяки рендера и начнут напрямую оперировать DOM деревом, без лишних перерисовок и перекомпоновок чего-попало.
Само собой, статьи на тему «почему не ангуляр» нужны. Но эта статья какая-то странная… Здесь скорее перечислены проблемы, возникающие при старте, чем какие-то фатальные недостатки, которые будут преследовать вас на протяжении всего процесса разработки.

Собственно, из недавно прочитанного я бы посоветовал это:
www.fse.guru/2-years-with-angular
www.fse.guru/why-you-should-learn-angular-anyway
Я автор вышеприведенных статей.
Статьи написаны «по верхам» с умыслом.
Если у вас будут вопросы — то я с радостью отвечу :)
О, я тогда хочу вам сказать спасибо, за упоминание mithril.js в обзоре фронтенд-фреймворков. Чудесная штука.
Посмотрите еще cycle.js: github.com/staltz/cycle

Правда, я бы не сказал, что это продакшн-реди фреймворки, подходящие под мои критерии. Но идеи и тенденции в них заложенны более здравые.
Спасибо, я посмотрю на cycle и попробую разобраться с FRP еще раз. До сих пор не осилил как-то.
Он сыроват пока, и для продакшена не готов (
Ну что ж поделать-то. Значит, нужно использовать в pet project-ах и ждать готовности. =)
«ага, тут кликнули по кнопке и изменилась модель, теперь нужно слушать изменения на этой модели и когда она меняется вызывается хэндлер», а не «кликнули на кнопку, вызвался хэндлер»

Хм, ng-click=«clickHandler()»?
ДВУСТОРОННИЙ БИНДИНГ — ЭТО НЕ ТО КАК ПРОИСХОДИТ ОБРАБОТКА СОБЫТИЙ В ПРИНЦИПЕ

Угу, и, $watch() моевтон в 99% случаев, особенно в таких, которые вы описали.
Еще двусторонний биндинг означает, что изменив что-либо в своем приложении, это тригерит сотни функций

Странно, а я думал что там dirty checking цикл, и изменение переменной абсолютно ничего не триггерит.
ТО ВЫ ТОЧНО УПРЕТЕСЬ В ЭТО ОГРАНИЧЕНИЕ

Стоит подумать о своей архитектуре, а не об архитектуре ангуляра. Да, на RICH приложения он и не затачивался (это, кстати, к слову о gmail'e). Если вам нужно 1000+ биндингов, то вы неверно выбрали инструмент.
Когда вы минифицируете свой код, то он перестает работать

Когда это минификатор, особенно с агрессивной политикой оптимизаций, не требовал препроцессинга / своего стиля написания кода?
Наследование скопов

Хм, а прототипное наследование в JS вас не напрягает заодно? А ОО-архитектура со странными всплывающими багами при непонимании парадигмы? Имхо, скопы и их наследование довольно хорошая штука. Если посидеть 15 минут с отладчиком и поразбираться в их механике, то в дальнейшем вопросов нет.
сделать одну единственную функцию

Вы не поверите, но описывать директивы можно одной единственной функцией. Использование синтаксиса директив на полную не всегде нужно, но он придаёт довольно сильную гибкость директивам.
трансклюд вообще хрен пойми

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

Программирование на достойном уровне вообще сложная штука. Даже без ангуляра более-менее сложное приложение не разобрать с наскоку. Ну скажем, если не хотите async hell'a, то у вас будут промизы, которые в серверных языках не всегда используются.

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

Очевидно, но, надо признать, достаточно геморройно, особенно если юзаешь сторонние директивы и их приоритеты.
Странно, а я думал что там dirty checking цикл, и изменение переменной абсолютно ничего не триггерит.


Обычно в сложном приложении получаются много $watch('xxx', function(...){...}). Вот они вызываются при каждом $digest цикле и не по одному разу.
Недостатки будут везде, их не избежать.

Но плюсов, то больше. Фреймворк позволят весьма удобно организовать код, и сразу знать где что искать.

Директивы — это конечно ад, зачем их так сложно сделали, понять просто не возможно. Если их не писать постоянно, то скорость непонимания уже написанного просто феноменальна.

P.S. Мой личный фаворит в недовольстве — «а давайте обернем весь остальной мир в директивы». Это просто ужас, делать столько бестолковой мало чем оправданной работы… При том что авторы того, что мы оборочаиваем тоже не дураки и часто их решения по подключению бибилиотеки просто в разы удобней всяких директив, за которыми надо еще следить потом.

Как всегда, собственно. Сначала всем всё нравится, но обязательно должен появиться кто-то, кто скажет, что это плохо. Думайте, наконец, своей головой, ей богу. Ни один из аргументов в статье нельзя воспринимать всерьёз.
Мне вот например не нравится бутстрап, который нравится очень многим :)
Не только вам.
Он гробит семантику разметки и задачи самого HTML5.
Так что годится не более чем для внутреннего использования и прототипирования.
В очередной раз «умение готовить» демонстрирует принцип — сначала создадим себе проблему, а потом будем её решать сторонними дополнениями.
Просто нужно использовать CSS-препроцессоры, и никто ничего гробить не будет.
Раздражает его привязка к тегам, а не классам.
это нормализация, а не часть функционала. все на классах.
тэги используются там, где обусловлены семантикой — для них это стало главным с выходом 3й версии.
Понял, думал, что вы про общие теги (например, привязка div.alert или table). Вообще, есть такое.
Мне тоже. :) Но я хотел сказать не об этом. Автор статьи, толком не разобравшись с проблемами, вставшими у него на пути (а все эти проблемы вполне себе преодолимы), рекомендует нам не использовать Angular, что, по сути, весьма неразумно, учитывая все те прелести, что фреймворк нам предлагает.
Разве? По-моему автор часть решений проблем разобрал. Его позиция заключается в том, что это не практические проблемы, а проблемы плохого дизайна.
UFO just landed and posted this here
После знакомства с Ангуляром мне в голову пришла следующая метафора.

Предположим, у нас есть некоторое приложение. Мы, как архитектор этого приложения, знаем как в нём организованы потоки данных. В приложении мы задекларировали эти потоки данных и то как их следует обрабатывать в виде некоторого кода. То есть у нас описаны некоторые конкретные блоки, которые связаны конкретными линиями-направлениями данных.
В противовес этому, Ангуляр представляет собой что-то вроде «множества универсум», где всё связано со всем. В первый момент это вызывает wow-эффект. В самом деле, путём нескольких деклараций и пары строк кода мы организовали полноценный ввод пользователя, обработку и автоматическое обновление представления (!). Но в дальнейшем становится ясно, что такая полносвязная схема имеет свои побочные негативные эффекты: низкая производительность и сложность восприятия.

Я был очень рад услышать, что идёт разработка Angular 2, который (как и обязано мажорному релизу) будет обладать существенными изменениями, и в частности упрощениями, выпиливанием целой кипы фич. Также, существует разработка angular-light, которая освещалась на Хабре и ознаменована той же цели: упростить и оздоровить Ангуляр.

После использования Ангуляра я пришёл к выводу, что лучше строить приложение, основываясь на явных потоках данных. Для этого лучше всего подходит идея FRP. Что замечательно, FRP прекрасно компонуется с существующими библиотеками (я считаю, компонуемость — это очень хороший признак действительно здоровой концепции), например, можно использовать jQuery для получения источников данных (пользовательские события, которые инициируют flow/поток), так и для отображения ($.text, $.html в конце цепочек), также FRP прекрасно дружит со всеми существующими шаблонизаторами.

В общем, явное лучше неявного, FRP и компонуемость это будущее.
Абсолютно согласен, на парадигмах FRP писали реактивный манифест.
Пробуйте React + rx.js если интересует полноценное FRP в браузере, и Typesafe Stack со Scala на сервере…

За реактивными приложениями действительно большое и светлое будущее.
На вкус и цвет — все фломастеры разные.
На самом деле Angular никак вас в этом плане не ограничивает. Есть Angular-bacon для того что бы строить FRP в angular-based приложениях.

Более того, я лично вижу проблему во фразе «Angular-way». В частности, довольно популярная библиотека для работы с localStorage полностью построена на ватчерах и циклах дайгест. То есть просто так. Потому что это этот самый angular-way. Откуда у людей берутся такие идеи я не знаю.

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

p.s. основная идея Angular Light не в том, что бы «оздоровить» Angular, а в том что бы дать возможность использовать тот самый синтаксис шаблонов (а с ним и директивы + фильтры) без необходимости использовать полноценный фреймворк.
Такие идеи из примеров, пропагандировавших этот подход.
Ранняя документация имела конкретные намеки на angular way.
p.s. основная идея Angular Light не в том, что бы «оздоровить» Angular, а в том что бы дать возможность использовать тот самый синтаксис шаблонов (а с ним и директивы + фильтры) без необходимости использовать полноценный фреймворк.
Я тут не вижу противоречия. Похоже, что мы с вами говорим об одном и том же. Под «оздоровить» я как раз и имел ввиду «выделить ключевую идею и убрать мишуру».
Под мишурой вы имеете в виду то, что делает Angular фреймворком а не библиотекой как react.js? Ну так в Angular2 уже решили сделать все модульным. То есть начиная с версии 2.0 фреймворк будет полностью разделен на отдельные независимые компоненты (кое какие, например тот же DI, уже доступны и как по мне вполне себе стабильны) и вы будете вольны использовать только то что используете. Меня же устраивает монолитная структура Angular так как я задействую всю эту мишуру (DI, директивы, модули, разделение на этап конфигурации и выполнения и прочую «чушь»).
О, вы меня сподвигли начать писать статью про vue.js, наконец.
Который при желании может прикидываться и ангуляром, и бэкбоном (в минимальной форме, конечно, но порог входа для тех, кто с ними имел дело, около плинтуса), летает (перфоманс — изумительный). Поддерживается буквально двумя людьми, но при этом мелкие issue-ы, которые я им пишу, например, вечером в четверг, в 6 утра в пятницу оказываются уже исправлены :)

Ну и подход очаровывает.
«DI? да нахрена вам DI в фреймворке для клиентсайда, у тебя есть AMD или CommonJS или что еще придет в твою больную голову»
«Что? Навигация? Чувак, тебе оно точно надо? Посмотри сколько клевых библиотек для навигации и без нашей помощи сделано, мы тебе сделали директиву для смены лейаутов, на здоровье»
«Компоненты? Службы? Модели? Директивы? Сервисы? Чо ты к нам пристал. На тебе фильтры для шаблонов, компоненты для, собственно, автономных компонентов, и директивы для всяких мимимишных жкверишных плагинов твоих, хватит тебе».
И реально хватает ведь.
А что самое крутое — он эти шаблоны свои — ну вот такой, например: {{ profiles[currentUserId] }} — (да-да, привет, ангуляр) он не разворачивает как-то, а превратит в
try {
return this.profiles[this.currentUserId];
} catch (e){
...
}

и если флаг debug установлен — он сам вызовет дебаггер на ошибке. А this реально указывает на окружение, которое можно полноценно поинспектировать.
Я так приложение в айфрейме дебажил (был один прикол, связанный с хромовскими приложениями). Как бы я с другими фреймворками это делал — вообще бы не представляю.
vue штука действительно хорошая и минималистичная.
Видимо вы не видели обёрток backbone которые пытаются предотвращать утечки, но у них это не очень хорошо получается. И не строили рективных приложений с частыми (50-60 в сек) push-нотификациями с сервера по comet'у или websocket'aм…

Vue.js достаточно простое решение производительность которого под большим вопросом — авторы говорят что сравнивать его с React'ом, Backbone'ом или Angular'ом на данном этапе развития нельзя — слишком разные методы рендеринга, больше меряем производительность браузера нежели фреймворка… хотя на самом деле авторы хотели переплюнуть React, но у них это не получилось и им стыдно стало :3 А вот с тем что с остальным сравнивать бесполезно — там будет разница просто адовая, я вполне согласен.

Но опять же очередное сырое решение не готовое для продакшенов средних размеров.
С react-ом — сравнивать вообще что-либо сложно, особенно с react+om.
А в нынешней версии (0.11.х) почти все детские ошибки исправили. Я за проектом почти год уже слежу и могу на полном серьезе сказать — 99% кейсов покрыто, и неожиданные ошибки в духе «что-то не работает, хотя должно» — на 0.11 у меня ни разу не появлялись. Да, были ляпы, связанные именно с новыми фичами (вот два, которые я закоммитил: #652, #594, например) — но конкретно с работой приложения они уже не были связаны.

Я бы сказал, что сейчас Vue — medium rare. Да, немного сыроват, но удовольствие от употребления будет наблюдаться у большинства :)

А насчет 50-60 обновлений в секунду — я в январе за подобный проект берусь. При этом это полноценный энтерпрайз с джавой на бэкенде и прочими удовольствиями жизни. Сейчас думаю над выбором: ангуляр или React+Om. При этом совесть меня склоняет к первому, а предчувствие жопы с перформансом — к второму. О Vue там и речи быть не может, конечно — даже не из соображений того, что он нестабилен так или иначе, а как минимум из-за того, что он поддерживаться будет не один год, и найти разработчиков на vue в дальнейшем будет сложнее, чем на react или angular.
J2EE сервлеты vs Plain Netty это ~35 к 1 по скорости обработки пустых запросов.
При больших БД, и толстых кэшах нужно внедрять offheap кэширование, можно на hazelcast'е или terracotta'е.
ClojureScript'овый Om выглядит лично для меня очень небрежно — как если бы elisp с prolog'ом смешали.
Кроме всего этого нужно ещё внедрять rx.js или highland для отработки асинхрона без лишних проблем.
Да я-то тут при чем. Я фронтэнд обеспечиваю. Я вообще джаву не умею и не хочу уметь (но, видимо, андроида ради и придется когда-нибудь).
Как специалист я сраный фронтэндщик, который даже верстает медленно, зато умеет в джаваскрипт так, что все вокруг хренеют, на этом мои прикладные способности заканчиваются. То, что я умею дизайн, ux, настраивать nginx, спокойно кодить под рельсы, работать с кучей других языков, читать исходники v8, паять усилители, управлять разработчиками и разбираться в особенностях низкоуровневых протоколов — это круто, но это исключительно жырный плюс к тому, что я хороший фронтэндщик, который понимает как работает все, с чем он взаимодействует — начиная от того, как работают http-запросы на всех уровнях модели OSI и заканчивая тем, как повысить конверсию :) Потому и занимаюсь такими замороченными проектами.
И вот честно, никакого желания в этот неплохой багаж знаний добавлять особенности работы кэшей под джаву)

Но про Om запомню, спасибо.
Извините, но что у Вас за задача такая, которая вынуждает слать 50-60 нотификаций в секунду с сервера?
Учёт работы ~400 человек персонала в реальном времени: телефония, консультирование, денежные транзакции, доставка товаров…
Смысла нет так часто слать, раз в секунду достаточно, человек же не машина.
Там очень много данных вбивается и редактируется в реальном времени достаточно большим количеством людей — нужно это всё синхронизировать и формировать Batch запросы на запись в журнал изменений, проставлять временные метки в векторных часах и решать задачу консенсуса (у меня пока raft). Это можно представить как один большой гуглодок с табличками которые очень быстро правят 5-6 человек, и в метериализованном представлении которых постоянно пересчитываются и перепроверяются данные после каждой правки в браузере.
Да, именно поэтому и спросил. Мне сразу представилось перемигивание разных кнопочек и формочек в окне, от которых начинает рябить в глазах. Так и не понял почему нельзя посылать «сумму» изменений к примеру раз в секунду (а то и реже).
Количество плюсов этой статьи напрямую отражает количество дилетантов на хабре, и это печально.
А может некоторые уже давно перешагнули ангуляр? Ну хотя бы разработчики самого ангуляра ;) Версии 2.0. Хотя там вроде даже люди поменялись, но это другое
Для тех, кто перешагнул ангуляр, не составит особого труда погуглить и решить все проблемы описанные в статье.
Автор решил. Не использует ангуляр.
Как по мне это не перешагнуть а сдаться.
Использую Angular не два года, а всего полгода, но хорошо понимаю автора.

После известий о Angular 2.0, который всё поломает, я решил посмотреть на что-то другое и сейчас читаю документацию по ember.js — и знаете, СЛЕЗЫ СЧА^W^W слезы счастья катятся по моим щекам. Если кто-то испытывает непонятный баттхерт от прекрасной, как все вокруг говорят, технологии — советую посмотреть на ember.
У ember'a долгое время до первой версии были проблемы с API и сообществом — не было документации нормальной, и обратная совместимость отваливалась от версии до версии. Сейчас это один из ходовых фреймворков без особых заморочек, «который работает». Его задачей было: сохранить простоту, и не раздувать излишне свой функционал. Angular любят за то что там можно писать меньше кода, и от него бывает больше толку. Но шаг влево — шаг вправо, не по гайдлайнам — сразу начинаются приколы. В общем порог вхождения не большой — нужно просто много читать и разбираться, а не писать вот такие вот бесполезные статьи на хабр.
Пишу и на Ember, и на Angular. На Ember у меня всегда меньше кода получается. И самое главное: я могу пересесть с одного Эмберовского проекта на другой без особых разбирательств, а Angular в каждой команде почему-то готовят по-своему и приходится время тратить, чтобы разобраться, какие тут приняты правила и конвенции.
Пишу на Ember. По началу — все радужно. Потом всплывают разные косяки, которые обещают починить в 2.0

Основное, что считаю поломанным сейчас:
1. собственно EmberData. Да, оно в бете, и грех жаловаться, но готовьтесь к тому, что: rollback не работает на one-to-one, one-to-many, DataBoundPromise никак не доедут до релиза
2. документация отличная, но не покрывает все моменты (некоторые вещи приходится смотреть прямо в коде)
3. многострадальные queryParams. Они вроде как есть, но некоторые вещи в них не работают и на них заведено много issue
4. синглтон контроллеры настолько всем не нравятся, что их убирают в 2.0
5. сложно писать сложные компоненты, где требуется обновление большого кол-ва property и не хватает one-way binding property. Новый подход к компонентам обещают в 2.0 (больше похоже на React)

Что действительно радует — роутер, к нему претензий нет.

Судя поrfc для 2.0, они хотят с помощью HTMLBars + one-way binding сделать компоненты похожими на React, но при этом использовать всю мощь роутера и EmberData для моделей
По 4му пункту я сейчас обхожусь тем, что пишу без контроллеров. Все контроллеры — автогенеренные Эмбером везде, где можно. По факту пишу свои только если нужны queryParams. Решает кучу проблем.
Это то, к чему они идут в 2.0. Т.е. все property, фильтры и прочее в Route?
Скажите, а зачем вы выбираете инструменты, которые «умеют все»?
Я о том, что многие инструменты пытаются добавить все на свете в свой функционал. ИМО это плохо заканчивается.
Согласен, «разделяй и властвуй».
Угу. При чем плохо заканчивается для разработчика/продукта. Вместо замены одного компонента приходится выбрасывать 80% кода при переходе от А к Б.
Вопрос не в том, что инструмент умеет все, а в том, сколько у вас накапливается в проекте кастомного и glue-кода, который ничего не делает кроме как соединять отдельные «идеальные» микро-библиотеки.

Многие считают:
1. о, я возьму вот эту микробиблиотеку, соединю вон с той, буду брать все самое лучшее, все то и только то, что подходит для моей задачи, — и получу идеальный проект.
2. потом в коде для склейки частей у них возникает какое-то дублирование кода, вырисовываются какие-то шаблоны, они их начинают вычленять, радуются, как у них все идеально и идиоматично, и т.д.
3. так из идеальных кусочков у них получается свой недофреймворк, на котором они пишут свое приложение.
4. а потом этот фреймворк начинает трещать по швам из-за «особых частных случаев», обхода багов в выбранных библиотеках, несостыковываемостью выбранных компонентов между собой, проблем с производительностью и т.д.
5. а времени фиксить недофрейсворк нет — проект, сроки, заказчик, менеджер. Взяли человека в команду — ему с ним теперь неделями разбираться. А если «автор» фреймворка уже ушел из команды, и вы — как раз тот человек, кому придется разбираться в костылях вокруг идеальных библиотек образца 2013 года?

Иногда проще взять готовое большое решение и быстро решить задачу. Плюсы Эмбера:

— это такой же фреймворк, как и ваш самописный, но его в том или ином виде дорабатывают с учетом требований различных разработчиков несколько лет. Получается, что у вас фора — несколько десятков человеколет на вашем проекте. Багов в нем мало, шансов столкнуться с ними — не один раз в день, а один раз в месяц, например. Если у вас возникает «особый случай», очень высока вероятность, что где-то в Эмбере предусмотрены лазейки и хуки, чтобы его вписать во фреймворк.
— архитектура решена за вас, не нужно ничего придумывать, не нужно спорить о том, как сделать лучше.
— вопрос инструментов сборки или подключения аддонов для вас тоже не стоит: все уже решено, вы делаете как все.
— в отличие от Angular подводных камней гораздо меньше, мест где нужно изобретать велосипед — тоже, инструменты лучше, диагностировать и решать проблемы производительности проще.
— полно больших open-source проектов — всегда можно посмотреть, а как люди решают ту или иную задачу.
— все пишется в открытую: нет такого «ой, мы тут версию 2.0 готовим — все теперь будет не так, как раньше»

Он не делает для вас все, но 90% того, что он делает, вам наверняка подойдет.
Здраствуйте. Что-то просмотрел пост в свое время.

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

Что до Эмбера, то ничего не скажу. С виду хороший, во многом наверное лучший фреймворк для многих задач.
Довелось мне как то переписывать код с angular на backbone. Angular не понравился из-за вшитого кода в html. Htmlу и так уже плохо от всяких штук, а тут ещё и angular. Так что я не против angular, но только если мне не придется на нем писать.
«Я не против angular, но только если мне не придется на нем писать» — гениальное выражение :) Его кстати можно применить к вообще любой технологии :)
А мне довелось переписывать с backbone на angular, потому что backbone кушал 80Mb+ оперативки xD
а мне как разработчику не знакомому тогда ни с тем, не с другим, к backbone сразу любовь, а вот к ангуляру отвращение. Код был не рабочий, и понять что в нем не работало было невозможно.
У всех свои задачи. И есть инструменты которые подходят, или не подходят… нужно всё пробовать и мерить. А «любовь»/«нелюбовь» или «удобство»/«неудобство» не совсем конструктивное отношение по отношению к реализации любых продуктов. Это ведёт к «golden hammer»'ам и фанатизму.
Было бы интересно узнать, что там такое жрало много памяти. По моим представлениям там просто ничего такого нет, чтобы много жрало.
То есть вас не смущает вкрапления JS в шаблонах для lodash/underscore или специфичный синтаксис handlebars? Если бы шаблоны лежали с расширением не html а aml (angular markup language) вам было бы спокойнее? Это просто синтаксис шаблонов, ничего более. Чего все так зациклились на этом…
ну значит мне просто не нравятся шаблоны похожие на перенасыщенный html с атрибутами ангуляра.
этой проблемы можно было бы легко избежать просто УБРАВ ВОЗМОЖНОСТЬ НАСЛЕДОВАНИЯ СКОПОВ
Вы имеете ввиду, если бы был один scope на все?
В данном примере ng-if отвечает за дочернюю структуру (DOM и scope), и когда значение в ng-if будет = false, эта директива уничтожит дочернюю структуру (DOM и scope), если бы был один scope на все, то было бы не понятно, какая его часть является дочерней и что уничтожать, это разграничение обязанностей.
Если просто убрать наследование, то не будут видны родительские объекты напрямую — это неудобно.
К вопросу о проблемах с людьми, ну и взгляд извне веб-разработки:

Основной мой профиль — C#+WPF, опыт web/js был лет 7 назад, когда ещё jQuery только набирал популярность.
Пришлось добавлять фичи в соседний проект на ASP.NET MVC Web Api + AngularJS, был приятно удивлён удобству Angular и схожести концепции байндингов с WPF. Втянулся за пару дней, реализовал несколько довольно объёмных формочек, пару директив. Конечно, спотыкался на многом, но в целом всё понравилось. У коллег тоже проблем не возникло.

Считаю, что идея байндингов — очень правильная и удобная. И опции байндинга (one time, one way) вовсе не является костылями.
Ну видимо в гугле gmail и другие сервисы написаны до angular-а
А тот же React как я понимаю писался под facebook (или параллельно, как например Django — изначально писалась для новостного портала)
Насчет сложности проекта на ангуляр и что в нем не разберешься…
Все зависит ведь от разработчиков. Мне попадались проекты на jquery — где черт ногу сломит. Сейчас есть проект где используется React.js — тоже много спорных моментов.
С ангуляром достались два проекта — в которых все средне (то есть разобраться можно, но есть весьма и весьма спорные моменты)
Однако с ангуляром же есть и удачный пример. Когда мне попался код, написанный на coffeescript + angular
По сути читал проект как книгу, все ясно и понятно и на своих местах, при том что до этого я на coffee не писал.
Ну криворукость отдельных индивидов от фреймворка не зависит. Костылять можно везде, не зависимо от инструментов, и к инструментам это не имеет никакого отношения. Я видел костыли и хорошую реализацию во всём с чем приходилось работать.
Собственно я о том же. В статье просто есть упрек, что в ангуляр проекте сложно разобраться новичку, а дескать в React все лекго и просто. Хотя на самом деле все зависит от реализации конкретного проекта
Смешались в кучу кони и люди…

ДВУСТОРОННИЙ БИНДИНГ — ЭТО НЕ ТО КАК ПРОИСХОДИТ ОБРАБОТКА СОБЫТИЙ В ПРИНЦИПЕ

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

ТО ВЫ ТОЧНО УПРЕТЕСЬ В ЭТО ОГРАНИЧЕНИЕ

Точно упретесь при плохо спроектированном UI со 100500 элементами на одном экране или на определенных задачах, например, бесконечном скроллинге. И потом столкнувшись с парой таких проблем, просто реализуете локальное решение, заточенное под конкретную задачу в данном конкретном месте, покроете это все тестами и забудете. Вообще, конкретики по этому громкому выводу явно не хватает.

ЭТО ПЕРЕСТАЕТ РАБОТАТЬ ПРИ МИНИФИКАЦИИ КОДА

Одноразовая ужасная проблема для новичка.

Там вводятся 5 новых сущностей: provider, service, factory, value, constant (непродуманная-архитектура#4).

Проблема на один раз разобраться и потом использовать по месту удобный способ объявления.

Дебаггинг

Это могло бы быть реальной мешающей проблемой, т.к. вроде как не совсем одноразовая. Наверное здесь стоило бы что-то улучшить. Но это является большой проблемой для тех, кто много дебажит. Если кто-то в ангуларе много дебажит — скорее всего у него какие-то проблемы с тестированием приложения. Это если не касаться дебага выражений в шаблонах, т.к. если кому-то надо дебажить выражения в шаблонах, то я даже не знаю, как бы покорректнее такого frontend «программиста» можно было назвать.

Я не буду объяснять почему так происходит, на эту тему столько статей написано в интернете. И что самое интересное — этой проблемы можно было бы легко избежать просто УБРАВ ВОЗМОЖНОСТЬ НАСЛЕДОВАНИЯ СКОПОВ. Это был бы правильный дизайн. К тому же когда вы используете переменные из родительского скопа, это становится крайне сложно тестировать, странно, что фреймворк, который ставит одной из своих самых сильных сторон легкость тестирования, вводит такую логику.

Слабо раскрытая тема, я бы сказал, никак не аргументированная. Хотя следующий раздел про директивы наталкивает на мысль о глубине понимания автором директив и шаблонов в AngularJS.

И что самое обидное — ЭТА СЛОЖНОСТЬ НЕ НЕСЕТ НИКАКОЙ ПОЛЬЗЫ.

Абсолютно популистское утверждение. Только я один не заметил никакой аргументации по этому пункту?

Проблемы с людьми

Хороших программистов мало. Точнее всегда не хватает. Так что на этот пункт можно и с другой стороны посмотреть — AngularJS в некоторой степени даже ускоряет идентификацию уровня программиста и четко выявляет, на каком уровне человек находится сейчас, планирует ли развиваться (или будет из любой мухи слона раздувать), быстро станет ясна и динамика развития.

Ужасная документация. Приходится дополнительно гуглить много информации.

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

До сих пор отсутствуют директивы для Drag and Drop событий (на момент написания этой статьи). Само по себе это не очень большая проблема, но это сигнализирует о продуманности продукта и внимании к деталям.

Для вот этого? И как оно по Вашему должно в стандартной поставке выглядеть?

Когда вы пишите на ангуляре вы помещаете логику в ваш HTML. ng-repeat, ng-show, ng-class, ng-model, ng-init, ng-click, ng-switch, ng-if — что это как не помещение логики в представление. Само наличие такой логики — это не настолько страшно, как то что — это невозможно тестировать юнит-тестами, невозможно продебажить и оттуда не кидаются ошибки

В каком смысле невозможно тестировать? И что Вы там дебажить то хотите?

НЕ ИСПОЛЬЗУЙТЕ АНГУЛЯР

если вы ничего не знали и не хотите знать про двойной датабиндинг или он вам не нужен;
если вам ближе разработка UI в императивном, а не в декларативном стиле;
если вы предпочитаете дебажить вместо того, чтобы тестировать;
если вы не хотите разбираться с «ужасными» директивами;
если вы считаете что фреймворк должен думать за вас.

А в целом в любом активно развивающемся направлении/инструменте всегда будут какие-то проблемы, ошибки и т.п. Как вообще без ошибок можно развиваться? Систему характеризуют не ошибки, а реакция на них. Ну и легкость решения возникающих проблем. Не увидел в этой статье ни одной непреодолимой проблемы. Хотя, честно говоря, и проблем то особых не увидел.
Отметил кстати для себя, что ангуляр как правило не любят бэкэндеры (по крайне мере в моей практике это так). Обычно бывает такая ситуация — человек смотрит туторы — все легко и просто. Начинает делать сам и сталкивается с суровой реальностью — что все не так легко и просто, когда делаешь не «hello world» и тут наступает момент разочарования и мысли что лучше бы я использовал — backbone, react, asm.js и т.д

Да, я бы даже обобщил: используется ли Angular для создания SPA или как-то по-другому.
У меня 5 лет опыта разработки бэкэнда. А последний год я пишу на ангуляре. И доволен как слон.
Аналогично, у меня 5 с лишним лет бэкенда вперемежку с спагетти-коддингом «на jQuery». Потом я понял, что в фронтенд-разработке должно быть что-то более удобное, что помогает, а не мешает писать код. Мои поиски привели меня к ангуляру. Да, поначалу трудно понять, нужно менять мировоззрение после jQuery, но потом все становится на свои места.
Сейчас у меня около полутора лет опыта разработки с использованием ангуляра и могу сказать, что в целом он удобен. Да, есть недочеты и есть тонкости, но они есть везде и с ними можно жить.
Если вы действительно хотите получить ответ, то не спрашивайте напрямую как сделать XXX на фреймворке ZZZ. Надо писать так: да ваш ZZZ — полный отстой, на нем даже нормально XXX нельзя сделать. И вам очень быстро ответят как правильно сделать, то что вы хотели.
У меня давно впечатление, что написать что-то разумное на js просто невозможно.
Разумность написанного зависит от разумности пишущего.
Маслянность масла зависит от маслянности масла.
По делу то что сказать хотите?
Я уже сказал. Говорить о том что на {язык} невозможно написать что-то разумное в ситуации когда на {язык} написано много разумного слишком противоречиво.
Для людей с бинарным мышлением хочу подчеркнуть, что выражения «у меня впечатление, что невозможно» и просто «невозможно» не эквиваленты. Как бы вам не хотелось, я сказал не то, что вам захотелось прочитать. Будьте внимательнее.
Нет, я вас все таки правильно понял. Однако, углубляться в словарную казуистику не стану.
«Не стану» надо было делать поста 3 назад.
Когда мне понадобятся от вас советы, я обязательно обращусь. А пока, оставьте свое дурное воспитание при себе.
У меня все в порядке с воспитанием. Если вам не нужны советы, зачем вы комментируете мои посты? Думаете мне нужны ваши?
Тема «что-то не так с Ангуляром» обсуждается довольно давно и многочисленно. Чтобы собрать ссылки по этой теме, сделаем простой поиск и обход англоязычных источников.

What’s wrong with Angular.js
!0 проблем и тем: (чтобы сравнить с названным в статье — вот список)
* Angular — HTML-парсер. Вследствие этого — трудности отладки.
* Двустороннее связывание автор считает антипаттерном (связывать View в направлении Model).
* Затратные средства наблюдения за событиями, что часто избыточно и сказывается на загруженности мобильного приложения.
* Дублирование структуры с angular.module, что приводит к двойным изменениям кода в HTML и контроллере.
* Медленность из-за dirty checking and HTML parsing (следствие п.3)
* Нет серверного рендеринга, если без хаков.
* Высокий порог входа (по факту), хотя провозглашали обратное. Признаётся как результат плохого дизайна. Много абстрактных слоёв.
* Google сам не использует его в своих флагманских приложениях Gmail и Gplus
*… Поэтому им ничего не стоит закрыть проект когда угодно
* Будет скоро переписан [2.0], что есть хороший знак, но и будут новые проблемы.

Как видно, очень много пунктов пересекаются в сравнении с названными 12 в статье автора, т.е. это — действительно, многими признаваемые системные проблемы. Но есть и некоторые новые для топик-стартерской статьи пункты относительно политики Google.

Прочее (из популярного найденного первым же поиском):
AngularJS: The Bad Parts
Почему (и куда) мы ушли от Angular
Things I Wish I Were Told About Angular.js
The reason Angular JS will fail
Почему земля круглая и мывсеумрём Не менее очевидный набор фактов
Как видно, очень много пунктов пересекаются в сравнении с названными 12 в статье автора, т.е. это — действительно, многими признаваемые системные проблемы.


Спорный вывод. Я вижу в той статье и приведенном резюме другое: автор является убежденным противником двухстороннего связывания и декларативного программирования. Кроме того, автору кажется, что «медленный» dirty-checking особенно сильно скажется на мобильном приложении. Ну и плюс страшилки про закрытие проекта, абстрактные слои и переписывание.

По поводу медленного dirty checking, особенно, в мобильных приложениях. На мой взгляд, это не так. Согласно моему опыту в мобильном приложении больше проблем возникает из-за количества одновременного рендеринга (сложный DOM, который еще и анимируется). В качестве примера: live-search с вываливающемся списком категорий при пустом поле ввода. Я тоже сначала подумал, что вся беда в dirty-checking — ведь надо слать запросы, частенько случается $digest и т.п. Убил некоторое количество времени на профилирование, добавление оптимизаций в js-код (запросы то, конечно, изначально не на каждое изменение поля ввода слались). Ощутимой разницы вообще не было. Проблемы оказались две: слишком много пытались отрендерить, что реально было не нужно — 3-5 записей максимально одновременно на мобильном экране были видны. Ну и в вываливающемся списке категорий изначально были svg. Замена svg на png дала, мягко говоря, ощутимый прирост скорости.
Вообще, конечно, dirty-checking был и будет большой темой для споров. Это осознанный выбор авторов. Обсуждение его в отрыве от плюсов и минусов альтернативных решений, особенно в манипулятивном стиле без явных кейсов — это скорее популизм.

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

Ну и еще немного про приведенную статью:
We are developers, we write and debug code. But Angular is HTML parser. I really don’t want to debug any string based parser instead of my code.

Первый пункт, наверное, должен быть самым важным и мощным. Но это прям какой-то каминг-аут. Если вам приходится дебажить строки шаблонов вместо вашего js-кода (последнее тоже не совсем хорошо, но иногда нужно), то с вами что-то не так. А с кодом 99,9% почти все не так.

И еще раз про то, для кого же создан AngularJS:
для тех, кто будет стараться тестировать вместо того, чтобы дебажить;
для тех, кто считает, что надо использовать декларативный подход для построения UI, а не императивный (как минимум, для тех, кто хотел бы уйти от императивного);
для тех кто будет часто и много думать о декомпозиции приложения и повторном использовании.
Я думаю, именно это потом оказывается «высоким порогом вхождения», а не количество абстрактных слоев, качество документации и т.п.
вот что плохо в подобных статьях — много слов, мало кода, ДАЙТЕ КОДА, особенно для примеров с плохой производительностью
А есть ли нормальный js фреймворк для построения многостраничного приложения в котором страницу изначально рендерит backend а frontend js потом подхватывает?
Angular он все же для одностраничных приложений. И если стоит задача связки backend+forntend без API то он вообще не подходит. И сколько я не искал, ничего удобнее для таких целей чем jquery я не встретил. Но jquery это библиотека и она не очень подходит для больших сайтов.
Polymer как вариант. Это не то что бы фреймворк… скорее полифил для web components… но это единственное что подходит к любому многостраничному приложению. А далее идут нюансы и различные юзкейсы которые можно решать отдельными библиотеками типа того же накаута или бэкбона.
Так как на бэкэнде (на сервере) ещё нет никакого DOM, то задача «отрендерить страницу» сводится попросту к задаче «подставить данные в шаблон на сервере», если я правильно понял формулировку задачи.

На языке JavaScript выбор средств для решения этой задачи — это выбор сервера и движка шаблонов.

Полагаю, что неплохим выбором является употребление Express в качестве сервера, Handlebars в качестве движка шаблонов (достаточно популярный выбор по данным опросов) и express-handlebars в качестве средства подключения движка шаблонов к серверу.

(Это простое решение. Если взаимодействие клиента и сервера подразумевается более тесным, чем скачивание страницы, тогда какие-то более навороченные средства применяются.)
На данный момент, этот здравый подход является практически святым граалем веб разработки.

Это то к чему стремятся сейчас все все веб приложения.
Mithgol очень толково подсказал что можно уже сегодня легко использовать и пускать в продакшн.

Для расширения кругозора можно также посмотреть это видео:
OSCON 2014: How Instagram.com Works; Pete Hunt
Давно присматривался к AngularJS. Но вот после таких публикаций пропадает желание применить его в новом крупном проекте. Испугался типичного сценария, где на первых этапах радость и эфория от новой технологии, а по мере развития проекта снежный ком из граблей и костылей.
Лучше попробую применить AngularJS в каком нибудь маленьком и некритичном проекте. А серьезный проект буду реализовать по старинке на jQuery, где есть уверенность что абсолютно все проблемы решаемы и не потребуют больших извращений.
(Может автор и не прав, но мне стало страшно.)
Я думаю несмотря на предвзятость и агрессивность автора статьи, большой проект на jQuery он тоже вряд ли одобрит =)
Он этот пост написал чтобы попиарить React.js и унизить Angular.js.

По поему опыту Angular.js в проектах любого уровня хорош, очень легко поддерживается и не требует гуру JS на каждый чих как для React.js. А проекты с jQuery после нескольких килобайт кода превращаются в адское месиво, где непонятно что и откуда вызывается, особенно если в команде есть люди которые не придерживаются code style.

P.S. Правильное ощущение от Angular.js можно понять только когда через год залазишь в какой-либо проект чтобы что-то допилить и разбираешься в этом за 5 минут + минут за 15 допиливаешь и ты молодец.
Я видел много всякого ангулярного дерьма, которое писалось дилетантами, и которое нереально поддерживать. После рефаторинга и покрытия тестами оно становится в половину легче и в раз 20 шустрее… Для Реакта не нужно быть «гуру JS», просто нужно относится к нему как к шаблонизатору загружающему различные данные, а их контроллеры уже нужно реализовывать отдельно в асинхронных решениях типа Rx.js или highlandjs.
1. Ну когда нужно чуть-чуть поправить вёрстку и надо лезть в JS код, где шаблон описан кодом и при ошибке всё может сломаться, туда простых верстальщиков пускать не надо, а ведь в большинстве компаний не «фронтенд разработчики», а верстальщики, которые с JS совсем «на вы». Про «гуру» я конечно перегнул, но это должен быть человек который умеет программировать настолько чтобы всё не сломать в чужом коде, для этого в нём ещё и разобраться нужно.
2. Да и уже несколько раз я участвовал в подобных спорах по поводу «пошустрее», никто так и не привёл пример проекта где использование React.js действительно оправдано перед Angular.js. Это нереально субъективная вещь из разряда — почему вы пишите на PHP/Ruby/Python/Perl, если на Java быстрее? Большая часть задач, особенно в web-разработке, не требует мегапроизводительности, и то что больше половины сайтов в мире сделано на wordpress это доказывает.

А вообще я считаю для каждой из технологий и React.js и Angular.js есть своя ниша и моё мнение что эти ниши не особо-то и пересекаются.
Ко второму пункту:

Обычно медлительность ангуляра является следствием чрезмерного использование ватчеров. Многие не используют ресолверы для контроллеров и вставляют кастыли на промисах что бы подгрузить данные что так же сказывается на отзывчивость системы. Скажем в том же angular 1.3 был добавлен bindOnce который при обдуманном использовании так же нехило ускоряет отрисовку. Ну и да, непосредственно работа с DOM (если мы говорим о стандартных средствах angularjs а не о кастомных директивах) реализована очень эффективно. По сути единственное преимущество React.js которое я увидел — он заставляет людей думать, что я считаю не плохо. Angular же предоставляет удобный и универсальный но не совсем эффективный метод работы с обновлением view. Это не означает что нельзя использовать более эффективные методы (тот же bindOnce) просто подавляющее большинство разработчиков не парятся особо.

По сути все сводится к тому что при помощи стандартных средств Angular можно довольно быстро поднять довольно большое приложение а затем уже оптимизировать узкие места. Ровно то же справедливо для проектов на PHP/Riby/Python. Сначала реализуется проект или его версия а затем происходит оптимизация узких мест. В WEB на бэкэнде узкое место это I/O и использовать более быстрые языки программирования (типа Java, D и т.д.) не имеет смысла так как время выполнения кода в большинстве случаев составляет всего 10%-20% от общего времени запроса.

Конечно если на сервере чиселки считаются то тут имеет смысл взять другую технологию, хотя еще лучше опять же определить узкие места постфактум и затем уже реализовать оные на более эффективных технологиях типа golang/rust/d/c++.

Так же и в Angular. Скажем у меня в одном из проектов была довольно серьезная проблема с производительностью для построения календариков с событиями и подобными штуками связанная именно с data-binding. Сам календарь изначально был инкапсулирован в директиву так что можно было безболезненно переделать все на ванильный JS максимально оптимизированный под задачу, и с этим дальше жить.

Увы нет таких инструментов которые позволяют решать задачи эффективно как с точки зрения потребления вычислительных мощностей так и с точки зрения трудозатрат. Обычно перекос идет в одну или другую сторону.
Если умеешь пользоваться гуглом и читать доки — нет проблем.
Все проблемы в статье решаемы, и связаны с нежеланием автора искать какое-либо решение, а гневно ПОСТИТЬ КАПСОМ, потому что эта технология оказалась для него слишком сложной в освоении.

Если хочется шустрее чем Angular, Ember или Backbone — пробуй лучше React с rx.js или highlandjs.
Кстати, да. Очень напрягли рассказы о тормозах при сложных интерфейсах и моделях. Обязательно покапаю React.
У меня несколько проектов на ангуляре где есть странички с тысячами объектов, с событиями, всякими выражениями, работает быстро, кстати, там такое количество объектов обусловлено непродуманным UI, потому их и несколько. Производительность вещь крайне субъективная, кто-то коллайдером управляет и каждую миллисекунду учитывает, а кто-то форму обратной связи делает, это только практически выясняется.
Опять же высокая скорость обычно обозначает больше кода и код более сложный в поддержке. И лично мой опыт говорит о том, что тормозит чаще не от архитектурных проблем, а от кривых рук программистов и там где больше кода эта кривизна явственнее.
По-моему проблемы, описанные вами в статье отчасти уже поднимались на англоязычных ресурсах (как уже заметил один из комментаторов), а отчасти являются вашим субъективным мнением. На самом деле большая часть проблем, поднятых вами действительно существует, но среди них нет ни одной неразрешимой.

Меня немного удивила позиция по поводу поддержки клиентского кода серверными программистами. Вы считаете, если человек знает Python (например), то он должен разбираться в JS фреймворках и наоборот? Такие утверждения, по своей сути, являются колыбелью быдлокодинга: «Давайте наймём Васю, он знает Python и если что, сможет поддерживать фронтенд часть».

По поводу серверного рендеринга и т.п: если вам нужен информационный сайт, который будет индексироваться поисковиками, то использование ангуляра было, как вы говорите, непродуманным решением №1. Что касается скорости рендеринга, то я немного не понял: генерируя страницу на стороне сервера, вы просто подставляете параметры в шаблон, рендерит её всё равно браузер. Да, вы можете закешировать страницу, с подставленными в неё значениями, но скорость рендеринга от этого не изменится, вы просто уберете время на процессинг шаблона (что на современных клиентских машинах, пусть даже на мобильных устройствах) занимает сотые доли секунды. Но если хотите и это оптимизировать, можете взглянуть в сторону appcache и кешировать то же самое на стороне клиента, тем самым убрав с сервера часть расходов процессорного времени и памяти.
UFO just landed and posted this here
Могли бы вы раскрыть немного свою мысль про «симфонию»? Что именно так плохо, что печалит больше всего. Интересен взгляд со стороны.
UFO just landed and posted this here
Симфония требует тонн бойлерплейта

Симфони как раз таки избавляет от необходимости писать тонны бойлерплейта. Хотите поспорить? Попишите на Silex что-то средних и больших масштабов. То что нельзя запомнить все эти аннотации и прочие штуки — ну… уж простите. Вопервых самые основные вы так или иначе запомните, а для всего остального есть гугл + автокомплит/сорсы.

Темизация форм хороша до тех пор пока не нужно прикрутить кривой, но нужный скрипт с гитхаба.

Вас никто не заставляет использовать Symfony Forms. Более того, никто не заставляет вас писать свой form type для этого.

Валидаторы в Entity превращаются в тыкву, когда нужно добавить в форму левое поле не связанное с Entity

Как это так? Откуда у вас вообще такая необходимость возникает? Типа галочки аля I agree и т.д.? Ну так для этого есть виртуальные проперти. Да и опять же, мне кажется тут проблема в целом в постановке задачи.

Наследуется только один форм-тип от другого.

И прекрасно. Не вижу проблемы. Если у вас есть общий функционал — есть экстеншены, которые позволяют вам горизонтально расширять ваши форм тайпы.

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

Мне кажется вам само то будет Yii или Laravel с его сингелтонами/фасадами. Вы покрываете код тестами? Судя по всему нет или только функциональными/интеграционными (хотя я тоже в основном ими пользуюсь но все же).

Примерно нулевая интеграция фреймворка с клиент-сайдом из коробки

Есть такое дело. Проблема уже поднималась. Я полностью согласен с тем что ассетик крайне неудобен в использовании если у вас хоть сколько нибудь серьезный фронтэнд. Потому я лично использую gulp и люди делают штуки типа gassetic (замена assetic на основе gulp). Лайврелоад, инкрементная сборка, сорсмэпы… чудо просто. Правда я пока не решил проблему с элегантным способом инджекта скриптов в темплейты так что частично пока использую assetic для этих целей. Может доберусь и до этого в ближайшем будущем, благо у меня мало проектов с фронтэндом. В основном только REST Api и SPA. Админки я уже давно делаю на angular и получается намного проще.

DQL — это зло

Знаете в чем основная плюшка DQL — вы не привязываетесь к структуре базы. Только доменная модель имеет значение. Только поля ваших объектов. Возможно движек базы данных вы и не меняете, но за жизнь проекта может поменяться структура базы и не один раз (наследование таблиц, переименование полей тоже случается и тд.). Вы видимо не осознаете преимущества DQL перед работой напрямую с SQL. И на самом деле довольно сложно ее осознать… это можно сделать только если у вас отберут эти плюшки. Скажем в Doctrine ODM для монги нет привязки полей объектов в DQL и вы должны оперировать именно именами полей документов… что ужасно неудобно.

Длинные неудобные команды для ассетов, миграций, запуска команд

Как вы верно заметили… автоматизация наше все. Пусть все эти длинные команды дергают сборщики и средства автоматизации деплоймента.

Симфония это просто квинэссенция идеи делать простые вещи максимально сложным способом.

Симфони это просто квинтесенция идеи делать сложные вещи максимально эффективным с точки зрения разработки и процессов образом.

Резюмирую. Если я правильно понимаю, у вас не такой большой опыт работы с этим фреймворком (как минимум мало проектов на нем, если я правильно понимаю вообще только один проект на нем). Возможно для ваших задач он является оверхэдом. Что поделать. Подозреваю что под ваши задачи идеально подходит Laravel за счет более простой реализации и меньшего упарывания по всем этим DDD/BDD/TDD/Countinuous Integration and delivery которые вам нафиг не сдались.
UFO just landed and posted this here
Ну… из вашего комментария я сделал вывод что вам не нравится конкретно symfony/forms и assetic. Прелесть симфони в том, что это всего-лишь набор компонентов и не более. И использовать что-то из этого или нет решать вам. Скажем вы могли вместо symfony/forms сделать свой мэппер объектов на формы и обратно, или воспользоваться другими реализациями форм билдеров, альтернативы ассетика тоже есть.
UFO just landed and posted this here
Нужно все писать на Vanilla.js! Меня жутко бесят те 3-4 страничные приложения с 5-10 попап окнами которые сначала загружаются пол века, а после еще и жрут процессорное время своим рендерингом. Используйте пререндер на сервере и вставляйте кусками, как это сделал ВК.com.
Прежде чем тыкать на минус, тыкните меня носом в сайт, который использует React, Angular, Backbone, Ember и который так же быстр, как ВК.com.
UFO just landed and posted this here
Ладно, если мы разрабатываем хорошо масштабируемое серверное приложение, можно спокойно пожертвовать скоростью работы ради скорости разработки — докупим серверов и все будет отлично, железо дешевле программистов.
Ладно, если мы разрабатываем внутрикорпоративное приложение — оборудование под нашим контролем, всегда можно посмотреть у кого/почему тормозит, сделать небольшую оптимизацию, когда нужно.
Но когда речь заходит о веб, когда оборудование не под контролем, связь не под контролем, а «лишние» 10% пользователей могут принести дохода на 100 программистов — вот тут вопрос производительности встает в один ряд со скоростью разработки, и просто так жертвовать одним ради другого нельзя. Для прототипа/первой версии можно использовать фреймворки, но для полноценного приложения нужно что-то более специализированное.
Ну да… писать все на ванильном JS. Все с нуля. Даже если не учитывать тот факт, что среднестатистический фронтэндер без этих всяких реактов/бэкбонов и прочего сделает вам неподдерживаемую кучу гуано, которая будет жрать побольше (даже с учетом пререндринга на сервере) чем все эти ангуляры и реакты вместе взятые, подобным решением на ранних этапах жизни проекта мы сознательно увеличиваем риски, сроки разработки и соответственно стоимость заложенную в разработку. Причем это мы еще не знаем выстрелит проект или нет. Просто так. Потому что так делают в ВК. То есть если рассматривать вопрос с точки зрения продукт оунера, не думаю что вы бы остались довольны таким подходом к разработке.

С другой стороны… Можно реализовать проект на Angular/Ember/whatever, а затем заниматься оптимизациями и т.д. и как только мы поймем что проект не мертв и дает прибыль, вот тогда можно нанять армию фронтэндеров которые будут постепенно оптимизировать все и в конечном счете все придет к ванильному JS, с пререндрингом (хотя это не пререндринг, это препроцессинг шаблонов и только, разбирать все это добро в DOM и отрисовывать всеравно придется браузеру и тут уже больше влияет верстка и взаимодействие с DOM) и чем хотите.

Еще все забывают что верстка сама по себе может добавить лагов. Один лишний box-shadow на сложном бэкграунде и лаги при скроле на слабых девайсах вам обеспечены. А если еще поделка на ваниле будет постоянно reflow страницы вызывать то взвыть можно.

Как по мне не стоит вообще ориентироваться на начальных этапах на проекты из ТОП100 просто потому что вы так хотите. Лучше дешевле и быстрее выпустить продукт на рынок и затем уже заниматься плюшками.

Вспомните VK лет 5-7 назад. Он был намного менее сложный в плане реализации фронтэнда.
вроде 5 лет назад закос в эту сторону уже был… не помню… помню разбирался как там это все реализовано и помню что сделано все было очень просто и влоб.
Можно попробовать потыкать вас носом в проекты гугла. Там не то, что angular, там gwt найти можно.
Gmail и Youtube не так быстро загружаются. Все что быстро прилетает статика
Ну если у вас gprs может и медленно. JS не плохо кэшируется и выдается с кэша браузера.
Не вижу проблем с angular в этом смысле, я думаю у вас вряд ли получится написать лучше, чем написано там.
Кстати у гугла не только gmail и youtube
Было бы неплохо в статье все примеры сделать в сравнении с ReactJS, раз уж вы его так горячо рекомендуете. Сейчас ознакамливаюсь с документацией React — на первый взглядт те же яйца, что из Angular. Так же куча каких-то методов: getInitialState, getDefaultProps и т.д.
Во вторых серверные разработчики вообще не будут понимать, что творится на front-end'е и не смогут читать код.
Это многое объясняет. Если автор работает в окружении таких дубов, не удивительно, что и сам сделался ретроградом. У нас серверные разработчики за пару месяцев не просто вникли в Ангуляр, но и стали на нем полноценно писать и брать фронтендские задачи (c jQuery, backbone и проч. такого не получалось)
Angular как раз с прицелом на серверных разработчиков и пишется во многом. Они привыкли, что должен быть DI — вот им DI. Они привыкли, что внешние источники данных в тестах заменяются на Мокки — вот им мокки. И т.д. Все сдобрено словами Google и Enterprise — и все: орда джавистов, дотнетчиков и питонистов записывается в ваши поклонники!

Они и хорошо — гораздо лучше, когда люди из фронтенда лучше понимают бекенд, а люди из бекенда — фронтенд. Так и общий язык найти проще, и задачи быстрее выполнять.
Соглашусь с мыслью о том, что в Angular приходится решать много проблем, которые создает сам Angular. Тем не менее, применять его в больших проектах можно. Возможно, ошибка в проекте автора в том, что Angular пытаются применять не как SPA-фреймворк.
Конкретные перечисленные пункты не совсем корректны. Документация не такая плохая, минификация кода- это просто отдельная задача, структурно не относящаяся к проблемам фреймворка, разработчиков на Angular наоборот стало слишком много. Предложение не наследовать скоупы может принести столько же проблем, сколько решит.

Интересно другое — сравнение ресурсов разработки в Angular и не Angular проектах на запуск/поддержку/расширение. Предлагаю product owner'ам поделиться своими впечатлениями, в новых статьях. Как раз сейчас Angular стал стандартом выбора для многих молодых проектов, и информация для оценки всех стадий развития может быть полезной.
Во вторых серверные разработчики вообще не будут понимать, что творится на front-end'е и не смогут читать код.


Так можно сказать и про любой другой фреймворк. Для того чтобы понимать, что творится — нужно разбираться и не важно angular это или к примеру jsf, primefaces…
Angular, при всех его проблемах — просто-напросто более-менее юзабелен, и позволяет быстро писать красивый UI, в отличие от тонн jQuery-ада или вороха несовместимых между собой наколеночных фреймворков.
Раз статья вызвала такой ажиотаж, значит кому-то она оказалось полезной, или хотя бы интересной. Я учел комментарии, переработал некоторые моменты статьи, что бы более четко выразить свою позицию и охватить все аспекты. Спасибо всем критикующим, вы мне помогли сформировать более полное мнение об ангуляре и действительно подкорректировали мою позицию.
В вашем новом PS слишком много «я не хочу думать», в принципе это коче-что объясняет.

Я хочу думать о бизнесс-логике и о том какие задачи мне нужно решить по факту, но я не хочу думать о бессмысленных суррогатных коцептах

Вы тут либо лукавите, либо решили опять пострадать популизмом. Концепты бессмысленны для тех, кто не задумывался о смысле. Но разберем попунктно.

наследовании скопов

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

Если вы опираетесь в своей логике на наследование скопов, то такую логику становиться крайне сложно тестировать (нужно инициализировать еще состояние родительского контроллера).


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

когда нужно использовать односторонний или двусторонний дата-биндинг

я не хочу решать проблемы производительности

Ангуляр даже накладывает ограничения на то насколько богатый UI можно писать. И что самое интересное, это не какое-то эфемерное и далекое ограничение в которое вы никогда не упретесь. Это всего лишь 2000 биндингов, и если вы разрабатываете более-менее большое приложение, ТО ВЫ ТОЧНО УПРЕТЕСЬ В ЭТО ОГРАНИЧЕНИЕ.

Тут есть два аспекта.
Почему был выбран dirty checking и как обстоят дела с альтернативами.
Так вот, не хотите dirty-checking, придется иметь дело с «change listeners». Вам ближе второй подход? Нафига вы выбрали AngularJS, чтобы потом громко и так популистски кричать?

Второй аспект UX: 2000 биндингов — это 2000 элементов на странице, которые могут постоянно автоматически обновляться. Хм, не кажется, что с этим что-то не то? Как с количеством элементов (как у вас обстоят дела с проектированием UX?), так и с тем что все обязательно должно автоматически обновляться (это к вопросу, зачем нужен односторонний). Смотрите ка, я не совсем-то и в специфических терминах AngularJS рассуждаю, а в общем о подходе к построению UI. Вы не хотите об этом думать? Не уверен, что это что-то говорит о самом AngularJS.

когда нужно использовать compile, link, controller

Вы не хотите думать об инкапсулировании поведения в директивы. Бывают визуальные компоненты, бывают валидаторы, бывает повторно используемое поведение (всякие show/more и т.п.), которое можно один раз выделить, один раз протестировать и потом повторно использовать. У директив очень много аспектов применения. На этом держится львиная часть AngularJS. Но вы не хотите думать обо всех аспектах, проще голословно заявить «ЭТА СЛОЖНОСТЬ НЕ НЕСЕТ НИКАКОЙ ПОЛЬЗЫ. Нету логических причин разделять логику на 3 метода (compile, link, controller), все это можно легко реализовать в одном методе.» Успехов в реализации всего многообразия usecase-ов для директив с помощью одного метода.

когда мне нужно использовать value или constant, provider или factory

я не хочу думать о том, зачем нужны Provider для каждой внедряемой сущности и не хочу знать ничего о run и config фазах

Вам не нужна гибкость в настройке поведения вашего приложения в зависимости от определенных факторов (простейший пример, production/sandbox/beta)? Вам дали инструмент, как подобное делается легко и единообразно в рамках AngularJS. Оно вам не нужно? Ну не нужно, не задумывайтесь, используйте просто factory, если вам его хватает.

я не хочу думать о том, что делать когда я хочу интегировать натинвые события события в мир ангуляр

Это к вопросу подходов, если вам data-binding на dirty-checking вместе с декларативным подходом к UI не нужен, а хочется простого императивного подхода и change listeners, нафига вы выбрали AngularJS?

я не хочу думать о том увидел ли пользователь {{ скобочки }}

Разработчики прошли очень немаленький путь в сокращеннии необходимости написания boilerplate кода (алиасы к объявлению сервисов тоже к этому относятся), повышению читабильности и декларативности. К сожалению, иногда это приводит к тому, что люди не хотят задумываться о причинах добавления тех или иных фич, а думают только о своем одном уютненьком случае использования. Что наталкивает их на мысль, что все можно было сделать проще и не так.
Есть ng-bind. Если вместо скобочек всегда использовать его, то пользователь не увидит скобочки. И тут вам дали вариант выбора, где не надо, чтобы видели скобочки, используйте ng-bind или ng-cloak, а там где скобочки сразу не будут видны точно, то для читабельности можно и {{ }} заюзать (и таких случаев будет большинство, по-крайней мере в SPA и тут у меня потихоньку начинает появляться ощущение, что вы не SPA пишете). Но это же уже надо думать, что, где и когда применить — слишком сложно.

ГОСПОДИ, АНГУЛЯР ОТПУСТИ, ВЕДЬ Я НЕ В ЧЕМ НЕ ВИНОВАТ, ДАЙ МНЕ ПОЖАЛУЙСТА ПО ПРОГРАММИРОВАТЬ, МНЕ ЭТО НРАВИТСЯ.

Что, прям-таки пришел злой Angular, приковал вас и не хочет отпускать? Или вы его сами выбрали зачем-то?
Любая табличка с живыми данными (яркие примеры — эксельчик, календарь с расписаниями) и вы легко преодолеваете порог в 2000 элементов. Особенно, если монитор большой и позволяет показать сразу много данных без скроллинга.
Угу, и если большая часть вашего приложения такая, то надо грамотно выбрать инструмент, и в этом случае это, с большой вероятностью, будет не AngularJS. Если это одно состояние из сотен, а в остальном сильно хочется AngularJS, то с одной такой страничкой вы без проблем справитесь. Никто же не имеет ничего против того, что есть разные подходы и у каждого есть свои преимущества и недостатки. Но сравнение подходов — это не про эту статью.

И чтобы в одном месяце календаря получилось 2000 живых элементов, надо не менее 60 в каждой ячейке. Поэтому по поводу легкости преодолевания у меня пока все же некоторые сомнения.
С большой вероятностью AngularJS будет выбран потому, что миллион обезьян не может ошибаться, а по началу данных совсем не много. Со временем архитектурные просчёты выбранного фреймворка начинают все сильнее и сильнее бить по рукам. Но к тому моменту уже поздно что-то менять — написано куча кода, не отделимого от фреймворка. И приходится либо дальше мириться с ограничениями, либо всё полностью переписывать. Над архитектурой приложения нужно думать сразу и не полагаться на то, что «2000 жлементов хватит каждому».

В календаре далеко не один месяц. А в дне, далеко не один час.
В календаре далеко не один месяц. А в дне, далеко не один час.


И это тут случай, когда мы возвращаемся к проектированию UX. А также к вопросу «крайний случай» vs «обыкновенный случай». Никто не спорит, что на страницу можно вывести очень много, только зачем? Чтобы у пользователя глаза в кучку собрались? Или чтобы показать «архитектурные просчеты» фреймворка, которые на самом деле являются осознанным выбором и не скрываются ни от кого?

С большой вероятностью AngularJS будет выбран потому, что миллион обезьян не может ошибаться

Ничего глупее нельзя представить. Тем более, что еще неизвестно, у каких фреймворков армии обезьян больше :)
А давайте UX всё же будут заниматься специально обученные UX-еры, а не создатели JS-фреймворка?

Вы тут шутки шутите, а каждый второй проект сейчас начинается на AngularJS отнюдь не по причине его технологического совершенства.
А давайте UX всё же будут заниматься специально обученные UX-еры, а не создатели JS-фреймворка?

UX конкретного проекта будут проектировать не создатели фреймворка по определению. А вот почему создатели фронтенд-фреймворка не должны задумываться о принципах построения UI, я не понимаю. Кроме того, UX — это только часть того, о чем я говорил.

Вы тут шутки шутите, а каждый второй проект сейчас начинается на AngularJS отнюдь не по причине его технологического совершенства.

Я особых шуток тут не шутил, уровень аргументации просто на уровне популистких агиток, что с этим сделать можно?..

Кроме того, я не знаю, что такое «технологическое совершенство». Я знаю, что у каждого инструмента есть своя область применения. Если при выборе инструмента никак не учитываются его ограничения, то при чем тут фреймворк?

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

Даже уперевшись в 2000 биндингов (кстати, не факт, что эта цифра на данный момент именно такая, все же AngularJS развивается и оптимизируется), в небольшом количестве мест — это решается, причем изменения легко локализуются, тестируются и т.п. Если оно по-всему приложению так, то тут уж как ни крути, либо надо признать, что инструмент выбран неправильно и переписать. Либо вариант с кривыми руками тоже никто не отменял. С абстрактными рассказами про проблемы с производительностью никогда не поймешь, а точно ли причина там, где описывают.
О чём вы вообще говорите?

2000 это не жёсткий лимит где-то внутри ангуляра, а один из разработчиков однажды сказал что не очень разумно показывать юзеру больше 2000 элементов одновременно на экране, а потом его уже как только не перефразировали.
Хотите больше элементов — да добавляйте, ей богу.

Я писал уже что у меня есть проекты где отображаются тысячи элементов и ничего не тормозит, потому что я знаю что такое bind-once, как прятать методы от $scope и другие особенности.
ещё добавлю:
тем более это может замедлять когда много элементов внутри одного scope (и это не постоянно тормозит, а при выполнении каких-то действий и/или изменении данных), то есть если грамотно использовать директивы и/или контроллеры + отключать двойной биндинг где не надо (а он на самом деле в большинстве мест не нужен вообще), то никаких проблем вообще нет, будь у вас хоть десятки тысяч элементов.

Опять же все рассуждают про тысячи элементов, а привести пример навскидку сможете любого сайта, где несколько тысяч однообразных элементов выводятся? Я вот лично затрудняюсь, но зато раздули из мухи слона…
и ещё добавлю:
я переделывал на ангуляр в одном проекте 2 отчёта, где выводились десятки и сотни тысяч DOM элементов, там странички весили 2-50 мегабайт, так вот при таком количестве DOM элементов браузеры сжирали всю память и умирали в страшных муках, то есть с некоторыми данными отчёты вообще не могли отобразиться. Сначала сделал с ленивой подгрузкой и фильтром и всё залетало, потому что все эти данные стали отображаться частями, потом переделал на пагинацию, потому что была необходимость посмотреть в конце выбранных данных.
1. Выбираешь медленный фреймворк
2. Пишешь пагинацию и ленивую загрузку, что бы фреймворк не тормозил
3.…
4. PROFIT!

Можно было сразу выбрать что-то, что не тормозит и не насиловать себя.
Причем тут фреймворк если браузер сам по себе умирает при отображении DOM в 100К нод.
Не знаю, в 2005-м IE 5.0 не умирал при рендеринге всего списка БИК.

А в 2014 новомодный браузер от корпорации добра умирает.
Полный список БИК это статическая таблица где-нибудь в 10K строк или меньше, нет?

А теперь добавьте к этому постоянные reflow/repaint страницы вызванные изменением данных в ней (речь же шла о постоянных изменениях данных и их отображении).
нет, это 25 мегабайт чистого текста, без разметки. Разметка туда вставляется автоматически, примерно утраивая объём.
Как можно говорить «медленный», если нет кода? ЛЮБОЙ фреймворк медленнее native кода, любой native код медленнее оптимизированного native кода. Вы пишете на asm.js? Конечно же нет. Почему во всём мире уже почти не пишут на ассемблере? Почему по улицам не ездят на болиде «формула 1»? Скорость это далеко не самое важное, в программировании важно быстро писать работающий код (и тут то что вы записали в минус про то что неиницилизированные переменные не выбрасывают исключений превращается в плюс) + код должен быть легко расширяемым (тут декларативность ангуляра вне сравнений вообще, я тут уже писал что через месяцы я открываю код и быстро его меняю под новые требования) + надёжность/тестируемость (да, код должен быть надёжным и тут у ангуляра тоже всё в порядке).

У ангуляра нет проблем со скоростью, есть проблемы с руками у программистов, но эти проблемы никаким фреймворком не исправить, я видел сайты где backbone тормозил, хотя он очень лёгкий. Потому предлагаю скинуть код сайта где реально медленно работает и разобраться тормозит сам фреймворк или у программиста рак мозга.
Добавил React.js в местный «хабра-бенчмарк», в этом тесте он себя не важно показывает.

Это всего лишь 2000 биндингов
На jsperf есть тест скорости обработки $watch примитивов для Angular — на моем ноутбуке, Chrome обрабатывает 11М $watch'ей в секунду (1ops = 10k watch), поэтому проблем с 2000 биндингов быть не должно, чаще производительность будет упираться в DOM — а это проблема вне зависимости от фреймворка.
В хабра-бенчмарке надо бы до последнего 1.3 обновить, он получше в плане производительности, что впрочем видно и на jsperf.
Я немного поправил ваш пример для React.js, сравните ещё раз. На самом деле, я думаю можно ещё быстрее + было бы неплохо привести какой-нибудь более «толстый» пример (чтобы показать разницу в обновлении данных)
Ваш пример не учитывает время рендеринга — callback вызывается сразу, а не через setTimeout как во всех остальных примерах.
Тогда для справедливости нужно аналогично переделать все тесты, а некоторые фреймворки не будет возможности протестировать, например Knockout.js часть процесса «откладывает» через setTimeout и без таймера не замерить весь процесс.
А зачем в бенчмарке, в update(), render()? Оно же два раза будет перерисовывать. Хотя, похоже, на результат оно не сильно влияет.
Почему два раза?
Главное что-бы сравнивалось одинаковое — для одних фреймворков учитывается время рендеринга, значит и для других должно быть так же.
Так же там есть чекбокс «Take into account rendering time», который скрывает отрисовку.
Согласен, был неправ по поводу setTimeout(callback, 0) -> callback.call(null), однако поменяв этот кусок обратно, и просто убрав jQuery (который там вообще ни туда, ни суда, т.к. React в дефолтной конфигурации никак не зависит от него), у меня всё равно получается у ангуляра 3321мс на filling и 747мс на update для 10000 на раб. машине против 1589мс на filling и 727мс на update у React. И кстати, имеет смысл сравнивать не только время, но и размер памяти, выделяемый при этом сравнении. У меня angular съедает на 50% памяти больше (37,8Мб у React против 57.1Мб у Angular).

Выводы из этого сравнения:
В рамках тестирования на моей рабочей машине
— angular медленнее в первоначальном рендеринге данных на 100%
— angular и react одинаковы в скорости обновления этих данных
— angular съедает на 50% больше памяти, чем React

В заключение хочу сказать, что если бы часть данных оставалась такой же (т.е. не изменялась бы при операции update), то React показал бы более производительный результат за счёт своего diff-алгоритма.
Ну раз такая пьянка, то давайте еще уберем влияние jQuery на Angular (если Angular найдет jQuery он будет использовать его вместо jqLite).

На моем ноуте результаты примерно такие, с jQuery — filling ~ 960ms, update ~ 140ms. Без jQuery — filling ~500ms, update ~ 140ms. Для сравнение react в вашей версии теста выдает у меня ~ 520 при заполнении и ~ 130 на обновлении.
Хорошее замечание, поправил тест.
Теперь у меня в Chrome, Angular.js быстрее чем React.js по обеим полям.
Только, чтобы никого не смущать, надо внести правки, о которых указал lega в код React. Я сделал это тут. Действительно, angular выигрывает в производительности на этом тесте. Но было бы неплохо приблизить тест к реальным условиям, а именно:
— Добавить условие при обновлении (например, обновлять только чётные строки)
— Изменить дописывание в <li> на что-то более, например на <li><span class="first">{{ first }}</span></li> при заполнении и на <li><span class="first">{{ first }}</span>, <span class="second">{{ second }}</span></li> после обновления
— Удалять часть DOM-элементов (например, кратных 3)
— Добавить обработчики на <li> элементы

Лично мне было бы интересно сравнить выбранные библиотеки/фремворки на таком бенче, как считаете?
как считаете?
Да, мне тоже интересно, но как минимум этот тест ломать не стоит. Для начала, сделал «набросок» с добавлением DOM.
Тут у меня Angular.js быстрее в «update» для Chrome и Firefox, а React.js в Firefox быстрее по «filling», добавление DOM примерно одинаково.

По хорошему нужно добавлять разные тесты, а по текущим результатам можно сказать, что переход на React.js из-за скорости — не имеет смысла (нужны другие причины), тем более что узкие места в Angular.js можно переписать на vanilla JS который имеет наибольшую производительность.
Добавил свою старую либу: plnkr.co/edit/l6Rmz6VeydPjISIBAezZ?p=preview
Первичная инициализация довольно медленная (создаётся 100500 реактивных переменных с замыканиями, что даёт большую нагрузку на GC), зато потом все шустро — изменения применяются хирургически.
Бестолковый тест. Он фактически измеряет скорость доступа к 3 полям объектов. Конечно это плёвая операция. В реальном приложении $digest будет пропорционален объёму наблюдаемых данных, а их может быть чуть менее, чем дофига. Например, в последнем разрабатываемом мною приложении нужно было следить за данными порядка 50000 значений. Кроме того, $digest повторяется от 2 до 10 раз. Так что 11M можно смело делить на 100K и в результате получить жалкие 110 dps. И это только для того, чтобы узнать «а не изменилось ли чо», без какой-либо полезной нагрузки.
Мне кажется что реализовывать отслеживание 50000 объектов через dirty-checking это как-то слишком в лоб. Я слабо представляю зачем вообще это нужно делать. У вас все 50000 объектов могли измениться в любое время и нужно было на это как-то реагировать? Не могли бы вы конкретизировать пример.
Именно так. Есть список на несколько тысяч элементов, сгруппированный и отсортированный по некоторым правилам. В любой момент модели могли поменяться, от чего требовалась бы пересортировка списка.

Просто если все это происходит из UI то все 50000 одновременно поменяться не могут. 50000 элементов все же тоже не особо шустро отрисовываться будут.

Короче я просто думаю что если у вас настолько специфичные задачи — расчитывать что стандартные решения справятся с ними так же как и со всем остальным как-то наивно.
Одновременно не могут. Но чтобы узнать что поменялось нужно несколько раз прогнать $digest.
Отрисовывалось разумеется только то, что попадает в видимую область, а вот чтобы узнать что попадает в эту область и нужно провести пересортировку.

Именно поэтому Angular не годится для написания контроллеров — только для вьюх и годится. Но на этом поприще его уделывает тот же React.
Но чтобы узнать что поменялось нужно несколько раз прогнать $digest.
Но на этом поприще его уделывает тот же React.
А вот и нет, в Angular нужно всего лишь прогнать $digest, когда в React.js нужно заново построить целый virtual-DOM (в render), после чего который пойдет в diff-обработчик — это значительно медленней.
Вот вам тест где это видно (второй тест update не производит модификаций), в итоге на этом тесте Angular работает в 20 — 25 раз быстрее чем React.js
это вы фантазируете. А у нас банальная смена ангуляра на реакт помогла решить эту задачу в лоб, без специфичных решений.
Ну наверное для подобных задач react.js и подходит лучше, но это крайне нетипичная задача и говорить что «Именно поэтому Angular не годится для написания контроллеров — только для вьюх и годится» как-то непрофессионально, я вот оперирую большим количеством данных и с отображением такого количества объектов в интерфейсе не встречаюсь.

P.S. что у вас за задача-то такая можно посмотреть?
А не думали не менять а добавить реакт? Или нормально ватчеры сделать? Профит реакта как по мне в том что он заставляет думать а не писать что-то типа $scope.watch(object, fn, true).
Вот за «нормально ватчеры сделать» в частности от ангуляра и отказались.

Как только его начинаешь оптимизировать, что бы он шевелился, он превращается в обычный jquery.
Ну да… обычный такой jQuery… где все изолировано и все можно покрыть тестами. Я не представляю как можно убить все предоставляемые ангуляром фичи «оптимизациями ватчеров». Вот честно…
Именно поэтому Angular не годится для написания контроллеров — только для вьюх и годится.


У вас $watch(..., ..., true) в контроллере на огромный объект или массив?
При передачи третим аргументом true angular при изменении объекта копирует его целиком и затем рекурсивно сравнивает на каждый $digest цикл с текущим значением. Так что сложность цикла $digest увеличивается на порядок, особенно если меняется только одно свойство из десятков тысяч. Можно разделить объект на кучу мелких например и трекать отдельные свойства.

Скажем так, 50000 маленьких ватчеров которые будут трекать значения работать будет быстрее чем один по описанной выше схеме. Так же можно эти 50К ватчеров рассовать по маленьким скоупам и вместо жирного $apply делать им $digest.
Убить производительность? Ну можно не только количеством или размером наблюдаемого объекта, но и тяжелыми операциями в watchExpression или listenerFn. Да мало ли способов можно придумать.
У меня похожая ситуация. Список из 700 потоков в интерфейсе видеостримингового сервера.

у каждого стрима порядка 20 свойств, которые меняются во времени. Ангуляр такое вообще прожевать не смог, переделали на реакт, летает пулей.
И как человек может одновременно смотреть эти 700 потоков?
Элементарно. Админ анализирует состояние системы.
А что означает «прожевать не смог»?
jsfiddle.net/49d84pjq/

Как и с какой периодичностью изменения моделей происходили?
Вы вообще определили, где затык то был?
Раз в секунду обновлялась статистика по потокам. Затык в ангуляре. Где конкретно — не скажу, не смогли померять.
А что означает «прожевать не смог»?

Вис на обновлении? 700 запросов к серверу единомоментно слали? Отвисал в конце концов?
страница не может отрендериться. Запрос к серверу один, рисуются его результаты.

Отвиснуть оно не может, потому что раз в секунду запросы шлются.
На основании нижепроведенных исследований, вполне возможно, что вашу проблему мог бы решить track by :-/

В этом случае у вас висло все из-за постоянного удаления/добавления большого количества DOM-а. У вас не обновлялись, а пересоздавались элементы.
вполне возможно. Но мы уже переписываем на реакт и довольны =)
на самом деле скорость была не единственным критичным моментом. Второй момент — ангуляр очень сильно подталкивает к скрытой связности и полуглобальным переменным. Не очень хочется.
Это как же? Какие такие «полуглобальные переменные»?
связывание компонентов через $watch полей на одном объекте, который между ними передается.
Ну прям серебрянная пуля :-) Почему же track by не используется по умолчанию?
Как ответил Флоранс, track by хорош только в тех случаях, когда мы знаем, каким образом будут изменяться данные с течением времени.
Обычно мы это знаем все же и мне казалось что при работе с reactjs мы тоже должны это учитывать. Надо все же поковырять реакт потому что высказывания на подобии этих вызывают у меня сомнения.
Да, мы действительно обычно знаем, какие данные нужно отобразить и как они изменятся. Но тут акцент не на это, просто два разных подхода к решению задач: angular просит нас указывать ему, каким образом у нас будут изменяться данные, на основе чего он выбирает оптимальный путь к отображению этих данных (обновление связанного с данными DOM элемента или полная перерисовка). React же не требует от программиста дополнительных инструкций — он просто построит виртуальный DOM для новых данных и сравнит его с текущим (иногда можно ешё на этапе получения данных проверить на наличие изменений и установить shouldComponentUpdate на false в случае отсутствия онных. Это отменит процесс построения вирт. DOM и нахождения разницы между ним и текущим состоянием). Оба подходы имеют право на жизнь и существенно не влияют на скорость или качество разработки ПО (разве что косвенно).
trackBy используется по умолчанию в виде:
<li ng-repeat="item in list track by $id(item)"


Именно по этой причине если мы заменяем значения в коллекции а не всю коллекцию все работает быстро. К каждому элементу коллекции добавляется пропертя $$hash по которой идет мэппинг с DOM.

Если скажем у нас массив скаляров — это уже работать не будет и тогда придется написать track by $index. Если в коллекции у нас массив айтемов у которых есть свой уникальный идентификатор, то можно указать его что бы не пересчитывать hash объекта на каждый чих.

trackBy не серебряная пуля. Скажем в случае если у нас прописан track by item.id и каждый раз генерируется новый список уникальных айтемов — все будет грустно. С другой стороны если мы будем привязываться к $index и постоянно менять количество айтемов в коллекции (например фильтр), то так же DOM будет довольно часто перестраиваться и тут уже имеет смысл привязываться к ID записи в коллекции.

Но эта штука позволяет покрыть 90% всех возможных проблем связанных с отображением коллекций. А обычно мы все же знаем как данные будут обновляться и что мы там храним.
Вот видео с конференции React.conf, которая была несколько дней назад (смотреть с 02:30), где можно посмотреть в сравнении ember.js, angular.js и react.js для большого количества динамически обновляющихся данных и поставить точку в споре о производительности.
Do not trust benchmarks you didn't fake yourself.
made my day, особенно оговорка про «fake yourself»
Это не оговорка.
Я имел ввиду, что это сделано специально, не предполагая опечатку.
Вы оригинально выбрали ветку :) По-моему, ваше видео только подтвердило, что AngularJS вполне спокойно «прожевывал» адекватные параметры. Обновление с нулевой задержкой прожевал тоже, но похуже react. Но в общем-то, вряд ли кто-то сомневается, что у dirty checking предельные параметры хуже, чем у change listeners. Свои плюсы, свои минусы.
Angular не может делать простое обновление текста медленее чем React, даже в теории (см. тест выше, и это не первый такой тест в интернете), скорее всего у Angular идет полное перестроение таблицы на каждой итерации. Где можно найти исходники этого теста? я уверен что там Ангуляр не оптимально использован.
aav Не соглашусь с вами — таблица из 100 строк с временем обновления в 1 секунду должна просто летать, а у angular'а начинаются проблемы уже на этом моменте. Я не считаю это каким-то надуманным кейсом. Как и говорит сам Райан, это их реальный кейс: кластер на 100 серверов и они хотят отслеживать изменение их состояний так быстро, как это возможно.

Fesor Пока сам не попробуешь — не узнаешь, я согласен. Но не думаю, что facebook будет подделывать тесты и подставлять свою репутацию ради пятиминутного видео сравнения производительности.

lega Я не думаю, что просадка происходит из-за обновления DOM'а, скорее из-за dirty-checking'а (о чём, кстати, говорит Райан Флоранс на видео).
Извините, невнимательно вслушался, там сначала говорится, что все ок, потом под конец что-то возникает. Вдвойне интересно было бы глянуть на исходники. 100 строк — это обыкновенный кейс, на котором я проблем у нас даже на мобильных платформах не получал.
Можно попробовать воссоздать подобный тест. Судя по тому, что это написано для мониторинга серверов Facebook, вряд ли у нас будет открытый исходный код.
Когда вы говорите о 100 строках, вы подразумеваете возможность изменения данных каждой ячейки раз в секунду? Есть ли в ваших таблицах зависимости между полями?
скорее из-за dirty-checking'а
Нет, dirty-checking очень быстрый — до 10М watch в секунду на современном железе — см. тест выше

не думаю, что facebook будет подделывать тесты
Не обязательно подделывать, можно просто сделать «равные» решения, т.е. просто отрисовку нового массива который прилетел с сервера, для React это будет нормально, а для Ангуляра это не оптимально, для него нужно немного не так.

Вот сделал подобную таблицу где Ангуляр «отрисовывает» таблицу 7х100, у меня на ноутбуке выдает ~105 fps.
Было бы не плохо если кто-нибудь сделает аналог на React.
Вы ссылку на AngularLight дали.
Да, Ангуляр лайт, на Angular.js будет примерно так же.
Вот аналог на React.js, на этом примере в хроме он работает в 2 раза медленее чем Ангуляр.

и поставить точку в споре о производительности.
xamd, точку можно поставить, но завтра появятся другие люди которые будет доказывать что React.js быстрее. Я в интернете периодический натыкаюсь на сравнения где кривое приложение на Ангуляре проигрывает Реакту.

Как я тут написал, переход на React.js из-за скорости — не имеет смысла, хотя в нем есть интересные идеи.
Данные всё же обычно не поэлементно устанавливаются, а приходят в виде JSON. По какой-то причине, ангуляр начинает тупить при замене объекта (по всей видимости, не найдя идентификатора в объекте он его перерендеривает целиком, вместо обновления текстового значения)

ReactJS с заменой JSON ~50fps
AngularLight с заменой JSON ~10fps
AngularLight c передачей данных из нового JSON в существующий ~80fps

Получаем, что в случае с ReactJS мы можем обновлять данные как нам удобно и быть уверенными, что скорость не просядет. А в случае AngularLight приходится выбирать между скоростью и удобством.
Дело в том чтобы эффективно использовать инструмент, нужно в нем разбираться. В этом плане React.js попроще, и это один из его плюсов.

не найдя идентификатора в объекте он его перерендеривает целиком, вместо обновления текстового значения
Да, если идентификатор не найден или он другой, то объект считается другим — и так оно и есть, поэтому под него создается свой scope и DOM, т.к. предыдущий DOM принадлежит другому объекту и возможно где-то используется.

Данные всё же обычно не поэлементно устанавливаются, а приходят в виде JSON.
Во многих приложениях данные прилетают, и пользователь с ними работает без «перерисовки», тут просто задача такая.

Вообщем с Ангуляром нужно применять голову (как и везде), для вашей проблемы есть несколько решений именно под эту задачу, вот например немного поправил ваш пример, и Ангуляр опять на высоте
Согласен, как я ни старался затюнить пример с React'ом, выше 50-55 операций в секунду (а не fps, к слову), не получается. Angular light на этом же примере показывает 55-60 операций в секунду. Посмотрим, может получится достать исходники Райана чтобы сравнить…
Offtopic: Тут пока соберешься что-нить ответить — уже то, что хотел ответить, устаревает :)

Я просто подумал, что Вы случайно ссылку попутали. С AngularJS, действительно, непринципиальное отличие.

Вам впору топик писать по особенностям производительности AngularJS и React :)
Никогда бы не подумал, что они на этой задаче наравне будут.
В реальном приложении $digest будет пропорционален объёму наблюдаемых данных


Да, и в AngularJS единица наблюдаемых данных и есть $watch. Так что ваши арифметические операции не очень понятны. Ладно бы на 2-10 поделили. Но зачем вы поделили на 100К?
Потому что стоимость выполнения $digest пропорциональная числу наблюдаемых данных.
А, мда, просто я это воспринял, как аргумент бестолковости теста. Тест как тест. Вполне себе дает общее представление о производительности. В частности, при 50000 watch-ей и 10 проходах на $digest приближаемся к критическим 50мс.

Хотя все равно непонятно, зачем такие задачи в лоб через $watch решать.
Всё, о чём он говорит — это, что код «scope.a.b.c == prev» выполняется 11M раз в секунду.

Как бы вы решили эту типичную задачу?
Это НЕ типичная задача.

Начал бы решать с выяснения, что именно тормозит. Если $digest не укладывается в 50мс, то профилировал бы, за счет чего не укладывается.

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

А я вот не занимался этой ерундой, так как не использовал Angular :-) А вот что я на нём делал, так это эксель на 2500 ячеек с простыми формулами — мягко выражаясь не летало. А как бы вы это реализовали?
А вот что я на нём делал, так это эксель на 2500 ячеек с простыми формулами — мягко выражаясь не летало. А как бы вы это реализовали?
По хорошему, большие таблицы делают как «viewport», т.е. строится только видимая часть ~20х30 ячеек с учетом скролинга — т.е. данные подстраиваются под скролинг.
А если там было-бы миллион ячеек, вы бы тоже все на страницу вывалили бы?

И как у вас получилось 50к watch'ей из 2500 ячеек?
Вы забываете, что ячейки — они не в вакууме находятся. Они связаны друг с другом формулами. Ангуляр не трекает зависимости, поэтому, чтобы реактивно распространить изменения, ему приходится перебирать все ячейки. Вообще все, а не только те, что попадают в видимую область.

Про 50К — это другой проект, про менеджмент проектов.

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

Теперь кажется понятно почему Ангуляр тормозил, вы делали «реактивное» пересчитывание на $digest циклах.
Ангуляр не для этого, можно было бы сделать так: при изменении значения, вызывается FRP библиотека которая моментально просчитывает все зависимости, после чего Ангуляр делает два $digest — изменения выводятся в html.

Как вам в этой задаче (пересчет зависимостей) помог бы React.js?
При чем тут написание контроллеров в Angular? Просто на определенных задачах нет смысла применять dirty-checking. Но Angular — это не только dirty-checking.
Типичная задача — загрузить все данные, чтобы их потом можно было сортировать/фильтровать/группировать на клиентской стороне? Ведь, если не все загружены, то при сортировке/фильтрации будут затронуты и те, что с сервера не подтянули. Это не выглядит типичной задачей.

Такой «ерундой» я тоже редко занимаюсь, т.к. мне не приходит в голову делать deep-watch на объект/массив с 50000 значениями.

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

Массив на 5000 элементов с 10 полями в каждом — не такие уж и большие объёмы, чтобы гонять безконца запросы к серверу.

Расскажие, как бы вы сделали этот граф? И какой прок остался бы после этого от Angular?
Еще раз — если вы грузите все данные, чтобы можно было делать на клиенте сортировку и фильтрацию, то ничего типичного в этом нет. Либо какая-то ваша специфика, что данных вряд ли будет больше и они редко добавляются. Либо как-то это все страньше и страньше звучит. Сегодня у вас 5000 элементов, завтра 100000. И я все меньше начинаю понимать, зачем там в контроллере нужен deep-watch (watch(..., ..., true)) на один объект/массив со всеми этими данными.

По Excel-ю — если это отдельное приложение, в котором ничего кроме непосредственного табличного процессора нет, то AngularJS там и не сильно нужен. Выше уже несколько раз писал, что выбор инструмента под задачу никто не отменял. Если это небольшая часть большого приложения, и табличный процессор там нужен в очень ограниченном виде, то почему бы и нет. Но это не значит, что надо сделать один большой объект — модель документа и повесть на него deep-watch. Но садиться и писать сейчас мини-Excel с использованием AngularJS я точно не буду в силу отсутствия времени. Хотите, выкладывайте свой тормозящий вариант, думаю, и помимо меня найдутся люди пооптимизировать/поправить.
Задача «отображать список в актуальном состоянии, оперативно реагируя на действия пользователя» — вполне типичная.
А вот решение этой задачи «загружаем все необходимые данные в клиент и оперативно престраиваем список» — нет. Оно годится, лишь когда данных не запредельно много. У нас была специфика (опять же, довольно типичная): несколько десятков тысяч задач в аккаунте — максимум, несколько тысяч задач в списке — в среднем. В этих условиях можно позволить себе более динамичный интерфейс, живо реагирующий на действия пользователя.

Запилил эксельчик на ангуляре: jsfiddle.net/h68wuy19/5/embedded/result/ (результаты в профайлере)
Я не спорю, что всегда можно вставить костыли, но зачем использовать инструмент, которому эти костыли нужны, если можно изначально не раскладывать себе грабли?
Ой, правильная ссылка такая: jsfiddle.net/h68wuy19/6/embedded/result/
Кстати, в эксельчике пришлось вставить ограничение на длину цепочки зависимостей, равное 8, иначе ангуляр бросает исключение. А если бы не бросал, то отрабатывал бы это ещё дольше (+1 digest на каждый уровень зависимостей). Даже KnockOut при всех его косяках в этих условиях справился бы куда быстрее.
Мы с вами выше уже выяснили, что Ангуляр не для FRP, вот переделанный ваш пример, где Ангуляр отрисовывает таблицу за 2мс, а FRP/математику (ф-ия changedCell) можете сделать например на $jin.atom :), тут вы скажите «зачем мне тогда Ангуляр», а он вам для быстрого/простого построения приложения.

Расскажите лучше чем React «уделывает» Ангуляр.
Ангуляр ничего не делает за 2 мс, да.

Но когда приложение начинает расти, данных становится больше, зависимости между ними становятся сложнее и запутаннее, а коней уже поздно менять, потому что написана уже груда кода.
Ангуляр ничего не делает за 2 мс, да.
Ну почему ничего, он отрисовывает таблицу, 2500 ячеек.

Но когда приложение начинает расти
Так оно, но приложения так же могут расти не только в сложности, но и в «ширь», т.е. просто увеличивается кол-во несвязанных формочек, и для большинства приложений хватает 2-4 $digest цикла.
C FRP это будет сложнее и медленее имхо, так что Ангуляр свою нишу занимает.
2500 ячеек он отрисовывает за четверть секунды.
image

А 640кб хватит всем :-)
2500 ячеек он отрисовывает за четверть секунды.
Не нужно указывать именно на Ангуляр, на других фреймворках будет примерно сопоставимое время.
Тем более это первое построение, а обновление проходит за считанные миллисекунды — это вполне хорошая скорость.

У меня в хроме так:
Первичное построение DOM, 115мс (+ 30мс на рендеринг)
Обновление одной строки: 1-4мс (это поиск изменений в модели и синхронизация с DOM)
О, вы прогрессируете, не только повесили deep-watch на большой объект, но и в listenerFn положили полный пересчет. В принципе, с одной стороны было бы классно, если бы фреймворки самостоятельно выбирали оптимальные алгоритмы, самооптимизировались и т.п., щелкнул пальцем «По щучьему велению» и получил результат. Правда, тогда бы и ЗП пониже были, как думаете?

Как-то так получилось, что все последнее обсуждение хоть и содержит постоянно слово AngularJS, но по сути сводится к обсуждению dirty checking и его использованию не к месту. А когда вы говорите про Knockout, я так понял, вы подразумеваете change listeners. Это два альтернативных подхода к отслеживанию изменений. И самое хорошее, что никто не мешает применить change listeners или что-нибудь другое в AngularJS под нужную задачу.
А как тут обойтись без полного пересчёта, если ангуляр не трекает зависимости?

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

image

По пунктам:
— кто-то изменил данные модели задачи
— изменилось свойство «заголовок» модели задачи
— изменилось свойство «заголовок» презентёра задачи
— изменился состав элементов в отображении задачи (хз, что поменялось, наверно баг)
— изменился текст в элементе «заголовок»
— отрезолвился какой-то промис (хз, что за креатив)

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


Вместо dirty checking? Нет, спасибо. Кому охота иметь всякие ko.observable(), ko.computed для всех задач вместо POJO, могут спокойно Knockout и выбрать. Вроде никто не мешает. Кому охота flux-style со всеми listeners, dispatchers и т.п. — тому в React. Есть выбор и это хорошо.

В дополнение? А что мешает подключить библиотеку не от создателей AngularJS?

И не заставляйте меня подбирать разные решения для одной и той же задачи синхронизации состояний :-)

Прозвучало как «не заставляйте меня подбирать способы хранения графа и алгоритмы по работе с ним». Есть разные способы, у всех свои преимущества и недостатки. Каждый выбирает, какой лучше подходит под задачу и больше нравится в использовании. Мой выбор — для большинства задач писать чистый (POJO) модульный тестируемый код с использованием AngularJS, там где упрусь в ограничения — применю локально альтернативные подходы, предварительно изучив как подобную задачу уже до меня решали.
POJO не проверит валидность данных (ловить ошибки вы будете не в том месте, где они совершены).
POJO не сообщит об отсутствующем поле (просто вернёт undefined)
После изменения POJO нужно не забывать вызывать $digest для всех зависимых от него скоупов.

Не заставляйте меня одну и ту же задачу (синхронизация состояний) в разных местах решать разными способами и огребать проблемы для их стыковки.
POJO не проверит валидность данных (ловить ошибки вы будете не в том месте, где они совершены).

Надо будет — проверит, не надо — не проверит. Как напишешь. Валидность я буду проверять в первую очередь в момент ввода.

POJO не сообщит об отсутствующем поле (просто вернёт undefined)

Об этом мне сообщат тесты.

После изменения POJO нужно не забывать вызывать $digest для всех зависимых от него скоупов.

Вы тут что-то странное написали. Во-первых, после изменения извне контекста AngularJS — не такое уж частое явление. Во-вторых, вы так написал, как-будто там чуть ли не вручную надо зависимости прописать и каждый раз что-то по-разному вызывать.
Вот именно, что как напишешь и не никаких гарантий. Именно поэтому в мире ООП не принято давать доступ извне к полям объекта — только через методы.

А могла бы сообщить IDE ещё в момент компиляции.

Обновление данных по сообщениям с сервера и из других вкладок — не такое уж и редкое явление.

А, ну да, в ангуляре же не принятно применять скальпель — только $rootScope.$broadcast, только бензопила :-)
кастыль это deep-watch.
Реализуйте без него, пожалуйста :-)
Я бы «эксельку» делал так:
— зависимости по ячейкам можно вычислить при разборе выражений (формул)
— для разбора выражений можно воспользоваться сервисом $parse и передавать в результирующую функцию свой контекст со всеми реализованными функцими типа SUM, ADD, POW и т.д. Так же автоматом хэндлятся все мат выражения и т.д. Ну и полная изоляция, можно покрыть тестами всю логику и т.д.
— По зависимостям строить граф и при изменении какой-то вершины обновлять всех кто от этой ноды зависит.

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

Теперь view — выводим мы таблицу всю через ng-repeat, который для нашей задачи можно заменить на какой angular-virtual-scroll который уменьшит количесво ватчеров до n*m, где n и m количество наблюдаемых в данный момент рядов и колонок соответственно. Опять же директива сама по себе покрывается тестами и никак не зависит от логики нашей эксельки.

В итоге выходит какая-нибудь такая наркомания:
codepen.io/anon/pen/qEPyWK

Сами понимаете делать нормально граф зависимостей мне было откровенно лень. Так же как и хэндлинг пограничных условий. отлов ошибок, да и редактирование выражений тоже… Так же я ничего не делал с ng-repeat.
Пока все зависимости остаются в рамках ячеек ваш костыль с ручным трекингом зависимостей работает. Но стоит ввести зависимости от внешних моделей и тогда придётся дружить ужа с ежом. Примеры функций:

=USER.NAME — имя пользователя, открывшего эксельчик
=TASK#123.TITLE — название задачи под номером 123
=NOW.HOUR — текущий час, обновляемый в реальном времени
Опять же, изменения во внешних источниках должны эмитить изменения ячеек. Тут можно использовать ватчеры, а уже по изменению эмитить апдейт ячейки и удалять ватчер как только от этого значения никто не зависит. Конечно круто взять и навесить жирный deep-watch на объект и не париться о том что какие-то значения будут изменены, написать три строчки кода и думать что «какого черта это медленно работает! Angular медленный!».

Я прекрасно понимаю что подход с $digest не сильно подходит для подобных задач, да и в Angular2 derty-checking будет использоваться только как фэлбэк для браузеров не поддерживающих Object.observer. Но опять же компоненты подобные можно реализовать как отдельный модуль со своими директивами и сервисами, внутри которых хоть на react.js делайте хоть еще как.
Каким образом Object.observer тут может спасти?
нет цикла $digest, действие можно совершать только по непосредственно изменению а не «в холостую».
в Angular2 derty-checking будет использоваться только как фэлбэк для браузеров не поддерживающих Object.observer
Кстати на счет Object.observe, он не может покрыть все юзкейсы derty-checking, например {{value()}}, он не сможет отследить что произошло в ф-ии, а вот как раз для массивов может быть эффективно применен (даже мог бы для Angular 1.3+). Так же Object.observer сам по себе медленее (для малых scope), так что вполне возможно derty-checking будет основным в Angular 2, но с максимальным использованием Object.observer.
О, я слишком быстро решил ответить и отвечал на

Потому что необходимо 50000 watch-ей или же 1 watch на структуру из 50000 значений. Особой разницы нет, разве что второй вариант куда экономней.


Но раз уж пошли в сторону уточнений, то $digest еще зависит от сложности вычисляемых условий каждого $watch-а. Потому рекомендуется иметь «легкие» (быстро-вычисляемые) условия для $watch.

Сам же тест фактически дает оценку сверху — максимальная производительность в текущей среде (браузер, ОС) при максимально легких (но в тоже время весьма типичных для шаблонов) $watch-ей.
Типичный ватч это
return currentValue === lastValue;


Меня больше интересует почему люди делают вывод в духе «angular для этой задачи не подходит» в то время как речь идет только об одной (пускай и одной из основных) его фич, причем для кейса, на который эта фича не расчитана.

Если данные меняются из UI и в один момент времени могут поменяться не все а скажем только 1000 айтемов в коллекции — следить надо за этой 1000-ей айтемов а не за всеми 50000. Angular предоставляет вам возможность:
— написать один кастомный ватчер для всей коллекции который можно использовать как сервис, покрыть тестами и реюзать.
— написать директиву которая будет сама это дело мониторить на основе каких-то ивентов в DOM и любых других способов определять что кто-то что-то изменил и обновлять не весь $rootScope а делить все на скоупы поменьше и запускать для них локально $digest.
Вы не уловили суть проблемы. Чтобы узнать какие 100 айтемов сейчас показывать нужно проверить не изменилось ли одно из 50000 значений.
Я не улавливаю почему мы должны по данным судить что сейчас видно.
Потому что сортировка/группировка/фильтрация по значениям.
Т.е. вы переложили работу модели на представление и удивляетесь, почему у вас тормозит?
Сортировка, группировка и фильтрация — это работа модели представления. В Angular модель представления находится в scope контроллера.
Сортировка, группировка и фильтрация — это работа модели представления.

Конечно же, это не так. Эти функции почти всегда связаны с моделью-моделью, кроме исключительно редких случаев, когда все данные загружены в модель представления. Причем, очевидно, что если в редкий случай попали огромные списки, то это ужасное архитектурное решение, так как их размер может стремиться к бесконечности.
Так, например, браузеры уже давно не отрисовывают промежуточные изменения.
Это именно так. А вот просачивание этой логики представления в модель — оптимизация, которая не всегда к месту.
Т.е. аргумент про бесконечность вы опустили за ненадобностью?) Т.е. если у вас в базе 3 миллиарда строк — вы выгрузите их все в представление скопом, чтобы влегкую делать там сортировку? А потом будете говорить какой плохой AngularJS? Ну, собственно, вы так и сделали, что я спрашиваю)
$digest повторяется от 2 до 10 раз.
Если ничего не изменилось, то $digest, отрабатывает 1 раз, в Angular Light даже если что-то изменилось, то в лучшем случае будет тоже 1 раз.

нужно было следить за данными порядка 50000 значений
Для не стандартных задач можно делать свои директивы которые например будут работать через Object.observe
Если ничего не изменилось, то и $digest вызывать не стоит.

Тогда зачем мне Angular? :-)
Например, если мы обновили (перезагрузили с сервера) данные, но не известно есть ли изменения.
Если ничего не изменилось, то зачем загружать заново данные с сервера?
На jsperf есть тест скорости обработки $watch примитивов для Angular
Если кому интересно, сейчас в разработке Angular Light + Object.observe, добавил на jsperf первую бета версию, для этого теста Chrome показывает неплохой прирост производительности.
Вот же ж где блин-то :) Не зря пятая точка подсказывала мну, что не стоит и начинать с Ангуляром…

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

Тогда появляется вопрос: а если на чистом JS плюс jQuery — проблем потенциально меньше будет?
UFO just landed and posted this here
Ок, поставим вопрос так: какие из них — по вашему опыту — более «достойны»? :)
UFO just landed and posted this here
Для меня критерий простой: изучение ЯП. Какого — вопрос.
С технической стороны все ясно, программист считает, что проще использовать фреймворк чем «чистый» js и предложил Angular.
UFO just landed and posted this here
Если у разработчика есть опыт работы с Angular а не на попробовать — то не вижу в этом никакой проблемы. Да и вообще думать надо головой а не пятой точкой.
В данном случае именно на попробовать — я только недавно начал изучать программирование.
я не о вас, а о том кто будет изначально делать проект. То есть если посадить новичка на проект в котором уже реализовано почти все основное, и написано это более менее по best practice или хотя бы с умом — и новичку будет проще и шансы зафэйлить все чуть ниже. Если же основу разрабатывали профаны в angular, то тут ничего не спасет от боли и сожалений при поддержке приложения. Хотя чудеса случаются.
Мы и будем. Настоящий :) программист серверную часть, мне нужно будет делать клиентскую.
Вопрос в том, что изучать дальше: сейчас я могу только PHP, но для клиентской части это вообще никак.
Ну тогда возможно Ember или Angular будет для вас правильным вариантом, ибо написать неподдерживаемый ужас на backbone/etc и уж темболее на js + jquery намного проще. Так есть хоть шанс что приложение будет структурировано. С другой стороны, если у вас не SPA — варианты разные появляются.
Нет, слегка посложнее: там и мобильные клиенты (со слегка другими функциями, нежели десктопные) и даже чуточку «интернета вещей».
В общем, рискну резюмировать: если вы собираетесь делать SPA, то используйте angular.js, будет быстро и просто: готовые архитектурные решения, высокоуровневое API, можно быстро развернуть из yeoman.io, вам де-факто нет необходимости лезть «под капот». Хотите рендерить с бэка и использовать JS только для свистулек/анимашек/прочего используйте jQuery, но имейте ввиду, что при больших объёмах jQuery ваш клиентский код превращается в лапшу, которую невозможно поддерживать (в меру отсутствия архитектурных решений со стороны библиотеки).

Если вы не планируете строить *реально большое приложение*, то проблемы, описанные в статье не будут вас трогать ни коем образом. У любых библиотек/фреймворков есть свои недостатки. И да, сравнивать jQuery с Angular'ом некорректно. Вы же не сравниваете php библиотеки и фреймворки?
Нет не «реально большое», так… немного математики плюс база данных плюс авторизация юзерей. Но однозначно не SPA.
Спасибо.
UFO just landed and posted this here
Ну так и есть, добавляем track by и все летает получше чем у react
Я сделал pull request, посмотрим.
Написал пост в ответ на статью. Думаю уже все обмусолили и обсудили многократно в комментариях, но все равно, так как я использую Ангуляр уже больше 2х лет, то решил тоже высказаться
Вы перепутали одноразовый биндинг с односторонним, а вот про лимит 2000.
по моему мнению AngularJS изначально не создан для огромных приложений
Что предлагаете использовать для огромных приложений?
односторонним

да, вы правы, спасибо, подправил
Что предлагаете использовать для огромных приложений?

честно говоря, пока так и не нашел ответа на этот вопрос.
для средних приложений с четкими требованиями можно использовать Ember.js.
а вот для Огромных, вероятно нужно будет пилить что-то свое на основе Backbone, React
для Огромных, вероятно нужно будет пилить что-то свое на основе Backbone, React…

То есть для огромных проектов вы предлагаете брать набор библиотек и пилить на их основе свой фреймворк. При том что вам никто не мешает взять Angular или Ember для организации основы, Backbone или любую другую библиотеку позволяющую выделить модели и слой по работе с данными и React для UI. Если для ветки 1.x выбор Angular еще может быть сомнительным в силу монолитности фреймворка, то вторая ветка построена как набор компонентов, чего так некоторым не хватало.
пока так и делаю с Angular, посмотрим к чему прийдем :)
Да, у количества вотчеров есть рекомендуемый лимит в 2000. Иначе будут тормоза. Это плохо.

Это не лимит. Просто довольно полезная мысль. Если у вас в приложении 2000 ватчеров — что-то пошло не так. Ватчеры в angularjs — инструмент быстрой разработки. Это эдакое решение в лоб. Для конкретных задач можно применить другие решения. Скажем выше описывался эдакий эксель и тут больше подходит другие средства. Выделяем все в директиву и не паримся. Внутри директивы может быть хоть jQuery хоть react.js хоть свой алгоритм… Словом, то что есть инструмент на котором вроде как можно реализовать задачу быстро, не означает что его нужно обязательно использовать.

Сам по себе цикл дайджеста (вместе с вотчерами) не медленный. Но если постараться, вы можете сделать его таким.

Именно так. Я помниться видел как-то модуль для работы с localStorage, где в комментариях к коду говорилось что-то о angular-way и все все все было обернуто в ватчеры с deep-watch. Это пример того насколько люди не верно интерпритируют задачи инструментов и подходы к разработке.

Что касается количество различных вариантов для сервис-провайдера – тут, конечно, с синтаксических сахаром перемудрили.

Да нет, все довольно просто. Хотите дать возможность задавать параметры сервиса на этапе конфигурации — пишите провайдер. Любите самостоятельно контролировать процесс инстанцирования сервисов (или же просто вам лень писать все эти MySecrive.prototype) — пишите factory. Используете ES6/кофе/typescript и пишите правильные сервисы — регистрируем конструктор сервиса в service и все хорошо. constant и value — просто какие-то параметры которые разграничивают на каком этапе что доступно.

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

по моему мнению AngularJS изначально не создан для огромных приложений

А есть хоть что-нибудь что создано исключительно для огромных приложеиний? А разве огромные приложения не состоят из множества маленьких? Мне кажется этот момент вообще никак не стоит учитывать — большие приложение это результат построения грамотной архитектуры с учетом возможностей средства разработки. И Angular более чем для них подходит.
Благодарю, за подробный комментарий!
UFO just landed and posted this here

Articles