Fork me on GitHub
#om
<
2017-01-19
>
tony.kay00:01:27

@anmonteiro So, GC isn't necessarily the problem. It's as I load data and the app state gets bigger. GC is going on, but it isn't the source of delays

tony.kay00:01:44

I'm getting 5s+ animation frame times

tony.kay00:01:45

about 90% of that is 2 calls to ui->props, and ui->props spends about 2/3 of its time in path-meta. But, the parser itself (db->tree) is about 600ms of that overall.

tony.kay00:01:01

so, I'm guessing simplifying my app state is about all I'll be able to do in order to fix it

tony.kay00:01:35

as a general note, though, in this app path-meta is always more that 50% of the time spent in the parser

tony.kay00:01:23

in the worst case, it was 75% of the time spent in the parser

tony.kay00:01:45

with an overall CPU time of nearly 2s

tony.kay00:01:22

frankly I'm not sure how that's possible on V8, unless it is billing the GC CPU time to the allocations

tony.kay00:01:15

actually, it doesn't look like it did a GC until the end of the whole mess

souenzzo00:01:26

Hey, there is some tutorial with om.next + some fetch library?

tony.kay00:01:06

Basically Om next with all the wiring pre-plumbed

tony.kay00:01:32

includes tutorials, getting started videos, cookbook, etc

tony.kay00:01:59

@anmonteiro FYI: I figured it out. The app was querying for a ton of small things, and leaving that in the UI query for every frame

tony.kay00:01:18

so, as more of the things got loaded...slow....slower....intolerable

anmonteiro00:01:33

so the fix is?

tony.kay00:01:51

the fix is not doing that to app state/query 馃檪

tony.kay00:01:10

they were pulling in 100's of items, and not paginating them or anything

tony.kay00:01:24

and each item had quite a bit of depth to it

tony.kay00:01:34

so the db->tree/path-meta overhead was huge

tony.kay00:01:09

so a combo of fixes: pre-roll the detail into blobs that don't need a query, paginate, and use unions to keep stuff that isn't in the view out of the query

tony.kay00:01:01

It is a little disappointing that db->tree was as slow as it was, though. I would have expected to be able to get away with 100's of items like that

tony.kay00:01:17

@anmonteiro would it be possible to calculate path data during render instead of as a post-step to db->tree?

tony.kay00:01:02

meh, not really

tony.kay00:01:12

since we're making components that are supposed to be plug-in compatible with React

tony.kay00:01:30

unless we keep some stateful mutating thing on the side during render

anmonteiro05:01:35

@tony.kay db->tree could be optimized...

anmonteiro05:01:51

I think we never got around to optimizing either tree->db or db->tree

hlolli10:01:53

