abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 00:22 | Pozvánky

Richard Stallman, zakladatel hnutí svobodného softwaru, projektu GNU a Free Software Foundation, vystoupí 6. června od 17:30 v Brně v kině Scala se svou přednáškou Free Software Movement and GNU/Linux Operating System. Přednášku organizuje Ústav práva a technologií Masarykovy univerzity.

Ladislav Hagara | Komentářů: 23
17.5. 21:11 | IT novinky

Hewlett Packard Enterprise (NYSE:HPE) kupuje společnost Cray Inc. (Nasdaq:CRAY) za přibližně 1,3 miliardy dolarů. Výrobce superpočítačů Cray má v seznamu 500 nejvýkonnějších superpočítačů na světě TOP500 aktuálně 52 superpočítačů. S Intelem staví další superpočítač Aurora. S AMD staví superpočítač za 600 milionů dolarů s názvem Frontier. Ten by měl v roce 2021 převzít vedení v TOP500.

Ladislav Hagara | Komentářů: 0
17.5. 19:44 | Zajímavý projekt

Ondřej Kokešpodcastu Dataři představuje projekt Česká otevřená data. Jedná se o sadu skriptů, které stahují především finanční data poskytovaná státními institucemi. V rozhovoru vysvětluje, že ke správné interpretaci dat jsou potřeba doménové znalosti, a popisuje zkušenosti, jak získat dokumentaci, která u datových sad často chybí.

Fluttershy, yay! | Komentářů: 0
17.5. 10:11 | Zajímavý projekt

Nadace XPRIZE vyhlásila před pěti lety soutěž Global Learning XPRIZE o nejlepší open source výukový program nebo inovativní způsob výuky, který umožní dětem v rozvojových zemích samostatně se naučit číst, psát a počítat. Tento týden byly vyhlášeny výsledky (YouTube). O první místo a 10 milionů dolarů se podělili Kitkit School a onebillion. Pět vítězných výukových programů bylo zveřejněno na GitHubu.

Ladislav Hagara | Komentářů: 19
17.5. 06:00 | Komunita

Dalších šest produktů od společnosti ThinkPenguin získalo certifikaci RYF (Respects Your Freedom, Respektuje vaši svobodu) udělovanou Nadací pro svobodný software (FSF). Certifikaci RYF má nově například také převodník z USB na paralelní port (LPT). Certifikace RYF byla představena v říjnu 2012.

Ladislav Hagara | Komentářů: 9
16.5. 23:11 | Pozvánky

Dnes je Světový den přístupnosti, anglicky Global Accessibility Awareness Day (GAAD, Wikipedie). Světový den přístupnosti vznikl v roce 2012. Jeho smyslem je šířit osvětu v této oblasti mezi širokou veřejností a motivovat ji k diskusím, přemýšlení a chuti dozvědět se o tématice přístupnosti webu, dokumentů, software, mobilních aplikací, asistivních technologiích či potřebách lidí s nejrůznějším postižením něco nového. O víkendu

… více »
Ladislav Hagara | Komentářů: 0
16.5. 19:55 | Pozvánky

Spolek OpenAlt zve příznivce otevřených řešení a přístupu na 164. brněnský sraz, který proběhne v pátek 17. května od 18:00 v restauraci Přístav u Vodů u Brněnské přehrady aneb v hantecu u Prýglu.

Ladislav Hagara | Komentářů: 2
16.5. 07:00 | Nová verze

Byla vydána nová major verze 9.0 svobodného systému pro řízení přístupu k síti (NAC) PacketFence (Wikipedie). Přehled novinek v oznámení o vydání. Pro uživatele předchozích verzí jsou k dispozici poznámky k aktualizaci.

Ladislav Hagara | Komentářů: 2
16.5. 06:00 | Bezpečnostní upozornění

