Случайны выбор дневника Раскрыть/свернуть полный список возможностей


Найдено 1105 сообщений
Cообщения с меткой

dom - Самое интересное в блогах

Следующие 30  »
noscons

Dom 3 онлайн игра

Вторник, 07 Февраля 2017 г. 10:18 (ссылка)

Dom 3 онлайн игра.


Читать далее
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
paibu

Политические самые актуальные футболки dom

Суббота, 07 Января 2017 г. 10:42 (ссылка)

Политические самые актуальные футболки dom.


Читать далее
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

Быстрый рендеринг с DOM шаблонизаторами

Суббота, 24 Сентября 2016 г. 10:42 (ссылка)

Борис Каплуновский ( BSKaplou)



Борис Каплуновский



Я довольно долго работал над докладом и старался сделать его настолько противоречивым, насколько это возможно. И сразу начну с противоречия – я в корне не согласен с тем, что веб-компонентами можно пользоваться. Уже поднимался вопрос о 300 Кбайтах, я глубоко уверен, что 300 Кбайт для страницы Javascripta – недопустимо много.



Сегодня я расскажу о довольно глубоком путешествии во фронтенд. Началось это путешествие тогда, когда я обнаружил, что фронтенд aviasales.ru тормозит, и надо что-то делать. Это путешествие началось года полтора-два назад, и вещи, о которых я буду рассказывать, – это сжатое повествование того, что я узнал.



Самым критичным, на мой взгляд, в производительности фронтенд-приложений является рендеринг. Все мы знаем, что работа с DOM – это такая вещь, которую нужно стараться избегать. Чем больше вы делаете вызовов к DOM API, тем медленнее работает ваше приложение.







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



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







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







Начнем о правилах игры. User experience зависит от скорости инициализации страницы. Все мы глубоко увлечены кэшированием страниц, но вынужден сразу же противоречиво заявить, что кэширование не работает. Не работает, потому что первый контакт с сайтом у человека – самый критичный. Если при первой загрузке сайт тормозит, то второй раз пользователь может к вам не вернуться. Первоначальная загрузка страницы крайне важна.



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



Следующая вещь – это потребление ресурсов. На веб-страницах важны два основных показателя: потребление процессора (если вы делаете много лишних действий, вы греете процессор, и у него не хватает времени, чтобы обсчитать анимацию на интерфейсе или что-то просто пририсовать), кроме того, если вы создаете много лишних объектов, это создает нагрузку на garbage collector. Если вы создаете нагрузку на garbage collector, то периодически он будет вызываться, и отзывчивость вашего приложения будет падать.



И последний, но от этого не менее важный пункт. Размер библиотеки. Если у вас single page application, то 200-300, иногда даже 400 Кбайт javascript вы можете себе позволить. Однако же, компонентный веб, в направлении которого мы с вами весело движемся, подразумевает, что страницы строятся из разных веб-компонент. Более того, эти веб-компоненты зачастую произведены в разных компаниях и приходят со своим пакетом.



Представим себе страницу, на которую вставлено десяток виджетов: виджет курсов валют, погоды, авиабилетов, черта в ступе чего… И каждый из этих компонент весит 300 Кбайт, и это только JS. Таким макаром, у нас запросто получится страница, которая весит 5-10 Мбайт. Все бы ничего, и Интернет становится все быстрее и быстрее, но появились мобильные устройства, появились медленные сети, и если вы пользуетесь Интернетом не в городе Москва, а где-нибудь в Екатеринбурге, то 15 Мбайтный сайт окажется для вас совершенно недопустимой роскошью. Именно поэтому размер библиотеки, на мой взгляд, критичен.



Чуть ниже я сравниваю несколько библиотек, и не сравниваю полимеры, не сравниваю по той причине, что 200 Кбайт для библиотеки веб-компонентов – это слишком много.







Итак, перейдем к теме разговора – к шаблонизаторам.



Все мы, кто занимается разработкой веб, привыкли уже к строковым шаблонизаторам. Строковые шаблонизаторы – это шаблонизаторы, которые в результате своей работы возвращают нам строку. Строку, которую позже мы вставляем посредством innerHTML в html. Это замечательный, древний, всем привычный механизм. Однако он имеет ряд недостатков. Главный недостаток – то, что каждый раз, когда вы произвели шаблонизацию и делаете вставку в innerHTML, приходится выкинуть весь DOM, который там был раньше и вставить новый DOM.



Насколько я помню, работа с DOM очень и очень медленна. Если вы выкинули 20 тегов с 30-тью атрибутами и вставили такие же, те же 20 тегов с 10-тью атрибутами, то это займет значительное время. 20 миллисекунд запросто. Кроме того, строковые шаблонизаторы не позволяют оставлять якоря для быстрых апдейтов единичных атрибутов, единичных текстовых нод и т.п.



Обнаружив эти неоптимальности, мы начали искать, как же можно избавиться от этих недостатков, что можно с этим сделать? И первое, что подсказал Goggle, это «Используйте DOM API». Это штука не очень простая. Но у нее есть плюсы.







Это скриншот с сайта jsperf. Бенчмарк, который видит производительность строковых шаблонизаторов, вставляющих куски html из innerHTML и DOM JS. Здесь мы видим в верхней части производительность на Android’е, и видим, что JSDOM API позволяет ускорить рендеринг в несколько раз. Здесь примерно в три раза. В то же время на десктопных браузерах такого адского прироста производительности нет.



Google примерно полгода назад начал обещать всем веб-разработчикам «мобилогеддон». Это значит, что все сайты, которые не адаптированы под мобильные устройства, респонсивные, адаптивные, будут пессимистироваться в поисковые выдачи. Это значит, что если вы не готовы к мобильным устройствам, просто трафик с Google на ваших сайтах значительно уменьшится.



По сути, этот слайд наглядно говорит, что используя DOM API, вы можете значительно ускорить рендеринг на мобильных устройствах. Причем это относится не только к Android’ам. Как вы знаете, все современные Android’ы и IOS-устройства используют один и тот же движок WebKit, примерно с одним набором оптимизации, а значит такой же прирост по производительности вы получите на всех IOS устройствах, если будете рендерить страницы через DOM API.







