Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Carbon.JS JavaScript framework (https://javascript.ru/forum/project/7571-carbon-js-javascript-framework.html)

Cr@ZyBoY 08.02.2010 16:30

Carbon.JS JavaScript framework
 
Всем привет! Решил, что пора уже заявить о своём творении.
Итак, представляю Carbon.JS (http://carbonjs.com) - jQuery-подобный велосипед собственного сочинения.
Особенности моей библиотеки: очень быстрое ядро, которое выбирает элементы по CSS-селекторам, модульность (на данный момент 6 модулей).
Таблица сравнения скорости с jQuery 1.4: http://carbonjs.com/2010/02/carbon-j...-1-8/#more-140, тест SlickSpeed - http://carbonjs.com/demo/slickspeed/.
В фреймворке присутствуют функции для работы с DOM, Ajax, функция анимации и пр.
Раздел демонстрации пока не готов, хотя можете полазить в папке ./demo/. На сайте есть документация, репозиторий и форум. Очень интересно ваше мнение, может кто-нибудь даже захочет помочь в разработке.

Octane 08.02.2010 17:04

На селекторах свет клином сошелся похоже :D

Cr@ZyBoY 08.02.2010 17:15

Эмм, это как понять?

Octane 08.02.2010 17:27

Неужели, вы, опытный JavaScript-программист, используете сложные CSS-селекторы в JavaScript, делая ваши скрипты, сильно зависимыми от вёрстки?

Cr@ZyBoY 08.02.2010 17:54

Лично я нет. Но никогда не знаешь, что где может понадобиться, поэтому почему бы не сделать ядро максимально функциональным в плане поддержки селекторов?
Ну и к тому же, это чисто спортивный интерес: типа, такое сделали в jQuery, Prototype и т.п., а чем я хуже? Пусть увидят, на что способен парень из страны, где по улицам ходят медведи в лаптях и все на ночь пьют водку с молоком.

Kolyaj 08.02.2010 17:58

Цитата:

Сообщение от Cr@ZyBoY
Пусть увидят, на что способен парень из страны, где по улицам ходят медведи в лаптях и все на ночь пьют водку с молоком.

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

Octane 08.02.2010 17:59

Ясно. Своих идей нет.

Cr@ZyBoY 08.02.2010 18:36

Свои идеи есть всегда, но почему бы не улучшить чужие? Пусть этих движков уже дофига, ну и что. Конкуренция - двигатель прогресса. ИМХО, чем больше выбор, тем лучше.
Да и к тому же у меня не просто один только движок селекторов, но и полноценная библиотека.

PeaceCoder 08.02.2010 20:29

Таксь. Ядро проанализировал. Говорю сразу кеш можете выкинуть. он не нужен, только испортит выборку.
Пример: сделали выборку, добавили элемент в дом и сделали еще раз такую выборку - получаем теже элементы, а новый не добавляется.
Это раз.
Два.
Q('* SPAN I + SPAN DIV B + *')

Заместь * представте что интересует не тег как фильтр, а сам фильтр, например атрибуты. И тут то ваш скрипт и полетел. jQ в два раза быстрее Вашего в этом случае. Этот метод я уже давно продумал выбирать все элементы в текущем контексте потом в каждом полученном выбирать новые + это все проверять(отсеивать), оч много лишних действий.
А еще баг есть
У Вас там есть такая фишка
315	var selectors = iargs.replace(/\s?(>|\+|~)\s?/g, "$1")

Тут вы убираете пробелы между комбаноториками, а не подумали что может быть такой запрос (привожу как пример)
Q('* SPAN I[name=Вася + Пупкин] + SPAN DIV B + *')

В данном случае фильтр искорябится...

П.С. тестил как Ваш, так и jQ без querySelectorAll и кешей. Задумка неплохая, и кстати понравилась фишка с getByCombinators.
П.П.С Отмечу что у Вас нет такого бага "+" как в jQuery это радует и вообще техника выборки другая => селекторы работают как надо. в JQ в этом плане есть немного багов

tenshi 08.02.2010 20:31

ядро - это грозно сказано х)))
если твой движок селекторов так крут - ну так и развивай jquery встроив движок в него

tenshi 08.02.2010 20:39

по коду - не стоит делать гигантских двумерных функций