K názvům Microarchitectural Data Sampling (MDS) a ZombieLoad Attack aktuálních bezpečnostních chyb v procesorech Intel přibyly nové názvy RIDL a Fallout. Na stránce RIDL and Fallout: MDS attacks jsou k dispozici další videoukázky, technické informace nebo i nástroj pro otestování, zda je konkrétní systém zranitelný. Ke stránkám ZombieLoad Attack, RIDL a Fallout lze přistupovat ze stránky CPU.fail.

Ladislav Hagara | Komentářů: 17
15.5. 18:22 | Zajímavý článek

V Edici CZ.NIC vyšla kniha Porty, bajty, osmibity od Martina Malého. Koupit ji lze tištěnou nebo zdarma stáhnout ve formátech PDF (3,6 MB), EPUB (10,8 MB ) a MOBI (28,7 MB). Jedná se o volné pokračování knihy Hradla, volty, jednočipy. Další informace ke knihám, odkazy na zdrojové kódy nebo errata na webových stránkách Porty, bajty, osmibity a Hradla, volty, jednočipy.

Ladislav Hagara | Komentářů: 24
GPU kterého výrobce aktuálně preferujete pro provoz Linuxu?
 (48%)
 (25%)
 (25%)
 (1%)
Celkem 292 hlasů
 Komentářů: 25, poslední 17.5. 18:39
Rozcestník

Reactor.js - moja odpoveď na ReactJS

26.9.2015 14:11 | Přečteno: 2386× | Web | Výběrový blog | poslední úprava: 28.9.2015 10:27

Dnešný blog bude tak trochu o benchmarkoch a tak trochu o porovnaní kódu ReactJS a reactor.js (názov reactor bol zvolený pred zverejnením ReactJS).

Obe knižnice majú podobnú filozofiu. Asi najväčší rozdiel je v šablónach - nemám napísaný kompilátor, takže DOM sa musí zatiaľ zapisovať priamo do kódu.

TODO aplikácia

Ako ukážku práce s oboma knižnicami som zvolil jednoduchú TODO aplikáciu. Začneme HTML kódom:

<!DOCTYPE html>
<html>
<head>
	<title>TODO</title>
	<meta charset="utf-8" />
</head>
<body>

<h1>TODO</h1>

<div id="container"></div>

<script src="react.js|reactor.js" type="text/javascript" charset="utf-8"></script>
<script src="todo_reactjs.js|todo_reactor.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>

Šablóny

// react.js
var PRIORITY_MAP = {
    1: 'Nízka',
    2: 'Stredná',
    3: 'Vysoká'
};



var Table = React.createClass({
    getInitialState: function() {
        return {todo: [], count: 0};
    },

    render: function() {
        return (
            <TABLE border="1">
                <THEAD>
                    <TR>
                        <TH>
                            Úloha (počet: {this.state.count})
                        </TH>
                        <TH>Priorita</TH>
                        <TH></TH>
                    </TR>
                </THEAD>
                <TodoList data={this.state.todo}></TodoList>
            </TABLE>
        );
    }
});

var Edit = React.createClass({
    render: function() {
        return (
            <DIV>
                <INPUT ref="input" type="text" />
                <SELECT ref="priority">
                    <OPTION value="1">Nízka</OPTION>
                    <OPTION value="2" selected="selected">Stredná</OPTION>
                    <OPTION value="3">Vysoká</OPTION>
                </SELECT>
                <BUTTON type="button">Pridať</BUTTON>
            </DIV>
        );
    }
});

var Item = React.createClass({
    render: function() {
        return (
            <TR className={"priority-" + this.props.priority}>
                <TD>{this.props.task}</TD>
                <TD>{this.props.priority_text}</TD>
                <TD>
                    <A ref="remove" href="#" onClick={this.removeItem}>Odstrániť</A>
                </TD>
            </TR>
        );
    }
});

