ermouth: (Default)
ermouth ([personal profile] ermouth) wrote2015-12-12 06:35 am
Entry tags:

jQuery.my 1.2.0

Отрелизил сабж, релиз больше про рефакторинг/оптимизацию. Проковырялся неделю вечерами с профайлером, открыл много нового про GC и скорость регэкспов. Вот примерчик особенно злодейский:

Снимок экрана 2015-12-12 в 4.39.41

Попутно напишу вот про виджет с заглавной, оч хорошо на нём видно и что такое $.my, и что я там оптимизировал. Пример, собсно, по клику на картинку.

Снимок экрана 2015-12-12 в 4.28.49

В примере 100 строк кода, 2Кб, это с HTML-ем уже. Эти 2 Кб грузят внешние данные и делают из них master/detail.

Особая фишка – в левой колонке позиции таскабельны. И номера обновляются по мере перетаскивания, причём если справа открыта карточка и тыкнуто в поле ввода, то фокус не теряется.

Ну и если справа начать имя править, слева оно немедленно рефлектится. Причём можно даже начать тащить айтем слева и одновременно печатать справа )

Кто делал что-нибудь похожее хоть раз в жизни, знает, что 100 строк кода на такое – это вообще наглухо магия.

Инициализация этого виджета с 280 строками данных (каждая из которых – тоже форма) занимает примерно 300мс. По 1мс на форму. Флеймчарты до и после оптимизаций:

Снимок экрана 2015-12-12 в 5.57.37

Снимок экрана 2015-12-12 в 5.57.20

В самом деле 1мс – это чрезвычайно дохрена. Мы на каждую строку слева инциализируем по сути маленькое приложение, и это дорого. Увы, такой подход можно наоптимизировать ещё примерно только раза в 2 и будет потолок.

Но у меня есть план Б.

В jQuery.my 2.0 будет другой (точнее, ещё один) алгоритм. Во-первых, просто сам старт одинаковых форм станет быстрее, потому что полуфабрикат формы будет кэшироваться. А во-вторых, рендерить я их буду чанками.

Подход с чанками у меня уже 3 года как реализован для длинных списков отдельным плагином и в бою обкатан, надо только вкрутить. Это уже в 2016 будет.

Завтра-послезавтра days off.

[identity profile] alexispokrovski.livejournal.com 2015-12-12 06:36 am (UTC)(link)
Круто. Потыкал на айпадике. -- все работает just as expected. Respect.

[identity profile] levgem.livejournal.com 2015-12-12 09:51 am (UTC)(link)
ты знаешь, почему такой кошмар с регекспом?

Имеет ли смысл регексп вообще или лучше строить парсер?

[identity profile] ermouth.livejournal.com 2015-12-12 11:19 am (UTC)(link)
С регэкспом знаю, там в твите первый пример – как раз замена второму. Не понимаю вообще, в каком сомнабулизме я тот предыдущий регэксп написал.

Это кста не в парсере, а в сериализаторе, внутри $.my не используется – сервисная функция для удобства.

[identity profile] levgem.livejournal.com 2015-12-12 12:31 pm (UTC)(link)
Я не могу понять, почему такая разница

[identity profile] ermouth.livejournal.com 2015-12-12 01:05 pm (UTC)(link)
В самом деле разница, конечно, не в 40 раз. Легко придумать такую строку где разница будет много порядков.

У второго – в наихудшем случае квадратичная сложность, у первого – линейная.

Иллюстрация: делаем строку из 1К символов без }, приписывам к ней в конце }x. Засекаем время на /[^}]+$/. Делаем то же самое, но 2К символов. Время увеличится в 4 раза.

Чтобы понять, почему так, посмотри, какие автоматы строятся на эти регэкспы http://hackingoff.com/compilers/regular-expression-to-nfa-dfa
Edited 2015-12-12 13:08 (UTC)

[identity profile] morfizm.livejournal.com 2015-12-14 01:15 am (UTC)(link)
Как насчёт плана C - lazy initialization? 1мс как результат юзер-клика на элемент слева будет куда незаметнее, чем cumulative 300мс при открытии страницы если инициализировать всё сразу.

[identity profile] ermouth.livejournal.com 2015-12-14 07:41 am (UTC)(link)
По-хорошему, в левой колонке вообще не нужен $.my в полный рост – там данные идут в одну сторону, только показываются. Для этого у меня есть суперскоростной плагин, я про него как раз и написал, что «3 года назад сделал».

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

Тем не менее, это всё не снимает лага на отрисовку, а он может быть существенный и непредсказуемый (у меня есть свежайший пример, где новый Хром проигрывает Файерфоксу в 60+ раз).

Lazy init – это хорошая идея, и она у меня есть в планчике – но немного не так, как ты пишешь. По такой схеме, как предлагаешь ты, непонятно, откуда в контроле возьмётся первоначальное значение. Чтобы оно там взялось, его надо туда записать. Чтобы его туда записать, надо подобрать к контролу подходящий «драйвер». Чтобы его подобрать – контрол надо проинициализировать.

В общем, всё сложно )

[identity profile] morfizm.livejournal.com 2015-12-19 10:29 am (UTC)(link)
Я нахожусь где-то около границы (а может, за ней), когда уже пора бы внимательно вникнуть в то, как работает твой jQuery.my, но пока всё ещё из общих соображений: если в контрол надо зафигачить первоначальное значение, то можно по тому же lazy init принципу добавить его в какой-то список или map, откуда контрол его зачитает когда юзер реально на него кликнет. Это сработает если инит-значения гарантированно валидные. Если же нужно делать валидацию, её можно либо сделать заранее, либо код валидации оформить модульно - таким образом, чтобы ты мог сконструкировать цепочку валидаторов без необходимости инициализировать весь контрол.

[identity profile] ermouth.livejournal.com 2015-12-19 05:35 pm (UTC)(link)
> когда юзер реально на него кликнет

Эммм, а как быть с тем, что в контроле значение должно быть _перед_ тем как юзер кликнул? ))

[identity profile] ermouth.livejournal.com 2015-12-19 06:09 pm (UTC)(link)
> когда уже пора бы внимательно вникнуть в то, как работает твой jQuery.my

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

[identity profile] vdggenerator.livejournal.com 2016-01-17 01:34 pm (UTC)(link)
Подскажите, пожалуйста, какие минимальные системные требования к браузеру для работы с jQuery.my? IE поддерживается?