PeaceCoder 08.02.2010 20:40

Цитата:

Сообщение от tenshi
если твой движок селекторов так крут - ну так и развивай jquery встроив движок в него

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

Cr@ZyBoY 08.02.2010 21:21

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

tenshi,
как я уже написал на своём сайте, я не собираюсь делать очередной jQuery, и тем более модернизировать его. Почему? Не люблю ковыряться в чужом навороченном коде. Я как-то пытался понять, а как же оно там всё устроено... И решил, что проще написать свою библиотеку.

PeaceCoder 08.02.2010 22:07

Цитата:

Сообщение от Cr@ZyBoY
Просто на этот счёт во всех функциях из DOM-модуля есть функция автоматического обновления кэша, соответственно таких проблем возникнуть не должно.

Другими словами DOM привязан к вашему ФВ. А это плохо и если сторонний срипт(какойто модуль другого человека или еще что) изменит вручную дом контент, то эффект от Ваших селекторов 0. А если например innerHTML=....

Cr@ZyBoY 08.02.2010 22:36

Ну, можно ещё пошаманить с MutationEvents.

PeaceCoder 08.02.2010 23:31

Цитата:

Сообщение от Cr@ZyBoY
MutationEvents.

Они поддерживаются, ито плохо, вроде только в MZ и Safari

tenshi 08.02.2010 23:43

Цитата:

как я уже написал на своём сайте, я не собираюсь делать очередной jQuery, и тем более модернизировать его. Почему? Не люблю ковыряться в чужом навороченном коде. Я как-то пытался понять, а как же оно там всё устроено... И решил, что проще написать свою библиотеку.
напиши свою либу с тем же апи и засунь вместо sizzle

PeaceCoder 09.02.2010 01:51

Cr@ZyBoY,
Кстати спасибо за идею разделения getByCombinators. Если я на верном пути, а это кажется так, то вроде допер как быстро выбрать нужные элементы не затрачивая практически времени. ща буду соединять логику jQ и твою...

Riim 09.02.2010 08:31

Array.prototype.inArray = function(value) {
	var i = 0, ii;
	while (ii = this[i++]) {
		if (ii === value) return true;
	}
	return false;
};


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

Вторая перезапись (i++) срабатывает лишний раз в последней итерации цикла.

Вообще все циклы очень не оптимизировано написаны.




CarbonJS.onDOMready = function(func) {
	var init = function() {
		if (arguments.callee.done) return;
....


ужасно написано:
- отдельный Interval для каждого вызова, можно обойтись одним.
- целевая функция должна вызываться в контексте document так как является обработчиком события DOMContentLoaded (в идеале) которое принадлежит документу.
- способ для отслеживания readyState в WebKit давно не имеет смысла, версиями браузеров для которых он придуман уже давно вообще никто не пользуется.
- вызов CarbonJS.onDOMready после onload уходит в пустоту, может это и правильно, но обычно это не так, кроме того при этом останутся Interval-ы которые уже никогда не будут сброшены.
- перезапись window.onload.
- вместо defer лучше использовать doScroll.

Мой старый вариант с defer:
http://javascript.ru/forum/events/60...d-i-defer.html
Octane там объяснил чем doScroll лучше.




window.onunload = function() { // Чтобы избежать утечек памяти во всеми любимом браузере, удаляем вручную все установленные обработчики событий
	while (CarbonJS.events.length > 0) Q(CarbonJS.events[0].obj).removeEvent(CarbonJS.events[0].evt);
};


если я через addEvent назначу событие onunload, то unload удаляющий все события вероятно сработает раньше моего (мой unload удалится и не сработает), window.onunload тоже занят, и как мне теперь свой unload поставить?




cl = cl.split(" "); // Чтобы удалить класс, сначала разбиваем className на массив значений


разделителем имен может быть любой пробельный символ, а не только пробел.




while (++i < cl.length) ncl += cl[i]; // и перезаписываем className


Array#join


//----------------

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

Cr@ZyBoY 09.02.2010 12:22

PeaceCoder,
да не за что. Кстати, интересно поглядеть на ваш движок. Kolyaj говорил, что он где-то в соседней теме, но я что-то не нашёл...

Riim,
на мой выбор такого типа циклов повлияла вот эта статья - http://habrahabr.ru/blogs/yass/49679/ ("Перебор массива"). Если вы знаете более быстрый способ - пожалуйста, я его рассмотрю и протестирую.
Про onDOMready: это отголоски моей первой библиотеки 2-летней давности, код я пересмотрю. Большую часть функций из модуля utilities я тоже буду переписывать, просто ещё руки не дошли.
Насчёт циклов я своё мнение уже сказал. Если вас не затруднит, посмотрите подробнее другие модули.

PeaceCoder 09.02.2010 15:42

Цитата:

Сообщение от Cr@ZyBoY
да не за что. Кстати, интересно поглядеть на ваш движок. Kolyaj говорил, что он где-то в соседней теме, но я что-то не нашёл...

Не совсем в соседней. Там ток наброски селекторов.
Скорость Выбоки jQuery

Движок селекторов еще в разработке, вот еще бьюсь над оптимизацией обьем/скорость.

П.С. Спс за ссылочку. Хорошая статья. надо будет залезть опять webo.in почитать. Новое смотрю появилось.

tenshi 09.02.2010 16:03

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

подкидываю бесплатную идею: сделать анимацию, основанную на классах
например:

.passive { background: blue; font-size: 1.2em }
.active { background: red; font-size: .8em }


Animator( element ).removeClass('passive').addClass('active').setDuration(1000)

возможность задания отдельной формулы для каждого поля - приветствуется

PeaceCoder 09.02.2010 16:30

F$(element).class('passive=').delay(1000,function(){this.class('active')});

В моем случае.
Или я не правильно понял? (убирает класс а через 1сек ставит актив.)

tenshi 09.02.2010 16:37

твой вариант не очень похож на анимацию х))