var TodoList = React.createClass({
    priorityText: function(priority) {
        return PRIORITY_MAP[priority];
    },
    render: function() {
        var self = this;
        return (
            <TBODY>
                {this.props.todo.map(function(todo) {
                     return <Item key={todo.id}  task={todo.task} priority={todo.priority} priority_text={this.priorityText(todo.priority) id={todo.id}/>;
                })}
            </TBODY>
        );
    }
});


// --- skompilované ---

var Table = React.createClass({
    displayName: "Table",

    getInitialState: function() {
        return {todo: [], count: 0};
    },

    render: function render() {
        return React.createElement(
            'TABLE',
            { border: "1" },
            React.createElement(
                'THEAD',
                null,
                React.createElement(
                    'TR',
                    null,
                    React.createElement(
                        'TH',
                        null,
                        "Úloha (počet: ",
                        this.state.count,
                        ")"
                    ),
                    React.createElement(
                        'TH',
                        null,
                        "Priorita"
                    ),
                    React.createElement('TH', null)
                )
            ),
            React.createElement(TodoList, { todo: this.state.todo })
        );
    }
});

var Edit = React.createClass({
    displayName: "Edit",

    createTodoItem: function() {
        createTodoItem();
    },

    render: function render() {
        return React.createElement(
            'DIV',
            null,
            React.createElement('INPUT', { ref: "input", type: "text" }),
            React.createElement(
                'SELECT',
                { ref: "priority" },
                React.createElement(
                    'OPTION',
                    { value: "1" },
                    "Nízka"
                ),
                React.createElement(
                    'OPTION',
                    { value: "2", selected: "selected" },
                    "Stredná"
                ),
                React.createElement(
                    'OPTION',
                    { value: "3" },
                    "Vysoká"
                )
            ),
            React.createElement(
                'BUTTON',
                { type: "button", onClick: this.createTodoItem },
                "Pridať"
            )
        );
    }
});

var Item = React.createClass({
    displayName: "Item",

    removeItem: function() {
        var index = undefined;
        var self = this;
        todoList.forEach(function(listItem, i) {
            if (listItem.id === self.props.id) {
                index = i;
            }
        });
        if (index !== undefined) {
            todoList.splice(index, 1);
            todoTable.setState({count: todoList.length, todo: todoList});
        }
    },

    render: function render() {
        return React.createElement(
            'TR',
            { className: "priority-" + this.props.priority },
            React.createElement(
                'TD',
                null,
                this.props.task
            ),
            React.createElement(
                'TD',
                null,
                this.props.priority_text
            ),
            React.createElement(
                'TD',
                null,
                React.createElement(
                    'A',
                    { href: "#", onClick: this.removeItem },
                    "Odstrániť"
                )
            )
        );
    }
});

var TodoList = React.createClass({
    displayName: "TodoList",

    priorityText: function priorityText(priority) {
        return PRIORITY_MAP[priority];
    },

    render: function render() {
        var self = this;
        return React.createElement(
            'TBODY',
            null,
            this.props.todo.map(function (todo) {
                return React.createElement(Item, { key: todo.id, task: todo.task, priority: todo.priority, priority_text: self.priorityText(todo.priority), id: todo.id });
            })
        );
    }
});

// reactor.js


var PRIORITY_MAP = {
    1: 'Nízka',
    2: 'Stredná',
    3: 'Vysoká'
};


var templates = {
    'table':
        E('TABLE', [
            E('@border', '1'),
            E('THEAD', [
                E('TR', [
                    E('TH', [
                        E('#text', 'Úloha (počet: '),
                        E('#text=count', '0'),
                        E('#text', ')')
                    ]),
                    E('TH', [
                        E('#text', 'Priorita')
                    ]),
                    E('TH')
                ])
            ]),
            E('TBODY=todolist', [
            ])
        ]),
    'edit':
        E('DIV', [
            E('INPUT=input', [
                E('@type', 'text'),
            ]),
            E('SELECT=priority', [
                E('OPTION', [E('@value', '1'), E('#text', PRIORITY_MAP[1])]),
                E('OPTION', [E('@value', '2'),  E('@selected', 'selected'), E('#text', PRIORITY_MAP[2])]),
                E('OPTION', [E('@value', '3'), E('#text', PRIORITY_MAP[3])])
            ]),
            E('BUTTON=submit', [
                E('@type', 'button'),
                E('#text', 'Pridať')
            ])
        ]),
    'item':
        E('TR', [
            E('@class=priority_class', 'priority'),
            E('TD', [
                E('#text=task', '')
            ]),
            E('TD', [
                E('#text=priority', 'Normálna')
            ]),
            E('TD', [
                E('A=remove', [
                    E('@href', '#'),
                    E('#text', 'Odstrániť')
                ])
            ])
        ])
};


var widgets = {
    'item': Reactor.Widget({
        template: templates.item,
        construct: function() {
            var self = this;
            this.component.elements.remove.onclick = function() {
                self.modelInstance.remove(self.modelInstance.indexOf(self.data));
                return false;
            }
        },
        update: function(data) {
            this.component.set.task(data.task);
            this.component.set.priority(PRIORITY_MAP[data.priority]);
            this.component.set.priority_class('priority-' + data.priority);
        }
    })
};

Šablóny v reactorj.js sú podstatne jednoduchšie, neumožňujú použiť žiadnu logiku. Logiku je možné obaliť do inštancie Widget. Widget okrem iného podporuje automatickú aktualizáciu elementov pri zmene modelu (v tomto príklade túto vlastnosť nepoužívam).

Logika aplikácie

// react.js

var todoTable = undefined;
var addTodo = undefined;
var todoList = [];
var next = 0;
var tableContainer = undefined;
var editContainer = undefined;

var createUi = function() {
    tableContainer = document.createElement('DIV');
    editContainer = document.createElement('DIV');
    document.getElementById('container').appendChild(tableContainer);
    document.getElementById('container').appendChild(editContainer);
    todoTable = React.render(
        React.createElement(Table, null),
        tableContainer
    );
    addTodo = React.render(
        React.createElement(Edit, null),
        editContainer
    );
};

var loadList = function() {
    todoList.push({task: 'test', priority: '1', id: next});
    todoTable.setState({count: todoList.length, todo: todoList});
    next++;
};

var createTodoItem = function() {
    var task = React.findDOMNode(addTodo.refs.input).value;
    var priority = React.findDOMNode(addTodo.refs.priority).value;
    if (task) {
        React.findDOMNode(addTodo.refs.input).value = '';
        todoList.unshift({task: task, priority: priority, id: next});
        todoTable.setState({count: todoList.length, todo: todoList});
        next++;
    }
};

createUi();
loadList();
// reactor.js

var todoTable = undefined;
var addTodo = undefined;
var todoList = undefined;

var createUi = function() {
   todoTable = Reactor.Etree(templates.table);
   _.id('container').appendChild(todoTable.tree);

   addTodo = Reactor.Etree(templates.edit);
   _.id('container').appendChild(addTodo.tree);
};

var createList = function() {
   todoList = new Reactor.ListModel();
   new Reactor.ListView(
      todoTable.elements.todolist,
      todoList,
      widgets.item
   );
};

var registerEvents = function() {
   todoList.signals.inserted.connect(function() { todoTable.set.count(todoList.list.length) });
   todoList.signals.removed.connect(function() { todoTable.set.count(todoList.list.length) });
   addTodo.elements.submit.onclick = createTodoItem;
};

var loadList = function() {
   todoList.insert({task: 'test', priority: '1'}, 0);
};

var createTodoItem = function() {
   var task = addTodo.elements.input.value;
   var priority = addTodo.elements.priority.value;
   if (task) {
      addTodo.elements.input.value = '';
      todoList.insert({task: task, priority: priority}, 0);
   }
};

createUi();
createList();
registerEvents();
loadList();

Veľkosť a zložitosť kódu je porovnateľná.

react.jsreactor.jsrozdiel
120 riadkov127 riadkov6% kódu viacej

Veľkosť

Vo svojich projektoch si môžem dovoliť implementovať len to, takže rozdiel vo veľkosti knižnice asi nikoho neprekvapí.

react.jsreactor.jsušetrené
600572 B14474 B97.59 %

Benchmarky

Pre mňa sú dôležité 3 operácie - vytvorenie inštancie, modifikácia a prístup k elementom.

// react.js

var suite = new Benchmark.Suite;

var tbody = document.createElement('TBODY');
var todoItem = React.render(
    React.createElement(Item, null),
    tbody
);

suite.add('Get reference', function() {
    var ref = React.findDOMNode(todoItem.refs.remove);
});

suite.add('Set state', function() {
    var priority = '1';
    todoItem.setProps({
        priority: '1',
        task: 'Text',
        priority_text: PRIORITY_MAP[priority]
    });
});

suite.add('Construct', function() {
    var tbody = document.createElement('TBODY');
    var todoItem = React.render(
        React.createElement(Item, null),
        tbody
    );
});
// reactor.js
var suite = new Benchmark.Suite;

var tbody = document.createElement('TBODY');
var todoItem = new widgets.item();
todoItem.construct();
tbody.appendChild(todoItem.component.tree);

suite.add('Get reference', function() {
    var ref = todoItem.component.elements.remove;
});

suite.add('Set state', function() {
    todoItem.update({
        priority: '1',
        task: 'Text'
    });
});

suite.add('Construct', function() {
    var tbody = document.createElement('TBODY');
    var todoItem = new widgets.item();
    todoItem.construct();
    tbody.appendChild(todoItem.component.tree);
});

Výsledky

 reactor.jsReactJSrozdiel
Firefox 40.0.2
Referencia 468 576 053 ops/sec ±0.41% 73 369 577 ops/sec ±0.58% 6.39x rýchlejšie
Nastavenie stavu 481 925 ops/sec ±1.94% 1 746 ops/sec ±7.29 276x rýchlejšie
Vytvorenie inštancie 8 713 ops/sec ±10.67% 726 ops/sec ±3.40% 12x rýchlejšie
Google chrome 44.0.2383.0
Referencia 30 791 589 ops/sec ±0.36% 22 138 994 ops/sec ±0.37% 1.39x rýchlejšie
Nastavenie stavu 265 029 ops/sec ±0.77% 2 364 ops/sec ±6.80% 112x rýchlejšie
Vytvorenie inštancie 6 869 ops/sec ±22.28% 973 ops/sec ±3.69% 7x rýchlejšie
       

Hodnocení: 100 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

mirec avatar 26.9.2015 14:12 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Příloha:

Použité zdrojáky.

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
Bystroushaak avatar 26.9.2015 15:29 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Zajímavé. Měl bys to hodit na github, přidat k tomu dokumentaci v angličtině a hodit odkaz do /r/programming, imho by to i pár lidí používalo.
mirec avatar 26.9.2015 15:41 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS

Zatiaľ mám akurát gist na githube. Proxy modely nad ListModelom majú hnusné API, ktoré by som najradšej prekopal. Vlastne je tam tých škaredých vecí, ktoré by som najradšej od základu prepísal viacej. Po stabilizácii API vytvorím repozitár.

Trochu offtopic .. pri programovaní v JS ma prekvapila jedna vec. Skoro všetko, čo píšem je rýchlejšie vo firefoxe, ale cudzie knižnice sú naopak zvyčajne rýchlejšie v chrome.

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
FoxVK avatar 26.9.2015 21:03 FoxVK | skóre: 1 | blog: Nora linuxáka
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
<offtopic> Je tady nějak přeliškováno... </offtopic>
26.9.2015 22:50 Petr
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Neboj, Bystroushaak je ve skutečnosti krysa :-D
Bystroushaak avatar 27.9.2015 01:08 Bystroushaak | skóre: 35 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Ty jsi můj nový troll, nebo jsi jeden z těch starých?
27.9.2015 18:56 Eliß
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Bystrpusak je ve skutecnosti Firefox, tedy panda
mirec avatar 27.9.2015 19:08 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS

Ale vreckový firefox (fenec) je skutočný vreckový lišiak ;)

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
27.9.2015 00:35 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Hm... na Reactu se mi libi model fungovani:

