This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-01-19
Channels
- # beginners (34)
- # boot (111)
- # cider (37)
- # clara (57)
- # cljsjs (1)
- # cljsrn (22)
- # clojure (156)
- # clojure-austin (2)
- # clojure-mke (7)
- # clojure-russia (9)
- # clojure-spec (221)
- # clojure-uk (47)
- # clojurescript (42)
- # code-reviews (4)
- # community-development (9)
- # core-async (3)
- # cursive (50)
- # datomic (81)
- # emacs (12)
- # events (5)
- # hoplon (1)
- # jobs (2)
- # lein-figwheel (4)
- # leiningen (1)
- # luminus (3)
- # mount (2)
- # off-topic (1)
- # om (94)
- # om-next (3)
- # onyx (33)
- # re-frame (23)
- # reagent (41)
- # remote-jobs (9)
- # rum (30)
- # slack-help (2)
- # specter (1)
- # untangled (20)
- # yada (17)
@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
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.
so, I'm guessing simplifying my app state is about all I'll be able to do in order to fix it
as a general note, though, in this app path-meta is always more that 50% of the time spent in the parser
frankly I'm not sure how that's possible on V8, unless it is billing the GC CPU time to the allocations
@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
so the fix is?
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
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
@anmonteiro would it be possible to calculate path data during render instead of as a post-step to db->tree
?
@tony.kay db->tree
could be optimized...
I think we never got around to optimizing either tree->db
or db->tree
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?
@hlolli isn't this what om/computed
is for?
Yes I would have thought so, but then is seems as if computed is mostly for passing down functions?
I use it for anything that isn't in the query. If the component has no query, I just use props
does om/computed merge the passing properties with remote properties and does it "survive" a set-query call?
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"
what are the problems you're seeing?
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).
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.
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.
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.
And yes, I'm starting to realize that Im getting the title of the ranter of this group 馃檪
for a calculation of app-state data, i think you just do the calculation in render...
maybe a specific example would help
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
yes, wanted to ask around before making an example, if the theory behind what I would like to achieve is flawed.
trouble is, im having trouble understanding the theory without an example
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
most of the time it comes down to how i designed the state/component hierarchy
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.
exaacly, the frequency of telling oneself "how stupid could I have been" is superexceeded in om.next development.
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 ?
i'd expect them to persist but can't say with certainty, thats why there are separate mechanisms for both...
@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
That's what I would have expected, good to confirm 馃憤
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
i think its simpler than that, (om/props) and (om/get-computed) are kept separate, when it re-renders it only updates props
it will only update computed props if the parent is re-rendered
react obviously has no concept of computed vs regular props, they are all just props underneath
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?
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.
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
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
That's my understanding, anyway
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.
Anyone know what (assert (nil? c) (str "Query violation, " x , " reuses " c " query"))
means?
i think i encountered that problem when I forgot to nest a sub-component query using its own key
yeah, im not nesting a sub-component query using its own key 馃檪
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)
yep, thats exactly what i did
it means i have to write a parser function for :b
doesn't it?
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.
and I thought also that the app-state must be constructed as a tree to mirror the rendering and query.
and I have write more code so the parser can participate in the overall query tree structure
basically i have a sidebar and a main view, with controls in the sidebar
and i want to update the main view's component query from the sidebar, without rendering the sidebar each time the main view updates
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
if your sidebar is a kinda similar to sidebar navigation in classic web-pages, maybe routing is a good solution
i suppose its similar in some respects
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/
yeah, was just reading that actually 馃檪
need to go away and think about it a bit
i feel like subquery might be of some use
Is the best way to do devcards + Om Next still https://github.com/anmonteiro/devcards-om-next ?
@peeja should be, let me know if anything doesn't work as expectd
you can also just use normal devcards like the ones in the Om repo
my repo is just sugar over them
oh, plus reloadable-safe stuff