• Год использования ReactJS: подводим итоги
    0
    http://localvoid.github.io/kivi-dbmonster/?m=0.001&n=5000

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


    Жду пруфов о том какой невероятной скорости вы добились в вашем фрэймворке на «create» и «clear»

    кажется вы не слишком внимательно читаете, я как раз без проблем признаю, что в создании/удалении мой подход будет медленнее, а вот у вас с признанием недостатков похоже проблемы. Какой смысл использовать вашу реализацию, если вы не готовы признавать её очевидные подводные камни. Сколько их там ещё? Для реакта они хотя бы нормально описаны в Интернете, прощупаны многими самостоятельно и есть отработанные костыли для их обхода.


    Давайте по пунктам:


    1. есть ситуации в которых vdom начинает рендерить/диффать слишком много лишнего, что может приводить к тормозам и без костылей в коде проекта не решается.
    2. в этих же ситуациях точечный биндинг — это просто запуск чего-то легковесного (ячейки в случае Rionite) и обработчика из одной строчки: github. Очевидно, что у такого подхода никаких проблем с производительностью не будет.

    Если есть нормальные контраргументы, я вас слушаю, но не надо кидаться в меня очередными тестами или мнением очередного "авторитета".
    Если вы нашли хороший способ избавляться от лишнего рендера/диффа, расскажите как, то что вы предложили выше — костыли похлеще тех, что использую я, видимо специфичны для вашей реализации. По крайней мере такой жести:


    используем внутренние часики и проверяем по дате модификации

    я ещё ни у кого не видел.

  • Год использования ReactJS: подводим итоги
    0

    Ну, я выше рассказал, почему я выкинул VDOM))

  • Год использования ReactJS: подводим итоги
    0
    Ну так у меня на входе поток данных, который посылает сообщения о том что табличка изменилась. Всё вполне реактивно.

    ok, раз вас всё устраивает, значит так и оставьте))


    Получается медленей так где итак всё тормозит

    ну, можно относиться иначе: на 1-2% медленнее в тех местах, где и так тормозит и не плохо бы воткнуть какое-нибудь сообщение о загрузке.


    зато пытаемся ускорить кэйсы на которых всё спокойно отрабатывает втечении одного кадра

    Эх, если бы это всегда было так))


    и лишь только ваш личный опыт с реактом

    не только мой личный, это опыт большой команды в компании продуктами которой вы с большой вероятностью пользуетесь/овались. Думаю там очень не глупые люди сидят, да и я со своими 10+ годами продуктовой разработки уже чего-то стою. Плюс у меня есть свои реализации как VDOM, так и патчера без V составляющей. Мне тоже вся эта идея изначально очень нравилась и нахватавшись всяких кейсов вроде описанного выше я попытался исправить их в своём варианте, поняв, что это нормально сделать не получается, начал пилить morph-element, идея была такой: сравнение строк — идеально быстрая операция, причём не зависит от длинны строки, даже при очень длинных и почти совсем одинаковых строках сравнение происходит сверхбыстро где бы не находилось различие. Дальше вместо подстановки разметки дочернего компонента за счёт вызова его как функции, родитель должен был генерировать кастомные элементы разметка которых разворачивалась уже в attachedCallback (ныне connectedCallback) (он синхронный, полифилится на MutationObserver не синхронно, но это я тоже порешал). Что это давало? Получалось, что каждый компонент генерирует только свой собственный контент, но не контент потомков, то есть при первой генерации можно просто запомнить эту строку и при последующей сравнивать не два огромных объекта со всем контентом потомков, а две относительно короткие строки, что в 100500 раз быстрее. Ну и естественно не перегенерировать контент потомков при равности контента родителя с предыдущей вариантом. То есть лишняя перегенерация всё же происходила (родитель), но уходила не на всю глубину, а максимум на один уровень. Такой подход решал некоторые проблемы VDOM, но не все и в целом патчинг с реального DOM (без виртуальной составляющей) всё же получается медленней, как бы я не пытался его оптимизировать и что бы там не говорил разработчик оригинального morphdom.
    В общем, пока я в тупике, а все другие варианты, что я посмотрел, предлагают костыли вроде:


    добавляем dirty флаг

    используем внутренние часики и проверяем по дате модификации

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

  • Год использования ReactJS: подводим итоги
    0
    моя реализация не будет менее реактивной, но видимо я недостаточно «хорошо» что-то там понял

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


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

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

  • Год использования ReactJS: подводим итоги
    0

    Вы уже второй раз скатываетесь на какие-то странные намёки, первый:


    Просто те у кого опыта побольше, те знают

    К чему это? Недостаток аргументов или раздутое самомнение? Я вроде пытаюсь нормально говорить и приводить нормальные аргументы. Может чего и не понимаю, так объясните без выпендрёжа.


    Ну и вообще, сравнение VDOM-vs-RP — довольно странное, как Слон-vs-Табурет, это не конкурирующие вещи, но они могут неплохо дополнять друг друга. Лучше запилите коннектор вроде этого: cellx-react, а я с удовольствием поставлю ссылочку на него у себя. Заодно сможете попробовать непонятную вам парадигму не отрываясь от своих наработок, плюс убедитесь, что АПИ вашей реализации позволяет полноценно делать такие коннекторы, в ранних версиях реакта у меня, помнится, были какие-то проблемы с этим.

  • Год использования ReactJS: подводим итоги
    0
    кроме тысяч ненужных биндингов, которые вешаются как раз в тот момент когда происходят самые тормозные операции

    добавить обработчик к эвентэмиттеру по сравнению с самим добавлением элемента — моментальная операция, не вижу проблемы. К тому же Rionite добавляет разметку компонентов фрагментами (один компонент — один фрагмент), а не по одному элементу и эти фрагменты, на момент добавления, уже обработаны, то есть куски типа "{name}" в них уже заменены на значения.


    ну а в случае со всякими фильтрациями, так вообще нужно вешать обсерверы на все фильтруемые значения, даже если отображается 10 из 10000.

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

  • Год использования ReactJS: подводим итоги
    0
    добавляем dirty флаг

    используем внутренние часики и проверяем по дате модификации

    вот я и говорю — костыли :), с точечными биндингами проблемы нет в принципе.

  • Год использования ReactJS: подводим итоги
    0

    В любом случае, скорости более чем хватает для реального проекта. Текущий проект, кстати, начинал на связке cellx+React, и уже на первом разделе были два места где немного притормаживало по вине реакта, позже начал с нуля на Rionite, доделываю второй раздел, пока всё летает)). Большой дататейбл тоже есть, как раз в том самом первом разделе. Проблема виртуального дома в том, что он вынужден считать дифф самого компонента и всех дочерних компонентов, и если рядом с обновляемым кусочком лежит какой-нибудь селект с несколькими тысячами опций (как-раз первое место с тормозами, селект был с городами) или что-нибудь в этом духе, то ему прийдётся всё это просмотреть. Тут, конечно, есть решения, но все они костыли по сути.


    На счёт mobx не знаю, но на этом бенчмарке он в 10 раз медленнее cellx-а.

  • Год использования ReactJS: подводим итоги
    0

    Но быстрее его реализации в реакте)) И мне одному кажется, что этот тест очень удобен для виртуального дома? В реальном интерфейсе обычно несколько тысяч активных биндингов и при каком-то действии пользователя меняются лишь несколько (1-10) из них. Именно меняются, не создаются/удаляются. Либо пользователь переключает раздел и тогда как-раз происходит массовое создание/удаление биндингов и опять же обновление лишь нескольких из них. Думаю если приблизить этот тест к реальности, то библиотеки с "точечными" биндингами (Rionite, rivets, ...) оставят далеко позади даже самые быстрые реализации виртуального дома.

  • Год использования ReactJS: подводим итоги
    0

    Посмотрите Rionite, это как раз попытка прилепить реактивные биндинги к кастомным элементам. Есть ещё набор компонентов на этой библиотечке: jsfiddle. Всё это пока малость сырое конечно, но ощущения от использования на реальном проекте реально здоровские, даже после реакта. Плюс всё это ещё и довольно шустрое получается: js-repaint-perfs .

  • Sprute.js. Ещё один изоморфный JavaScript фреймворк
    +1

    Привет, claygod недавно интересовался изоморфным фреймворком RiftJS, который использует cellx для реактивности. Если захотите встроить cellx в свой фреймворк — спрашивайте, попробую помочь, чем смогу)) Ну и сам RiftJS стоит поковырять, там много интересных идей, я его к сожалению забросил в пользу чисто клиентского фреймворка.

  • RxJS: реактивное расширение для фронтенд разработки
    +1
    Сильно много «реактивно» на Knockout не попишешь — не хватает доступных методов для работы с observable — filter/combineLatest/flatMap. Да и по виду код Knockout очень слабо похож на bacon/rx/kefir — мало в нем реактивного


    эти методы — буква F в FRP, отсутствие этих методов делает Knockout менее функциональным, но никак не менее реактивным. К тому же без них вполне неплохо живётся, просто вместо a.add(b) пишется a+b и необходимость в изучении 100500 методов на все случаи жизни сразу отпадает.
  • Для чего вообще нужна изоморфность?
    +2

    Все эти схемочки очень интересны конечно, но в них не учитывается один момент — запросы к АПИ/базе при рендеринге на сервере. И эти запросы (их обычно много) обычно получаются заметно медленнее чем скачивание бандла (рендеринг происходит после самого долгого из них). То есть при обычном подходе пользователь скачивает бандл, дальше у него рендерятся какие-то блоки, которые отправляют запросы за своими данными, выводят лоадер и по мере получения данных раздупляются, тут пользователь уже получает какую-то обратную связь, он видит, что что-то грузится, в случае изоморфного приложения здесь пользователь всё ещё видит белый экран. Первые полностью готовые блоки обычно получается быстрее чем рендеринг на сервере, хотя полностью готовый прил в случае с изоморфностью будет конечно раньше. В общем, без прогрессивного рендеринга вся эта изоморфность может быть интересна только для SEO (и то слишком дорогое SEO выходит, проще по старинке), в ощущаемой скорости загрузки изоморфные приложения всё же проигрывают. А понимая как работает реакт я сомневаюсь, что в него можно нормально этот прогрессивный рендеринг вкорячить, пока видел только одну попытку, и явно неудачную. Вот в этой ветке https://habrahabr.ru/post/280636/#comment_8882284 я как раз встал на сторону реакта (для выяснения истины так сказать) и получил ровно то, чего сам и придерживаюсь.

  • Основы синтаксиса TypeScript
    0

    Если всю жизнь ничего слаще морковки не пробовать, то она будет казаться очень сладкой)

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

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

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    Кстати, с неделю назад 2гис запустил новый проект http://skver.2gis.ru/, сделанный как раз на реакте с изоморфностью. Пообщался с одним из разработчиков, он говорит, что одна нода спокойно держит всю нагрузку, она (нагрузка) по сравнению с основным проектом конечно небольшая совсем, но при росте ещё можно приручивать кеш и масштабировать рендеринг на несколько нод. Так что не так уж всё и плохо с реактом как вы говорите, в теории, действительно, реакт должен рендерить медленнее классических шаблонизаторов, но в прямых руках он вполне годен для таких проектов.

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    Можно в виде кода попробовать разобраться. Как я понимаю у вас в упрощённом виде что-то вроде того: https://gist.github.com/Riim/6fe27c2ee69b13c9d1b41c48ff5ceabb
    Мне не нравится, что при записи в online произойдёт две лишние записи в innerHTML (https://gist.github.com/Riim/a3fab035befe77a6c90ab4cccfe17818#file-app-js-L44-L45).

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    Сеттер модели знает, как компонент узнаёт?
    Да.

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0
    Конструктор компонента

    тогда всё норм.


    через сеттер свойства модели

    так модель может узнать изменилась ли она и нужно ли генерить событие, но как компонент узнает, что изменилось в модели? Тут нужны либо события типа 'change:someprop', либо какая-то инфа в объекте события. Дальше либо много подписок и обработчиков, либо огромное ветвление в единственном обработчике. Дальше опять биндинги.

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    Какая нагрузка была? Сколько рендеров, скажем, в минуту?

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0
    myModel.bindedDomInstances = [myComponent, myComponent2, myComponent3];

    кто наполняет bindedDomInstances?


    Ничего, как вы видите, не обновляется без разбора

    как компонент узнаёт какие свойства модели, выводимые им, нужно обновить в dom-е?

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0
    реальном времени будет очень медленным

    как то замеряли это?

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    По вашей фразе:


    вызывает его обновление через сеттеры или через специальный метод update()

    создаётся впечатление, что речь не о подписке на модель, а модель сама знает о сеттерах и метод update()


    Ладно, здесь вроде разобрались, ещё вопрос про это:


    Если компонентов несколько — обновляет все. Без лишних событий и проверок на правильного подписчика.

    если обновляется всё без разбора, то что с сохранением позиций выделения/скролла (про скролл не уверен, в современных браузерах не замечал, но во всяких IE6 и флешах сталкивался)? В реакте это зашито в сам фреймворк, в вебкомпонентах ничего про это нет. Как-то решаете или не сталкивались ещё? Просто в реакте само устройство фреймворка таково, что приходится обновлять много лишнего, но зачем намеренно так делать с вебкомпонентами мне не понятно. Какой профит?


    UPD: хотя понял, вместо одного model.on('change', ...) прийдётся делать множество подписок на изменения отдельных свойств (model.on('change:someprop', ...)), тут то первый раз и захочется биндингов, потому вы и не понимаете зачем они.

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0
    рассылает данные экземплярам, но ещё и хранит их

    имеется ввиду, что хранит данные (хотя и сами экземпляры тоже).

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    Ok, но я бы не стал называть это моделью, можно было бы назвать въюмоделью, если бы не "Модель знает о всех экземплярах", так это скорее какой-то ComponentManager, но, опять же, создаётся впечатление, что у вас эта штука не только рассылает данные экземплярам, но ещё и хранит их. В общем, чудо-юдо какое-то)). Может тудулист для примера сбацаете?

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    Я верно понял, что, для того что бы просто передать данные компоненту, вы предлагаете создавать событие на родительском компоненте и подписавшись на него в дочернем вытаскивать данные из объекта события?

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    +1
    Модель знает о всех экземплярах связанного с ней компонента и вызывает его обновление через сеттеры

    то есть у вас модель знает о компоненте и сама обновляет его? Это как-то… кхм, необычно))

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

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

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0

    Это всё очевидно, данные то как биндить? Вариант с мешаниной калбеков не предлагать.

  • Как вы можете использовать отзывчивые веб-компоненты сегодня
    0
    Потом вам становится проще писать такие штуки самому, чем бороться с особенностями чужой реализации

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

  • Этажи: 3D-навигация на WebGL в 2gis.ru
    +3

    Афигенно получилось!!!


    Есть небольшие замечания:


    • Появляющийся тултип может вылазить за пределы экрана, надо поднастроить.
    • Задержка перед появлением тултипа нужна, но уже после появления малейшее движение мыши скрывает его, это не удобно, надо добавить какое-то минимальное расстояние, которое должна пройти мышь для скрытия. Ну или ещё что-то придумать.
    • Исчез плавный переход между подложками кнопок зума, я сначала подумал, что это специально, но на основной карте он ещё есть.
    • Опять разное поведение кнопок: наводим на кнопку зума, зажимаем кнопку и не отпуская уводим мышь в сторону, кнопка по прежнему выглядит зажатой и отжимается только при отпускании кнопки мыши. Кнопки переключения этажей отжимаются уже при mouseout. Первый вариант мне кажется более правильным, но как минимум это поведение должно быть одинаковым во всём приложении.
    • При выполнении пункта выше можно получить выделенный текст в тултипе.
    • Два маркера и тултипа друг над другом: https://yadi.sk/i/2_guZvsKrCm5o .
  • ES5 руководство по JavaScript
    0

    Разве здесь [].slice.call(arguments) есть утечка аргументов? slice же тоже ничего не меняет в arguments.

  • Почему я НЕ являюсь фанатом TypeScript
    –1
    Согласен на счёт FlowType, действительно как-то ненавязчиво он типы добавляет, указал тип — проверяет, не указал — пытается как-то его вывести и если уж возникает, то очень редко и действительно по делу. С typescript приходиться пол дня разбираться как его так настроить, что бы он уткнулся и не лез там где его не просят. Причём совсем утыкаться он всё же не хочет и кучу any всё равно приходиться добавлять. FlowType ещё долго до ума доводить (typescript тут всё же сильно впереди), но основа у него явно поудачней будет.
  • Шорткаты в JavaScript
    +1
    Меня одного напрягает, что в конструкциях типа:
    var i = list.length;
    while (i--) {
      var item = list[i];
      // ...
    }
    

    в последней итерации произойдёт лишний декремент?
    Иногда он конечно нужен, но чаще лучше без него:
    var i = list.length;
    while (i) {
      var item = list[--i];
      // ...
    }
    

    Понятно, что это не даст какого-то улучшения производительности, но так оно как-то правильней что ли.
    Ну и раз уж `i` нужна только для цикла, то в идеале вообще так:
    for (var i = list.length; i;) {
      var item = list[--i];
      // ...
    }