UI komponenta je funkce, ktera na vstup dostane stav a vrati HTML. Kdyz chci provest nejakou zmenu v UI, na DOM nesaham, ale upravim stav a reknu o tom Reactu. Ten se pak postra o update UI.

Napriklad kdyz chci smazat polozku v todo, pouze se upravi stav (smaze dana polozka v poli), nic vic neni potreba, React upravi UI automaticky tak, ze pregeneruje danou komponentu.

Tohle je podle me obrovsky paradigm shift a hrebik do rakve klasickym frameworkum jako Angular a Ember.

Z toho kodu to vypada, ze Reactor takhle nefunguje...
mirec avatar 27.9.2015 09:19 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
UI komponenta je funkce, ktera na vstup dostane stav a vrati HTML. Kdyz chci provest nejakou zmenu v UI, na DOM nesaham, ale upravim stav a reknu o tom Reactu. Ten se pak postra o update UI.

To je blbosť. Pôvodne som mal napísaný vlastný šablónovací jazyk (pôvodne fork t.js, ale akosi sa na to nabalilo automatické escapovanie, filtre atď), komponenty generujúce html pri zmene stavu ... ale celé som to zahodil. Je jednoduchšíe veľkú časť 10kB knižnice než je to u 500kB knižnice. To, že je to blbosť som už zistil na vlastnej koži keď to síce fungovalo pekne, rýchlo, ale robil som chatovaciu aplikáciu a akosi som potreboval aby sa zoznam užívateľov (select s optionmi) negeneroval vždy znovu keď niekto príde / odíde z chatu. Jednoducho to bolo blbé keď som si vyberal príjemcu a zrazu sa select vymazal a vytvoril na tom istom mieste, zmizol selection a celkovo je to nepríjemné keď počas výberu zmizne menu. Preto react.js potrebuje pri generovaní listu key, ktorý sa následne využíva na diffovanie listu. Ja takéto implicitné magické hodnoty nemám rád, preto to isté u mňa zabezpečuje dvojica ListModel a ListView. ListModel je v podstate obyčajný obalený zoznam ktorý má operáciu vloženia na určené miesto, odstránenia z určitého miesta a presun. Ďalej má 2 signály - inserted a removed (move sa dá rozložiť na tieto 2). ListView sa jednoducho zahákne na ListModel a vytvára / maže komponenty. Komponenty musia byť obalené do widgetu, čo je ľahká vrstva ktorá má ešte na starosti aktualizáciu jednotlivých položiek. Takže ListView nerobí nič iné len reaguje na vloženie / vymazanie, widget sa pri zmene modelu (napr. zmena mena užívateľa) mení sám. Samozrejme inicializovať sa to musí explicitne (funkcia createList), ale zvyšok už je rovnako pohodlný ako s reactom.