Однако, DOM API – штука довольно громоздкая. Здесь я привел пять основных вызовов, с помощью которых можно создавать участки DOM. Привел я их примерно в том виде, в котором они будут встречаться в коде вашей программы, если вы будете создавать участки DOM непосредственно через API.



Создание одного элемента, который раньше у вас укладывался в 15-17, может быть 30-50 символов, через DOM API запросто у вас выльется в 5-10 строк кода. Время работы программистов ценно, а это значит, что мы не можем заменить html на ручное программирование DOM.







Здесь-то нам и необходимы шаблонизаторы. Как вы помните, строковые шаблонизаторы медленные, и хочется иметь DOM шаблонизаторы, шаблонизаторы работающие через DOM API, но позволяющие пользоваться всеми теми плюшками, к которым мы привыкли, работая с обычными шаблонизаторами.



Итак, что же нам дают DOM шаблонизаторы, кроме возможности не использовать родной JSDOM API? Они позволяют сохранять DOM объекты в переменных для быстрого обновления позже. Используя DOM шаблонизаторы, можно использовать один и тот же участок DOM несколько раз.



Что я имею в виду? Предположим, мы посещаем страницу веб-магазина. Пользователи заходят в одну категорию товаров, и в заготовленные шаблоны подставляются данные об одном списке товаров. Когда человек переходит в другую категорию товаров, в эти же шаблоны подставляются другие данные. По сути, мы не пересоздаем DOM, мы используем одни и те же участки DOM для отображения данных. Это позволяет очень сильно сэкономить и на ресурсах процессора, и на памяти, и иногда на времени программистов.



После осознания этой мысли, что инструмент, который мне нужен, – это DOM шаблонизаторы, мы пошли смотреть, что же уже существует в индустрии, чем уже можно воспользоваться, чтобы быстро и качественно работать с DOM, и быстро его рендерить?



Дальше я расскажу, где, на мой взгляд, оступились гиганты.







Первый гигант, о котором я хочу рассказать, это AngularJS.



AngularJS, мне кажется, оступился прямо на самом старте. Если вы им пользовались, то, наверное, заметили, что все шаблоны передаются на клиент в виде либо DOM участков (что является не очень хорошим стилем), либо в виде строк. После того, как библиотека загрузилась, Angular вынужден скомпилировать ваши строки или DOM в реальные шаблоны. Это происходит на клиенте.



Представим себе интересную ситуацию. Пользователь заходит на страницу, грузит весь JS, которого для Angular приложений может быть довольно много – 100-200-300 Кбайт запросто. После этого каждый шаблон с разбором строк начинает компилиться. Приводит это всего к одной вещи – первоначальная загрузка Angular приложений может из-за этой компиляции (во время которой пользователи занимаются чем угодно кроме работы с сайтом) длиться полсекунды, секунду. Я встречал сайты, на которых процесс компиляции шаблона занимал даже две секунды. Более того, эта проблема нарастает как снежный ком: чем больше шаблонов в вашем приложении, чем сложнее ваше single page application, тем больше времени мы тратим на первоначальную компиляцию шаблонов.







Следующая проблема в Angular. Мы все помним, что Angular продавался нам господами из Google, как первый самый крутой фреймворк с двусторонним биндингом. Причем, этот двусторонний биндинг реализуется через т.н. $watcher’ы, которые вы вешаете на структуры данных для последующего отображения их в DOM. На слайде интересная картинка, но вы на нее не смотрите. Интересным в ней является только этот замечательный цикл, в ходе которого обходятся все $watch’и, на всех данных, которые у вас существуют в системе. Причем, конечно же, в документации и во всех туториалах, вам никто не будет рассказывать, что за $watcher’ами нужно следить. Приводит это буквально к следующему. В какой-то момент ваше замечательное приложение начинает раз в 100 мс хорошо притормаживать. Начинают тормозить анимации, начинает течь память. Оказывается, что допускать много $watcher’ов просто нельзя. Как только вы допустили много $watcher’ов, ваше приложение начинает спонтанно тормозить. Тут вы начинаете хитро изощряться, идти на что угодно, сокращать количество $watcher’ов, отказываться в приложении от двустороннего биндинга, ради которого вы брали Angular, только чтобы избавиться от тормозов.







Кроме того, мне кажется, архитектурной промашкой Angular является то, что в Angular не существует единственного правильно описанного способа работать с DOM. Директивы фактически независимы, каждая из их работает с DOM так, как она считает нужным. А получается, что пройдясь по директивам Angular, мы можем пометить некоторые директивы быстрыми, некоторые как медленные, а некоторые директивы как очень медленные.



Если вы пользовались ng-repeat, то вы, наверное, видели, что если вы запихнете 100 элементов в нее, и еще там будут $watcher’ы, то рендериться все это будет очень долго. Проблема настолько широка, что работая с Angular (наша предыдущая версия выдачи была построена именно на Angular), нам пришло написать свой ng-repeat. Это сделал наш сотрудник Антон Плешивцев и рассказывал об этом на множестве конференций. Кроме этого, 50 Кбайт минимизированного размера библиотеки, на мой взгляд, все-таки многовато. Т.е. за что вы платите? Если вы смотрите код Angular, то в эти 50 Кбайт зашита собственная система классов, туда зашита очень некачественная, на мой взгляд, версия Underscore. И это все вы получаете совершенно бесплатно в рамках 50-ти Кбайт кода.







Следующее. Намного более качественный фреймворк, на мой взгляд, это ReactJS. Судя по тому, как бурлит Интернет, каждый первый программист, даже не всегда фронтендщик, пользовался Angular и в восторге от него. Я не считаю, что virtualDOM может ускорить работу с DOM.



Смотрите, что нам предлагает virtualDOM. VirtualDOM является источником, из которого ReactJS создает настоящий DOM, т.е. кроме реального DOM, от создания которого вы никуда не денетесь (virtualDOM всего лишь позволяет его создавать), ReactJS в памяти держит еще virtualDOM, это называется избыточностью.