Cr@ZyBoY 09.02.2010 16:42

tenshi,
не совсем понял, что вы имеете в виду.
У меня, например, можно сделать такую анимацию на основе описанных вами классов:
Q(element).change({
  "background": ["00f", "f00"],
  "font-size": [12, 8]
}, CarbonJS.Transitions.Line.EaseIn, 1000);

Только у меня все размерные величины в px считаются, em и пр. задавать нельзя самому.

PeaceCoder 09.02.2010 17:06

Цитата:

Сообщение от tenshi
твой вариант не очень похож на анимацию х))

Ты предлагаешь по имени класса найти его в cssRules взять оттуда параметры для анимации и с анимировать? если да то это хорошая идея надо будет подумать.

tenshi 09.02.2010 17:19

да, именно так %-)

tenshi 09.02.2010 17:20

> У меня, например, можно сделать такую анимацию на основе описанных вами классов:

а где отделение оформления от поведения? ;-)

Cr@ZyBoY 09.02.2010 17:25

А зачем мне отделять оформление от поведения? По-моему в скрипте и так всё понятно.

Kolyaj 09.02.2010 17:28

Цитата:

Сообщение от Cr@ZyBoY
По-моему в скрипте и так всё понятно.

Пока скрипт маленький.

Cr@ZyBoY 09.02.2010 17:30

Я не понял, что конкретно вам не понравилось, ткните пожалуйста пальцем. В моём понимании оформление и поведение - это разделение HTML-кода и скриптов, но причём тут css, который употребляется внутри отдельно взятой функции?

tenshi 09.02.2010 17:43

> А зачем мне отделять оформление от поведения?
чтобы поправить цвета мог кто угодно, а не только тот, кто это написал

PeaceCoder 09.02.2010 17:44

Цитата:

Сообщение от Cr@ZyBoY
но причём тут css, который употребляется внутри отдельно взятой функции?

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

Cr@ZyBoY 09.02.2010 17:47

Ок, тогда тоже запишу себе в ToDo.

Riim 10.02.2010 13:07

Цитата:

Сообщение от Cr@ZyBoY
на мой выбор такого типа циклов повлияла вот эта статья

статья почти правильная, но вот поняли вы ее видимо не совсем правильно, вот эта фраза:

Цитата:


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

про кэширование сказано, но вот ни слова нет о том, в каких ситуациях это кэширование даст прирост производительности. Например, такой код:
obj.prop;
obj.prop;
obj.prop;
obj.prop;


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