Iný príbeh je ak si list neskladám sám, ale chcem ho trebarz aktualizovať z nejakej restovej služby. Na to mám triedu AutoListModel (v podstate je to len proxy na ListModel) a tá funguje takto:

var todoList = new Reactor.AutoListModel();
new Reactor.ListView(
      element,
      todoList,
      widget
);
var zoznam = [];
todoList.setData(zoznam);
zoznam.push({id: 1, ...});
todoList.setData(zoznam);

AutoListModel si už automaticky urobí diff podľa id a do modelu správne pridá / odstráni / presunie / upraví prvky. V podstate robí to isté čo react.js, ale musím ho inicializovať ručne, takže môj kód je o pár riadkov dlhší (< 10%).

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
mirec avatar 27.9.2015 09:46 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS

Ešte aby to nebolo zle pochopené .. nie som spokojný ako je u mňa implementovaný ListView, ListModel ... ale je to prvé riešenie, ktoré ma napadlo pri poslednom projekte. Predchádzajúce riešenia som nezverejňoval, lebo to bolo už dávno implementované lepšie v iných knižniciach. Automatická efektívna zmena DOM podľa modelu ako to mám implementované v súčasnosti prináša výkon porovnateľný s vanilla js. Preto som sa rozhodol zverejniť fragmenty kódu práve teraz. Kým to bude ako-tak učesané tak to ešte zopár projektov potrvá.

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
27.9.2015 12:48 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Nepochopil jsem co presne je blbost. Ze je potreba nekdy pouzivat key? To je, alespon z meho pohledu, zanedbatelny overhead (pro programatora).