VirtualDOM несколько меньше настоящего DOM, может быть раз в 5. Однако, на самом деле, вы вынуждены держать в памяти две копии virtualDOM. Т.е. вы держите настоящий DOM, вы держите отражение настоящего DOM в virtualDOM, кроме того, каждый раз, когда вы собираетесь делать div в virtualDOM, вы делаете еще одну копию DOM. У вас был один DOM, теперь у вас их три – молодцы! Более того, на каждое изменение данных, вы создаете еще одну копию virtualDOM, это и есть третья копия, однако, вы создаете ее с нуля.



Это создает серьезную нагрузку на garbage collector и на процессор. Кроме того, на мой взгляд, библиотека все еще жирная – 35 Кбайт. И опять же, ребята решили нарисовать свою систему классов, нарисовать свой lowdash, оригинальный почему-то не устраивал, и все это запихнули в 35 Кбайт. Кроме того, там упакован virtualDOM с мифическим алгоритмом, который якобы дает огромную производительность.



Следующая проблема virtualDOM и React в частности, это то, что ReactJS ничего не знает о семантике ваших данных. Давайте, посмотрим этот очень простой пример.







Здесь мы видим два вложенных
, и в них вложен еще один тег . Чтобы изменить value через virtualDOM, алгоритм virtualDOM внутри React вынужден сравнить три тега и одно текстовое значение. Если мы знаем семантику данных, для нас достаточно сравнить только текстовое значение, просто потому что в шаблоне написано, что внутри одного
всегда другой
, внутри следующего
тег … Зачем нам их сравнивать каждый раз? Это реально оверхед.



Кроме того, если вы программировали на React, то вы знакомы с такой штукой как pure-render-mixin. Суть его в том, чтобы избавиться от работы c virtualDom'ом. Случается очень интересная ситуация близкая к комичной. Сначала господа из Google пару лет продавали нам React как штуку, которая с помощью virtualDOM адски ускоряет работу с DOM, а потом оказывается, что чтобы быстро работать с DOM, нужно исключить virtualDOM. Молодцы, хорошо сделали.



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







Я рассмотрю две интересные библиотеки. Первая из них – RiotJS.



На мой взгляд, RiotJS – это правильная AngularJS, просто потому что размер библиотеки 5 Кбайт. Ребята взяли абсолютно те же идеи, что были в AngularJS, но не стали переписывать lowdash, просто сказали: «Зачем? Он уже написан». Ребята не стали переписывать, изобретать свою систему классов, ничего не стали делать. Получили библиотеку в 5 Кбайт. Производительность больше, чем у AngularJS, идеи абсолютно те же. И более того, шаблоны, используемые в RiotJS, используют семантику данных, что дает неплохой прирост по производительности. Но осталась и проблема – компиляция шаблонов все еще происходит на клиенте. Это не очень быстро, но уже намного лучше.







Следующая библиотека, которая привлекла мое внимание, это PaperclipJS.



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



Но и у этой библиотеки нашлось два недостатка: она довольно большая – 40 Кбайт, это больше, чем React; и, несмотря на хорошие идеи, разработка ведется довольно вяло. Этой библиотеке уже пару лет, однако, она до сих пор не вышла из стадии beta.



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







Первая вещь – это VirtualDOM. Его плюсы я долго искал, и нашел только один – он позволяет сократить количество вызовов к DOM, тем самым подняв производительность. Однако, оверхед на создание копии DOM, на мой взгляд, все-таки значительный. Сложный алгоритм сравнения, над которым до сих пор стоит завеса тайны, который используется в React, он не такой быстрый, как нам о нем обещают. Чтобы понять, как оно работает, вы потратите дня два. И всей этой магии, о которой рассказывали в блогах, там нет, на мой взгляд. Кроме того, virtualDOM сидит на той проблеме, что алгоритм ничего не знает о структуре данных. Пока мы ничего не знаем о структуре данных, все наши врайперы, все наши элементы верстки, негативно сказываются на производительности, потому что алгоритм virtualDOM должен участвовать в их сравнении.







Техники, которые были известны очень давно – это использование cloneNode, о котором я уже говорил в рамках PaperclipJS и DocumentFragment. Эти две техники используются для повышения производительности. Ни одна, ни другая техника, насколько мне известно, не используется ни в AngularJS, ни в ReactJS. Однако скриншот бенчмарка с jsperf наглядно показывает, что это позволяет ускорить работу с DOM, как минимум в три раза. Довольно неплохая практика, очень советую пользоваться.







Следующая техника, которая лежит абсолютно на поверхности, более того, неявно встречается даже в туториале по React, – это создание DOM участков заранее. Что я имею в виду? Предположим, человек заходит на страницу интернет-магазина электронных чайников. Вводит название чайника, название фирмы чайника, который хочет приобрести. В этот момент на сервер отправляется поисковый запрос. Если ваши серверные программисты быстры и молниеносны, то вы можете получить ответ за 20 мс, эти 20 мс пользователь практически ничего не делает. И в этот момент мы можем создать структуру DOM под данные, которые вернутся с нашего сервера. Довольно простая практика. Не знаю, почему она не получила широкого применения. Я ее пользую, очень круто получается.



Итого, что получается? Мы шлем запрос на сервер, пока мы ждем ответа с сервера, мы подготавливаем структуры DOM под данные, которые должны к нам прийти с сервера. Когда к нам приходит ответ с сервера, на самом деле нам его еще нужно разобрать. Чаще всего, это не просто принять Json, но и как-то адоптировать его. Если к этому моменту DOM у нас уже готов, то те 2-3-4 мс, которые у нас есть для работы JS мы можем потратить на адаптацию и на вставку данных в DOM и добавление данных на страницу.



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



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







Это шаблонизатор temple. Он очень простой, очень маленький, там буквально меньше 2000 строк кода.