var t = obj.prop;
t;
t;
t;
t;


вместо четырех считываний свойств (4X) теперь одно считывание и одна перезапись (2X), т. е. производительность улучшилась примерно в два раза. Однако если свойство считывается только один раз, то его кэширование приведет к ухудшению производительности, что и происходит в большинстве ваших циклов, цикл хоть и много раз срабатывает, но имя считываемого свойства меняется в каждой итерации.


UPD: не понимаю как без самых основ по оптимизации кода можно браться писать движки для выборки по css-селекторам.

Cr@ZyBoY 10.02.2010 13:33

Riim,
ну, не в большинстве, конечно, но учту в следующий раз.
Цитата:

не понимаю как без самых основ по оптимизации кода можно браться писать движки для выборки по css-селекторам
Меня почему-то совесть не мучает, если учесть, что мой движок быстрее чем Sizzle, base2, DOMAssistant, Prototype, MooTools, Dojo и Peppy.

Dmitry A. Soshnikov 10.02.2010 15:43

Cr@ZyBoY, работа проделана немалая (и по самому фреймворку, и по оформлению сайта, и по PR-у на сайте; главное, чтобы PR соответствовал тому, что есть на самом деле). Как минимум, если фреймворк не станет популярным - Вы набрались опыта. А так - продвигайте, мотивируйте, собирайте комьюнити, возможно, кто-то заинтересуется всерьёз и будет использовать.

Но это будет нелегко, даже несмотря на то, что движок селекторов у Вас быстрее: у монстров типа jQuery и т.д. совершенно другие ресурсы (деньги и т.д.) вбуханы в PR и продвижение.

Успехов ;)

Cr@ZyBoY 10.02.2010 16:13

Спасибо, стараемся :) Да, денег я, конечно, не вкладываю в пиар, да и молод я ещё... А так уже есть планы по использованию Карбона в движке форума ExBB, вроде на этой неделе собирались устроить конференцию в скайпе, будем обсуждать в том числе и интеграцию моей библиотеки :)

PeaceCoder 10.02.2010 16:27

Цитата:

Сообщение от Riim
вместо четырех считываний свойств (4X) теперь одно считывание и одна перезапись (2X), т. е. производительность улучшилась примерно в два раза

Только Вы забыли что если кешировать простое число или строку то запись в кешированную переменную бессмысленна.

На счет движков селекторов.
В документе 1360 элементов, включая такой HTML
<span id='id1' class='SPAN'>
  <i></i>
  <span id='id3'>
    <i>
      <span>
        <div>
          <b>
            <a class='SPAN1 ppp'>1</a>
          </b>
          <a id='id4'>2</a>
        </div>
      </span>
    </i>
    <span id='id2'>
      <div>
        <b>
          <a id='id3'>3</a>
        </b>
        <a id='id5'>4</a>
      </div>
    </span>
  </span>
</span>

Принудительно во всех движках отключен кеш и возможность querySelectorAll
На запрос (должен выдавать 2 элемента SPAN#id3,A#id3)
#id1 #id3

Такие результаты:
jQ: 0.1576мс, результат: SPAN#id3 (неверно)
Peppy: 0.1869мс, результат: SPAN#id3 (неверно)
DOMAssistant: 1.86мс, результат: SPAN#id3, A#id3 (верно)
CarbonJS: 0.075мс, результат: SPAN#id3 (неверно)

На запрос (должен выдать 2 элемента A#id4,A#id5)
* SPAN I + SPAN DIV B + *

Такие результаты:
jQ: 6.83мс, результат: A#id5 (неверно)
Peppy: 70мс, результат: A#id4,A#id5 (верно)
DOMAssistant: 10.571мс, результат: A#id4,A#id5 (верно)
CarbonJS: 12.84мс, результат: A#id4,A#id5 (верно)

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

Cr@ZyBoY 10.02.2010 16:38

PeaceCoder,
попридержите коней. Откуда у вас в html-коде взялось 2 элемента с одним id? Это прямое нарушение стандарта.
По поводу селектора "* SPAN I + SPAN DIV B + *" - вы же не каждый день такую мешанину ищите. На более простых селекторах, которые встречаются чаще всего, Карбон выигрывает.


Часовой пояс GMT +3, время: 22:01.