What are some of the experiences of other om.next users when it comes to passing down local component data down to another one that is not stored in global state. (def a (om/factory A)) (defui B object (render [this] (a {:some "data"})) And especially when the component (this example here A) is also doing remote reads, set-queries calls etc. Would this be seen as bad practice, is there an bug in om, if not, should om give an error immediately that this is not allowed instead of passing the inter-component values as unstable property?

danielstockton10:01:15

@hlolli isn't this what om/computed is for?

hlolli10:01:17

Yes I would have thought so, but then is seems as if computed is mostly for passing down functions?

danielstockton10:01:04

I use it for anything that isn't in the query. If the component has no query, I just use props

hlolli10:01:50

does om/computed merge the passing properties with remote properties and does it "survive" a set-query call?

hlolli10:01:23

anyway, if a component is receiving properties that is not coming from a static query or computed props, would it make sense to give the user a strong warning that "s/he's going to have a bad time"

danielstockton10:01:01

what are the problems you're seeing?

hlolli11:01:44

typical cycle, inital render: all local pased props and static reads are available to child component. I update the local state of the child then all local passed props are lost but reads stay the same. Then after that I may lose passed propes that are passed as joined link with a change in datastructure (this is still often preventable but very annoying).

hlolli11:01:55

I spent 12 hours yesterday believing this was due to unstable indexing from root to childs, like a lost react-key that the reconciler didn't know if that uniqe component instance has everything it needs. So I was chaising my tail to insanity, ending up doubting if local state and local data made any sense at all since it's almost immobile. With my ugly hacks I get around it, by reading the props only when it has values and "cache" it into the local state, but by doing those monkey patches Im making my life hard if I need to change anything in the spec.

danielstockton11:01:59

Perhaps you're relying on local state too much. Afaik, this is best used for 'transitional' states (animations etc...) and everything else should be in your app-state as a best practice.

hlolli12:01:12

local-state, some calculation of app-state data, don't know millions of reasons why one wouldn't want to overdo mutation, not to mention extra development time and lack of flow. Can't see why passing data from component to component can't be as easy as passing data from component to function.

hlolli12:01:42

And yes, I'm starting to realize that Im getting the title of the ranter of this group 馃檪

danielstockton12:01:20

for a calculation of app-state data, i think you just do the calculation in render...

hlolli12:01:33

if everything was in render I would only need one component.

hlolli12:01:41

(and functions)

danielstockton12:01:52

maybe a specific example would help

danielstockton12:01:24

it is quite frustrating when you have to forge your own best practices, i guess its to be expected on such a niche and modern framework

hlolli12:01:44

yes, wanted to ask around before making an example, if the theory behind what I would like to achieve is flawed.

danielstockton12:01:21

trouble is, im having trouble understanding the theory without an example

danielstockton12:01:42

the only problems i've come across of a similar nature is getting the right components to re-render when the right data changes, and not re-rendering too much

danielstockton12:01:52

most of the time it comes down to how i designed the state/component hierarchy

hlolli12:01:59

Yes, there's some need to add more to FAQ and pitfalls in the documentation. Because om.next assumes some philosophy that makes solving a bug become more than a straightforward problem.

hlolli12:01:27

exaacly, the frequency of telling oneself "how stupid could I have been" is superexceeded in om.next development.

mavbozo12:01:44

so, if A passes om/computed to its B child and B changes its local state, I assume om will trigger reads and render for B component. but will the om/computed props passed from A persists when re-rendering B ?

danielstockton12:01:42

i'd expect them to persist but can't say with certainty, thats why there are separate mechanisms for both...

hlolli12:01:47

@mavbozo almost the same question, where I would answer "maybe".

mavbozo12:01:50

@danielstockton @hlolli I made a small example above based on my previous question. After component B mounted, I set the local state of B. It turns out om.next triggers B query and re-render B and somehow, passed om/computed from A still exists when re-rendering B

danielstockton12:01:24

That's what I would have expected, good to confirm 馃憤

mavbozo13:01:24

so, I assume after B's local-state set, om.next triggers re-query. but instead of only querying the [:name] which is B's query, om.next finds where B's query located in the overall query tree structure and reads from to Root query in this case :b. But I could not understand although A's render is not called during re-rendering--only render B called, the om/computed for B still persists although from what I see in the code, om/computed for B is passed during A's render

danielstockton13:01:26

i think its simpler than that, (om/props) and (om/get-computed) are kept separate, when it re-renders it only updates props

danielstockton13:01:49

it will only update computed props if the parent is re-rendered

danielstockton13:01:12

react obviously has no concept of computed vs regular props, they are all just props underneath

hlolli13:01:17

ok nice that :b/computed stays there, so "my name is B" and :b/computed 1 are in the properties? Is :b/computed then only available via om/get-computed when passed in with om/computed?

hlolli13:01:09

Is there ever a reason to give a component like b anything else than the return of om/computed, if not, why isn't om/computed called by default when passing any sort of data into components.

hlolli13:01:49

just curous when it makes sense to pass any arbitrary data.

danielstockton13:01:34

Yes, its only available with get-computed. It makes sense to pass data as computed exactly in the case above ^^ If you passed it in props, it would be annihilated when props are updated

danielstockton13:01:34

In general, if it comes from app-state, its best to make it a query, unless the same data (or a pre-computed version) is required by a parent component that needs re-rendering anyway

danielstockton13:01:57

That's my understanding, anyway

hlolli13:01:48

yes, I use passing of local data a lot to control classnames and visual margins, not for any important data. But in ui development world, there can be the most minor visual details costing often larges chain reactions in many comonents.

danielstockton14:01:15

Anyone know what (assert (nil? c) (str "Query violation, " x , " reuses " c " query")) means?

mavbozo14:01:24

i think i encountered that problem when I forgot to nest a sub-component query using its own key

danielstockton14:01:33

yeah, im not nesting a sub-component query using its own key 馃檪

mavbozo14:01:22

for example, A which is a root does not need any data but its child say B needs data. A's query should be like this [{:b (om/get-query B)}]. But, I might think since A query is just the same as B, why not save keystroke and remove the :b so A's query become (into [] (om/get-query B)

mavbozo14:01:53

and I get the error.

danielstockton14:01:00

yep, thats exactly what i did

danielstockton14:01:15

it means i have to write a parser function for :b doesn't it?

mavbozo14:01:33

yeah, i was confused. I thought only the rendering components that need to be structured as a tree. the query structure also must be tree-like.

mavbozo14:01:23

and I thought also that the app-state must be constructed as a tree to mirror the rendering and query.

mavbozo14:01:17

and I have write more code so the parser can participate in the overall query tree structure

danielstockton14:01:08

basically i have a sidebar and a main view, with controls in the sidebar

danielstockton14:01:24

and i want to update the main view's component query from the sidebar, without rendering the sidebar each time the main view updates

danielstockton14:01:02

so i wanted to make the main view a child of the sidebar, or a sibling, but not sure how to set-query on it

mavbozo14:01:00

if your sidebar is a kinda similar to sidebar navigation in classic web-pages, maybe routing is a good solution

danielstockton14:01:59

i suppose its similar in some respects

mavbozo14:01:41

maybe if it is similar to the demo in this article, the routing solutions are appropriate for your case https://anmonteiro.com/2016/02/routing-in-om-next-a-catalog-of-approaches/

danielstockton14:01:12

yeah, was just reading that actually 馃檪

danielstockton14:01:36

need to go away and think about it a bit

danielstockton15:01:25

i feel like subquery might be of some use

peeja21:01:08

Is the best way to do devcards + Om Next still https://github.com/anmonteiro/devcards-om-next ?

anmonteiro21:01:32

@peeja should be, let me know if anything doesn't work as expectd

anmonteiro21:01:18

you can also just use normal devcards like the ones in the Om repo

anmonteiro21:01:34

my repo is just sugar over them

anmonteiro21:01:50

oh, plus reloadable-safe stuff