Какими же свойствами он обладает? Шаблоны компилируются на момент сборки в JavaScript код, т.е. на клиенте никакой работы, кроме загрузки JavaScript кода не делается. Возможность создавать куски DOM заранее поддержана прямо в библиотеке. Библиотека позволяет легко и просто переиспользовать шаблоны. Размер библиотеки, на мой взгляд, более чем скромный в минимизированном и gzip’ленном виде – это всего 700 байт. Более того, вещь, которая мне в ней нравится больше всего – это максимально быстрое обновление DOM.



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







Структура шаблона крайне простая и примитивная. Это усы, внутри которых подставляются переменные.







Все довольно очевидно, никакой магии. Кроме этого, поддерживает две конструкции. Это forall итерация по ключу для циклов и ветвления if. Не поддерживаются выражения. Некоторое время назад, до появления React, в индустрии доминировало мнение, что нельзя ни в коем случае мешать View и модель. Я до сих пор верю, что это правильный подход, поэтому если хочется использовать сложные выражения, лучше вынести это в отдельный компонент. Если вы помните, есть такие паттерные Presenter или ViewModel, если вам нужно сложно подготавливать данные отображения в шаблоны, лучше это сделать там, и не затягивать выражения в шаблоны.



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



Как выглядит работа с темплом.







Мы берем именованный шаблон из темпла, апдейтим данные в нем вызовом update. И вставляем его в DOM. Фактически это очень похоже на работу с обычным DOM API. После того, как мы попользовались шаблоном, мы можем убрать его из DOM вызовом remove. Все очень просто.







Как делается заблаговременное создание DOM? Предположим, мы послали на сервер запрос и знаем, что с сервера нам должен прийти набор чайников. В этот момент мы говорим пулу шаблонов: «Создай кэш на 10 чайников». Он создается, и когда мы в следующий раз будем делать такой же вызов get, реальной работы с DOM не будет, мы получим уже подготовленный и срендеренный шаблон. Т.е. получим шаблон для вставки в DOM мгновенно.



Когда этим удобнее всего пользоваться? Смотрите, мы посылаем запрос на сервер и у нас есть 20 мс, на самом деле, конечно, не 20, скорее всего это 200-300 мс, за это время мы можем накэшировать миллионы DOM нод, т.е. времени достаточно.



Второй вариант – это кэшировать шаблоны, когда мы ожидаем DOMContentLoaded.



С DOMContentLoaded есть такая проблема, что очень много обработчиков подписываются на это событие и в итоге в момент прихода этого события просыпается чертова туча скриптов, которые все по callback’у начинают обрабатывать, и после этого события около 100 мс приложение спит. Оно глубоко считает там что-то. Чтобы сократить это ожидание, можно кэширование DOM шаблонов сделать заранее, до того, как это событие к нам придет.







Быстрое внесение изменений в DOM. Здесь я привожу простой и понятный вызов, он очень похож на то, как делается update в React. Все помнят вызов в React setState, разница только в глубине стека. Если вы видели, насколько глубоко, сколько вызовов функций делает React, перед тем как сделать целевое действие (а целевое действие у нас, скорее, такое – просто подставить в DOM это значение), то знаете, что для React это может быть глубина стека 50-60, может быть больше.



Каждый вызов, особенно в динамических языках как JavaScript, дается нам совершенно не бесплатно. Это не так медленно как DOM вызов, но все еще не бесплатно. Темпл позволяет делать эту замену с глубиной стека =2, т.е. по сути, вызывается update, из него вызывается функция, которая заменяет это значение. По сути, это функция value. И с глубиной стека =2, мы получаем целевое действие. При этом вызов update рекомендуется использовать тогда, когда мы хотим изменить сразу несколько значений. Если мы хотим изменить одно, то это можно еще быстрее – прямым вызовов property и тогда эта подстановка будет сделана с глубиной стека =1, быстрее физически невозможно.







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







Дальше попытаюсь вам продать этот инструмент с помощью бенчмарков. Первый бенчмарк. Внизу я всегда привожу ссылку на бенчмарк, и помним, что на jsperf «больше» значит «лучше». В данном случае красное – это Темпл, и синее – это React. C React я сравниваюсь, потому что React, наверное, самое быстрое решение, он раз в 5 быстрее, чем Angular обычно. Итак, что же мы тут видим? Первоначальная инициализация в Темпле делается на процентов 30 быстрее в Chrom’е, и на процентов 10-15 в Firefox’е. За счет чего это получается? Внутри, в конечном итоге, использу.тся те же create element, create text, node appendchild. Однако в Темпле почти никогда нет глубины стека больше двух. По сути, мы экономим время исключительно на вызовах внутри библиотеки. Те 35 Кбайт JavaScript, которые вы скачиваете для использования React, отливаются вам этой разницей в производительности – длинные стеки.







Следующий бенчмарк, который мы изобрели и прогнали – это soft Update. Soft Update – это когда мы подставляем в шаблон те же данные, которые туда уже были подставлены. Это то место, где должен проснуться virtualDOM и сказать: «Ребята, данные уже есть, ничего делать не надо». Скажу сразу, что для чистоты экспериментов на virtualDOM я не использовал pure-render-mixin. И оказалось, что оптимизации в самом браузере позволяют делать это в четыре раза быстрее. VirtualDOM вносит тормоза в четыре раза.







Пойдем дальше, hard update. Hard Update – это сценарий, при котором в шаблоне обновляется не один участок данных, а все данные, которые есть. Опять же не используем pure-render-mixin, но он тут бы был и бесполезен. И получаем еще более интересные данные. При hard update выигрыш Темпла в десятки раз, просто потому что там нет virtualDOM.



VirtualDOM на практике оказался очень ресурсоемкой операцией. И если вы глубоко программировали React-приложения, то довольно быстро столкнулись с тем, что работу с virtualDOM нужно сократить. Я в этой идее достиг полного перфекционизма и считаю, что virtualDOM, как идея, плох, и его нужно выкинуть. Это сделает React легче Кбайт на 20, и быстрее раз в 10.