Kouzlo Reactu je, ze nemusim pouzivat specialni tridy jako ListView, ListModel nebo AutoListModel. (List byl priklad jednoho widgetu - u ostatnich si musim tyhle tridy vytvaret sam?) Vzdy staci funkce, ktera prevede stav na HTML - neni treba psat kod pro upravu takro vygenerovaneho HTML, o vse se postara React. Strasne to zjednodusi uvazovani o aplikaci. Ano, neni to vzdy stejne rychle jako vanilla JS, ale porad rychlejsi (nekdy radove) nez Angular a Ember.
mirec avatar 27.9.2015 13:08 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Nepochopil jsem co presne je blbost.

Blbosť je generovať html. Môj kód tak nefunguje, react.js tak nefunguje, len sa navonok tak tvári.

Kouzlo Reactu je, ze nemusim pouzivat specialni tridy jako ListView, ListModel nebo AutoListModel.

To je vec ktorá sa mi na reacte nepáči. Namiesto pohodlného ListView-u, ku ktorému mám nejaké API musím v react.js pracovať so surovým array-om. Je to vecou preferencií, keby sa mi páčil prístup react.js nemám dôvod písať niečo iné.

Ano, neni to vzdy stejne rychle jako vanilla JS, ale porad rychlejsi (nekdy radove) nez Angular a Ember.