Темпл, который мы делали, очень маленький. Aviasales – не Facebook, у нас нет миллионов инженеро-часов, у нас есть только… Как вы понимаете, разработка таких библиотек – не очень продуктовая фича, и в рабочее время заниматься этим не получается. Этим можно заниматься ночью небольшой группой энтузиастов. Поэтому библиотека очень маленькая. Темпл не предлагает работу с событиями. В React есть DOM delegate, в AngularJS есть своя работа с событиями. Но я и не считаю, что нужно работу с событиями интегрировать в шаблонизатор. Для работы с событиями можно использовать стандартные библиотеки. Мы используем domdelegate от Ftlabs. Ftlabs – это IT-подразделение «Financial Times». Ребята сделали очень хорошую, очень простую и производительную библиотеку, ее размер, если не ошибаюсь, меньше 5 Кбайт. Мы ее используем в паре с Темпл, и довольны результатами.







В пользу своих предыдущих бенчмарков и слов, хочу сказать, что на данный момент Темпл мы используем уже в двух проектах: это мобильная версия aviasales.ru и новая поисковая выдача aviasales.ru. В мобильной версии все шаблоны преобразуются в 10 Кбайт кода, речь идет о минимизированном и сжатом коде, и все приложение занимает 58 Кбайт. Мне кажется, это неплохой размер для довольно сложного single page приложения.



Следующим приложением, которое мы разрабатывали, была новая поисковая выдача, там шаблоны уже занимают 15 Кбайт, и все приложение занимает 70 Кбайт. Также было несколько интеграций с виджетами, но они менее интересны. Однако, 70 Кбайт для single page application, мне кажется это хороший показатель. Особенно если сравнивать с библиотеками, которые весят 200.







Собственно, это открыто в open source сейчас. Можете посмотреть его, поиграться с ним по url на слайде. Оно все еще довольно сыро.



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



Контакты



» BSKaplou

» bk@aviasales.ru



Этот доклад — расшифровка одного из лучших выступлений на конференции фронтенд-разработчиков FrontendConf. Мы уже открыли подготовку к 2017 году, а подписавшись на список рассылки конференции Вы получите 8 лучших докладов прошлого года.



Самая сложная секция грядущей конференции HighLoad++ это "Производительность фронтенда". Фронтенд стал большим, это уже полноценный софт со своей архитектурой, моделями и данными (а не просто интерфейс, как было раньше). Именно в этом разрезе мы и изучаем его на этой секции.



Вот некоторые из планируемых докладов:






Original source: habrahabr.ru.

https://habrahabr.ru/post/310868/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

DiffHTML.js — утилита для патчинга DOM

Вторник, 30 Августа 2016 г. 19:53 (ссылка)





Что такое DiffHTML.js?



DiffHTML — эта утилита для патчинга (частичного изменения) DOM-дерева. Она умеет находить разницу между существующим DOM-деревом и HTML-строкой, между двумя деревьями. В результате будут произведены только те изменения, которые реально имеют место быть. Те элементы которых не было — вставятся, атрибуты которые были реально изменены — изменятся, и только они. Остальные элементы останутся без изменений.



Зачем это?



Просто чтобы не трогать те элементы в которых не было изменений. Это дешевле, чем ре-рендерить полностью все дерево.



Как же React.JS?



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