Angular a Ember sú katastrofa. Obojstranné bindingy nemám rád. Rýchlosť je mizerná. Je to obrovské, monštrózne zložité a ako bonus celý angular prepísali.

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
27.9.2015 13:13 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
react.js tak nefunguje, len sa navonok tak tvári
Ano, tak jsem to myslel, ze React generuje reprezentaci html.
27.9.2015 13:11 Radek Miček | skóre: 23 | blog: radekm_blog
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Vzdy staci funkce, ktera prevede stav na HTML - neni treba psat kod pro upravu takro vygenerovaneho HTML, o vse se postara React.
To funguje, pokud máte malá data. Pokud budete mít milióny položek, tak to nebude zrovna efektivní.
27.9.2015 13:15 backinabag | blog: backinabag
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Vetsinou jde tyhle krajni pripady pomerne jednoduse zoptimalizovat.
27.9.2015 11:50 oryctolagus | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Osobně se mi moc nezamlouvá, když musím psát HTML v JS nebo nějak vytvářet DOM z JS. Problém je, že pak je tvorba UI hrozně rozházená - část je v .html souborech a část je porůznu v různých kouscích kódu někde v JavaScriptu. To mi přijde jako hroznej chaos.

Volil jsem ten přístup, že napíšu vše komplet v HTML, které obsahuje pár drobných značek (ale žádný templaty), které označují přístup z JS.

Minimalistický příklad:

HTML:
<div data-ov="mojeview/view">
	Counter:
	<span data-ov="counter"><strong data-ov=".num">1</strong> <span data-ov=".unit">meter</span></span>
</div>

JS:
var model = oswin.model({
	url: { get: '/some/url' },

	data: {   // Udava strukturu dat modelu a vychozi hodnoty
		counter: {
			num: 3,     
			unit: 'meters'
		}
	},

	members: {
		ctor: function() {
			console.log('This is a constructor');
		},

		// Tady je mozne definovat dalsi vlastni promenne a funkce modelu, etc...
	}
});

var instance = model.make();  // Nova instance modelu
instance.view('mojeview');    // Automaticky si najde v DOM element oznaceny data-ov="mojeview/view" 
                              // a navaze ostatni elementy pod nim podle jejich znacek na svoje data
instance.get();               // Nacte data z get URL
instance.data.counter.units = "potatoes";    // Zmeni data. Zmena se automaticky projevi i v DOM

Model má spoustu šikovných vlastností, jako eventy (pokud uživatel změní třeba hodnotu v textovém poli, změní se automaticky i data v modelu a vyvolá se event, který může být na něco navázaný), přístup k jQuery funkcím (třeba v příkladů výše instance.$('counter.num') vrátí jQuery kolekci, která reprezentuje data.counter.num ve view, čili to je ten <strong> element), controller (opět pomocí podobných značek v HTML - nemusí se nikdy vázat ručně žádné callbacky), "kolekce" - tj. třeba vypysování různých seznamů, které jsou opět definované čistě v HTML, dále knihovna obsahuje minimalistický router a pár utilit. Má to asi 8kb gzipped.
mirec avatar 27.9.2015 12:24 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Osobně se mi moc nezamlouvá, když musím psát HTML v JS nebo nějak vytvářet DOM z JS.

Ani mne ;) ReactJS to má vyriešené dá sa povedať pekne, ale strašne hnusne ;-). V podstate renderovať react šablóny na serveri je možné len pomocou node kvôli tesnej závislosti s javascriptom. Ich šablóny vyzerajú ako zápis DOM, ale nie je to zápis DOM ;-) Nie je možné zapísať class="trieda", namiesto toho sa musí zapísať className="trieda" čo znemožňuje 1:1 mapovanie medzi atribútmi šablóny a DOM atribútmi. Ja si dovolím namiesto šetrenia pár nanosekúnd volať priamo setAttribute. V budúcnosti asi napíšem preprocesor na html s pár značkami na vloženie obsahu z kontextu, ktorý mi vygeneruje príslušný js kód a serverový renderer, ktorý mi umožní renderovať šablóny na serveri v ľubovoľnom jazyku (bez ntnosti mať node na serveri) a odosielať ich ako fallback pre crawlery, alebo browsery s vypnutým js. Keď tak nad tým rozmýšľam možno by nebolo zlé dovoliť použitie ListViewu priamo v šablóne čím by sa zredukoval duplicitný zliepací kód na serveri (fallback rendering) a u klienta.

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
mirec avatar 27.9.2015 13:31 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
přístup k jQuery

Inak pozor na jquery a prístup k data. V prípadoch keď používateľ môže nastaviť data je správanie jQuery dosť nebezpečné. Stačí napríklad v tomto kóde zmeniť použivateľské meno na false a hrabnuť zlým spôsobom na length a hneď všetky zoznamy userov, v ktorých sa vyskytuje užívateľ false prestanú fungovať:

$('<div data-username="false"></div>').data('username').length

Od istej doby sa v rozsiahlejších projektoch vyhýbam jQuery kde sa dá. U malých projektov kde chce klient rýchlo niečo zbúchať je mi to jedno.

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
27.9.2015 13:38 oryctolagus | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
jQuery data() téměř nepoužívám...
27.9.2015 16:08 Ondra
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Volil jsem ten přístup, že napíšu vše komplet v HTML
ja to delam presne obracene, pouzivam SmartClient a vsecho co delam je JS. Jako kdybych psal pred 20 lety ve VisualBasicu
28.9.2015 08:26 gsnak | skóre: 20 | blog: gsnak
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
Jaku funkciu ma ta pajpa v script src?
DOGE: DE7q1kxqvoFek7UGWBWBt47QWJTRBqVNLL
mirec avatar 28.9.2015 08:58 mirec | skóre: 31 | blog: mirecove_dristy | Poprad
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS

Nechcel som tam dávať to isté HTML 2x, takže sa tam má includnúť súbor podľa toho, či sa použije reactor alebo react. Asi som v prvom scripte zabudol bodku ;-)

LinuxOS.sk | USE="-fotak -zbytocnosti -farebne_lcd +vydrz +odolnost +java" emerge telefon
16.1.2017 09:53 Hanna
Rozbalit Rozbalit vše Re: Reactor.js - moja odpoveď na ReactJS
It's a great blog post and read it twice for better knowledge. This is an impressing article which gives us good thoughts and interests to read more article like the same 192.168.1.1 192.168.1.1 192.168.1.1 192.168.1.1

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.