diff.innerHTML(document.body, '

Hello world!

');


и объект появится в DOM-дереве. Далее…



diff.innerHTML(document.body, '

Hello world!

');


и только атрибут class будет добавлен. Просто добавим параграф:



diff.innerHTML(document.body, '

Hello world!

Dear, World!

');


В общем идея очень простая и в то же время достаточно мощная.



Минусы (готовность для продакшена)




  • Проект молодой, поэтому здесь баги — это нормально

  • Проблемы с навешиванием событий (старые события автоматически не удаляются)

  • Нет большого количества информации вокруг этой библиотеки





Плюсы




  • Быстрей простой перерисовки всех элементов внутри контейнера

  • Есть middleware, можно контролировать проецес патчинга

  • Есть подобие Virtual DOM, можно писать React-like шаблоны

  • Меньше проводить времени с точечными модификациями DOM-дерева вручную

  • Отзывчивый разработчик





Где применять?



Лично я вижу сферы применения:


  • В старом коде, работающем на базе традиционных шаблонов и el.innerHTML вставки, можно добиться ускорения производительности

  • Для сложных SaaS виджетов, где важен размер подключаемых библиотек

  • Для pet-проектов, где React избыточен, но на Vanilla.JS уже не хочется





А ToDo?



Есть ToDo: github.com/tbranyen/todomvc, но как мне показалось — код сильно избыточен, поэтому я сделал свое:



Мое ToDo: github.com/jmas/htmldiff-todo (DiffHTML, Babel DiffHTML tag transformer, Redux)



Вывод



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



Будет очень кстати, если кто то возьмется померять производительность.



Github: github.com/tbranyen/diffhtml

Issues: github.com/tbranyen/diffhtml/issues



Спасибо за чтение!



Update

В комментариях подсказали, что еще есть аналог morphdomфорк).
Original source: habrahabr.ru.

https://habrahabr.ru/post/308856/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[Перевод] Зачем нам jQuery?

Пятница, 19 Августа 2016 г. 18:00 (ссылка)

Здравствуйте, дамы и господа! Вот уже без малого десять лет минуло с первого релиза библиотеки jQuery, и мы решили отряхнуть пыль веков с классики. Подумываем о выпуске третьего издания гусарской баллады об этой библиотеке:





Чтобы пояснить, чем она нас привлекает в эпоху Node и ES6 (у нас в ассортименте и этого добра навалом) предлагаем познакомиться со статьей Коди Линдли, вышедшей вскоре после вышеупомянутого третьего издания



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



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



Прежде чем я начну пылко отстаивать честь jQuery, давайте вернемся к ее истокам, чтобы всем стало понятно, «что» такое jQuery, и «зачем» она нужна.



Что такое jQuery?



jQuery – это библиотека JavaScript (т.e., она написана на JavaScript), предназначенная для абстрагирования, выравнивания, исправления и упрощения скриптинга при работе с узлами HTML-элементов в браузере или для работы в браузере без графического интерфейса.



Итак:





Все это оборачивается в более простой и менее корявый API, нежели нативный API DOM – вот вам и библиотека jQuery.



Теперь позвольте объяснить, что я понимаю под “скриптингом HTML-элементов”. При помощи jQuery совершенно тривиально решаются задачи вроде «визуально скрыть второй элемент h2 в документе .html. Код jQuery для такой задачи выглядел бы так:



jQuery('h2:eq(1)').hide();


Давайте немного разберем эту строку с кодом jQuery. Сначала вызывается функция jQuery(), ей мы передаем специальный CSS-селектор библиотеки jQuery, выбирающий второй элемент h2 в HTML-документе. Затем вызывается метод jQuery.hide(), скрывающий элемент h2. Вот как прост и семантически выразителен код jQuery.



Теперь сравним его с нативным DOM-кодом, который потребовалось бы написать, если бы мы не работали с jQuery.



document.querySelectorAll('h2')[1].style.setProperty('display','none');


Какой вариант было бы удобнее написать? А читать, а отлаживать? Также учтите, что вышеприведенный нативный DOM-код предполагает, что все браузеры поддерживают использованные здесь методы DOM. Однако оказывается, что некоторые старые браузеры не поддерживают querySelectorAll() или setProperty(). Поэтому вышеприведенный код jQuery вполне нормально работал бы в IE8, а нативный код DOM вызвал бы ошибку JavaScript. Но, все-таки, даже если бы обе строки кода работали повсюду, какую из них было бы проще читать и писать?



Имея дело с jQuery, можно не беспокоиться о том, какой браузер что поддерживает, либо какой DOM API в каком браузере может забарахлить. Работая с jQuery, вы сможете работать быстрее решать задачи на более простом коде, и при этом не беспокоиться, так как jQuery абстрагирует за вас многие проблемы.



jQuery = JavaScript?



Поскольку jQuery повсеместно распространена, то вы, возможно, не вполне представляете, где заканчивается JavaScript и начинается jQuery. Для многих веб-дизайнеров и начинающих разработчиков HTML/CSS, библиотека jQuery — это первый контакт с языком программирования JavaScript. Поэтому jQuery иногда путают с JavaScript.



Первым делом давайте оговоримся, что JavaScript – это не jQuery и даже не сам DOM API. jQuery – это сторонняя свободная библиотека, написанная на JavaScript и поддерживаемая целым сообществом разработчиков. Кроме того, jQuery не относится к числу стандартов тех организаций (напр., W3C), которые пишут спецификации HTML, CSS или DOM.



Не забывайте, что jQuery служит прежде всего как «сахар» и используется поверх DOM API. Этот сахар помогает работать с интерфейсом DOM, который печально известен своей сложностью и обилием багов.



jQuery – это просто полезная библиотека, которой можно пользоваться при написании сценариев для HTML-элементов. На практике большинство разработчиков прибегают к ней при DOM-скриптинге, поскольку ее API позволяет решить больше задач меньшим количеством кода.



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



Два краеугольных камня jQuery



Две базовые концепции, на которых основана jQuery, таковы: “найди и сделай” и “пиши меньше, делай больше.”

Две этих концепции можно развернуть и переформулировать в виде следующего утверждения: первоочередная задача jQuery заключается в организации выбора (то есть, нахождении) или в создании HTML-элементов для решения практических задач. Без jQuery для этого потребовалось бы больше кода и больше сноровки в обращении с DOM. Достаточно вспомнить рассмотренный выше пример с сокрытием элемента h2.



Следует отметить, что круг возможностей jQuery этим не ограничивается. Она не просто абстрагирует нативные DOM-взаимодействия, но и абстрагирует асинхронные HTTP-запросы (т.н. AJAX) при помощи объекта XMLHttpRequest. Кроме того, в ней есть еще ряд вспомогательных решений на JavaScript и мелких инструментов. Но основная польза jQuery заключается именно в упрощении HTML-скриптинга и просто в том, что с ней приятно работать.



Еще добавлю, что польза jQuery – не в успешном устранении браузерных багов. «Краеугольные камни» нисколько не связаны с этими аспектами jQuery. В долгосрочном отношении самая сильная сторона jQuery заключается в том, что ее API абстрагирует DOM. И эта ценность никуда не денется.



Как jQuery сочетается с современной веб-разработкой



Библиотеке jQuery уже десять лет. Она создавалась для той эпохи веб-разработки, которую мы уже безусловно миновали. jQuery не является незаменимой технологией для работы с DOM или выполнения асинхронных HTTP-запросов. Практически все, что можно сделать с jQuery, можно сделать и без нее. А если вас интересует всего лишь пара мелких простых взаимодействий с DOM в одном-двух современных браузерах, то возможно, лучше будет воспользоваться нативными DOM-методами, а не jQuery.



Однако, при любых разработках, связанных с BOM (браузерной моделью документа) или DOM, а не только с косметическими взаимодействиями, следует пользоваться jQuery. В противном случае вы станете изобретать велосипед (т.e. элементы абстракций jQuery), а потом испытывать его на всевозможных дорожках (т.e в мобильных браузерах и браузерах для ПК).



Опытные разработчики знают, что такое «стоять на плечах гигантов», и когда следует избегать излишней сложности. В большинстве случаев нам все равно не обойтись без jQuery, когда нужно в сжатые сроки выполнить нетривиальную работу, связанную с HTML и DOM.



Кроме того, даже если бы jQuery не решала ни единой проблемы с DOM или с разношерстными браузерными реализациями спецификации DOM, важность самого API ничуть бы не уменьшилась, поскольку он так удобен для HTML-скриптинга.



Причем jQuery совершенствуется, и с ее помощью программисты могут работать толковее и быстрее. Такова ситуация сегодня, так было и на момент создания библиотеки. Сказать «мне не нужна jQuery» — все равно, что утверждать «обойдусь без lo-dash или underscore.js». Разумеется, можно без них обойтись. Но об их ценности судят не по этому.

Их ценность — в API. Из-за излишней сложности разработка может замедляться. Поэтому нам и нравятся такие вещи как lo-dash и jQuery – с ними все упрощается. А поскольку jQuery облегчает выполнение сложных задач (например, писать сценарии для HTML), она не устареет.



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



Приложение – важные факты об jQuery



Наконец, перечислю некоторые важные факты, касающиеся jQuery.




  • Библиотеку jQuery написал Джон Резиг (John Resig), ее релиз состоялся 26 августа 2006. Джон признавался, что написал этот код, чтобы “произвести революцию во взаимодействии JavaScript с HTML”.

  • jQuery считается наиболее популярной и востребованной современной библиотекой JavaScript.

  • jQuery – свободное ПО, предоставляемое по лицензии MIT.

  • Существует две версии jQuery. Версия 1.x поддерживает Internet Explorer 6, 7 и 8\, а 2.x поддерживает только IE9+. Если вам требуется поддержка IE8, то придется работать с версией 1.x. Но это нормально, обе версии по-прежнему активно разрабатываются.

  • Минимальная версия jQuery 2.x имеет размер 82kb. В архиве Gzip — около 28k.

  • Минимальная версия jQuery 1.x имеет размер 96kb. В архиве Gzip — около 32k.

  • Исходный код jQuery доступен на Github.

  • На основе исходного кода с Github можно создать собственную версию jQuery.

  • jQuery можно установить при помощи менеджера пакетов bower или npm (т.e. $ bower install jquery or npm install jquery).

  • У jQuery есть официальная сеть CDN, в которой можно взять различные версии jQuery.

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

  • jQuery обладает обширным набором плагинов. Можно приобрести высококачественные плагины для enterprise-разработки (напр. Kendo UI) или воспользоваться не менее классными бесплатными (напр. Bootstrap).

  • jQuery можно разбить на категории (в соответствии с разбиением документации API ).




  • ajax

  • attributes

  • callbacks object

  • core

  • CSS

  • data

  • deferred object

  • dimensions

  • effects

  • events

  • forms

  • internals

  • manipulation

  • miscellaneous

  • offset

  • properties

  • selectors

  • traversing

  • utilities





Актуальность книги






































Проголосовало 95 человек. Воздержалось 35 человек.





Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.


Original source: habrahabr.ru.

https://habrahabr.ru/post/308134/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
Tatiana_pirogova

Poleznie i nezhelatelnie veshi v dome

Воскресенье, 17 Июля 2016 г. 21:53 (ссылка)

Это цитата сообщения Алиция_Гадовская Оригинальное сообщение

Полезные и нежелательные вещи для дома




1868538_ (700x522, 68Kb)



Что полезно иметь в доме



Цветы в горшках



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



Выделанные шкуры в доме (офисе или магазине)



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



Засушенные цветы в вазе



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



Читать далее...
Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество
rss_rss_hh_new

[recovery mode] Почему нельзя использовать Backbone.js в 2016 году

Понедельник, 09 Мая 2016 г. 07:15 (ссылка)

Сейчас я надену костюм моего нелюбимого супергероя, Капитана Очевидности, и через лень напишу эту статью. Она призвана с помощью небольшого примера показать один серьезный недостаток фреймворков прошлого поколения и, в частности, BackboneJS с обвесом типа Marionette, вынуждающих программиста вручную манипулировать DOM-деревом. Казалось бы, тема обсосана еще со времен первого AngularJS, но нет. Зачем я это сделаю? Ответ в самом конце статьи.



Смотрите, предположим нам поставили задачу реализовать простую форму:







var MyFormView = Marionette.ItemView.extend({
template: 'myForm',
className: 'my-form',
ui: {
$submit: '.js-submit'
},
events: {
'click @ui.$submit': 'submit'
},
send: function () {
myAsyncSubmit
.done(function () {
alert('Form submitted!');
})
.fail(function () {
alert('Error occured!')
});
}
});









Все просто, но у посетителя есть возможность сабмитить форму сколько угодно раз после уже отправки запроса. Блокируем кнопку до того, как станет понятно, что произошло с запросом:







var MyFormView = Marionette.ItemView.extend({
template: 'myForm',
className: 'my-form',
ui: {
$submit: '.js-submit'
},
events: {
'click @ui.$submit': 'submit'
},
submit: function () {
this.ui.$submit.prop('disabled', true);

myAsyncSubmit
.done(function () {
alert('Form submitted!');
})
.fail(function () {
alert('Error occurred!')
})
.always(function () {
this.ui.$submit.prop('disabled', true);
});
}
});




Далее форма долго или не очень живет своей жизнью до того дня, как ее не понадобится немного модифицировать. Теперь форма должна выглядеть так:







Поле «Your ZIP» забирает на сервере информацию по заданному ZIP и подставляет ее в поля ниже. Это позволяет обойтись без ввода «Your Region» и «Your City», но поэтому при нажатии кнопки «Set», блокируются поля «Your Region», «Your City» и кнопка «Submit» до завершения запроса, вот так:







Правим код:



var MyFormView = Marionette.ItemView.extend({
template: 'myForm',
className: 'my-form',
ui: {
$inputZip: '#inputZip',
$setZip: '.js-set-zip',
$inputRegion: '#inputRegion',
$inputCity: '#inputCity',
$submit: '.js-submit'
},
events: {
'click @ui.$setZip': 'setZip',
'click @ui.$submit': 'submit'
},
setZip: function () {
toggleZipInputs(true);

myAsyncSetZip
.done(function () {
alert('Form submitted!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
toggleZipInputs(false);
});

function toggleZipInputs (value) {
this.ui.$inputZip.prop('disabled', value);
this.ui.$setZip.prop('disabled', value);
this.ui.$inputRegion.prop('disabled', value);
this.ui.$submit.prop('disabled', value);
}.bind(this);
},
submit: function () {
this.ui.$submit.prop('disabled', true);

myAsyncSubmit
.done(function () {
alert('Form submitted!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
this.ui.$submit.prop('disabled', true);
});
}
});









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







Увеличение на этот раз лишь количественное, смысл работы полей остался тот же самый — кнопка «Set Your Car Number» на время выполнения запроса блокирует поля «Your Car Model» и «Your Car Age», кнопка «Set Your Social ID» делает тоже самое с полями «Your Gender», «Your Age» и «Your Sexual Orientation». Обе они также блокируют кнопку «Submit»:











Ооокей, пишем код:



var MyFormView = Marionette.ItemView.extend({
template: 'myForm',
className: 'my-form',
ui: {
$inputZip: '#inputZip',
$setZip: '.js-set-zip',
$inputRegion: '#inputRegion',
$inputCity: '#inputCity',
$inputCarNumber: '#inputCarNumber',
$setCarNumber: '.js-set-car-number',
$inputCarModel: '#inputCarModel',
$inputCarAge: '#inputCarAge',
$inputSocialId: '#inputSocialId',
$setSocialId: '.js-set-social-id',
$inputGender: '#inputGender',
$inputAge: '#inputAge',
$inputSexualOrientation: '#inputSexualOrientation',
$submit: '.js-submit'
},
events: {
'click @ui.$setZip': 'setZip',
'click @ui.setCarNumber': 'setCarNumber',
'click @ui.$submit': 'submit'
},
setZip: function () {
toggleZipInputs(true);

myAsyncSetZip
.done(function () {
alert('Form submitted!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
toggleZipInputs(false);
});

function toggleZipInputs (value) {
this.ui.$inputZip.prop('disabled', value);
this.ui.$setZip.prop('disabled', value);
this.ui.$inputRegion.prop('disabled', value);
this.ui.$submit.prop('disabled', value);
}.bind(this);
},
setCarNumber: function () {
toggleCarInputs(true);

myAsyncSetCarNumber
.done(function () {
alert('Car Number set!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
toggleCarInputs(false);
});

function toggleCarInputs (value) {
this.ui.$inputCarNumber.prop('disabled', value);
this.ui.$setCarNumber.prop('disabled', value);
this.ui.$inputCarModel.prop('disabled', value);
this.ui.$inputCarAge.prop('disabled', value);
this.ui.$submit.prop('disabled', value);
}.bind(this);
},
setSocialId: function () {
toggleSocialInputs(true);

myAsyncSetSocial
.done(function () {
alert('Social ID set!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
toggleSocialInputs(false);
});

function toggleSocialInputs (value) {
this.ui.$inputSocialId.prop('disabled', value);
this.ui.$setSocialId.prop('disabled', value);
this.ui.$inputGender.prop('disabled', value);
this.ui.$inputAge.prop('disabled', value);
this.ui.$inputSexualOrientation.prop('disabled', value);
this.ui.$submit.prop('disabled', value);
}.bind(this);
},
submit: function () {
this.ui.$submit.prop('disabled', true);

myAsyncSubmit
.done(function () {
alert('Form submitted!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
this.ui.$submit.prop('disabled', true);
});
}
});









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







Думаю, дальше можно не объяснять — при дальнейшем усложнении формы нам нужно будет создавать ссылки на каждый элемент формы, состояние которого будет меняться, а затем вручную изменять его состояние. Насколько это плохо в реальности, а не на демо-примере? Очень плохо. Я проработал с BackboneJS и его окружением два года, и это самый большой минус этого фреймворка — постоянно растущее количество кода и сложность его обслуживания.



С момента появления фреймворков нового поколения типа React+Redux, целесообразность использования BackboneJS лично для меня стала равна нулю. Вот тот же код с использованием React+какой-нибудь контроллер. Сравните даже не столько количество кода, а смысл происходящего в нем — здесь нет ни одной манипуляции с DOM вручную, той кучи сложноподдерживаемого кода из прошлых примеров:



var MyForm = React.createClass({
var self = this;
this.setState({ isZipSetting: true });

myAsyncSetZip
.done(function () {
alert('Zip set!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
self.setState({ isZipSetting: false });
});
},
setCarNumber: function () {
var self = this;
this.setState({ isCarNumberSetting: true });

myAsyncSetCarNumber
.done(function () {
alert('Car number set!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
self.setState({ isCarNumberSetting: false });
});
},
setSocialId: function () {
var self = this;
this.setState({ isSocialIdSetting: true });

myAsyncSetSocialId
.done(function () {
alert('Social ID set!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
self.setState({ isSocialIdSetting: false });
});
},
submit: function () {
var self = this;
this.setState({ isSubmitting: true });

myAsyncSetZip
.done(function () {
alert('Form submitted!');
})
.fail(function () {
alert('Error occured!')
})
.always(function () {
self.setState({ isSubmitting: false });
});
},
render: function () {
return (
















































































);
}
});




Послесловие.



Если у вас возник вопрос, зачем такие очевидные вещи писать в javascript-хабе, ведь React-одепты итак достали уже абсолютно всех, то у вас очень резонное замечание, потому что они конкретно достали и меня тоже. Но я не смог забить на это после того как встретил непробиваемое невежество в мирном с виду топике, приведя там похожий код. После чего не поленился и написал эту статью с примерами. Самый жир:



Пишу на BB давно и много. От прямой манипуляции с DOM отказался сразу, при этом давления со стороны библиотеки не испытал.


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


PS Да реакт клевый, было время я думал на него перевести приложения. Но, стильно/модно/молодежно — оставим для новичков. После глубокого анализа — бенефит был нулевой.


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


Мне даже шаблоны не нужны. А вот вы нагородили кучу всего. Повторюсь, вникните в суть фреймворков.




P.S.




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

  • Если вы считаете код на Marionette предвзятым, напишите свой код, лучше и проще, я сделаю апдейт поста.

  • Если вы по своей воле выбираете Backbone-like фреймворк для старта вашего проекта в 2016 году, то мне очень интересно узнать, почему вы так поступаете.





Original source: habrahabr.ru.

https://habrahabr.ru/post/283148/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best

Метки:   Комментарии (0)КомментироватьВ цитатник или сообщество

Следующие 30  »

<dom - Самое интересное в блогах

Страницы: [1] 2 3 ..
.. 10

LiveInternet.Ru Ссылки: на главную|почта|знакомства|одноклассники|фото|открытки|тесты|чат
О проекте: помощь|контакты|разместить рекламу|версия для pda