Fork me on GitHub
#cljsrn
<
2017-01-16
>
dvcrn06:01:42

@paulspencerwilliams I never used AsyncStorage before but I would use periodic saves. Either automatically through setInterval or use a timeout on app state change

dvcrn06:01:23

With Realm, I write to Realm through a timeout whenever state changes since my app doesn't have that many updates. With a lot of changes it could make sense to periodically update to make sure nothing gets lost

vikeri07:01:30

@paulspencerwilliams We write to AsyncStorage on each update of the db (serializing the db using transit, even though it is not recommended for storage, it is way faster than pr-str). One could technically write on app pause or close but we’re also a little afraid that those callbacks may not always be called. You’d still have to read directly from the in-memory app-db because since the AsyncStorage is slower than accessing memory and does not have the reactiveness required for re-frame. How fast is it to write/read to realm @dvcrn? And do you still need to keep the app-db atom?

dvcrn07:01:47

I am not sure to be honest. I am not using it directly on read and still have my state atom. I'm having a lazy-load approach where I fetch the data into the state atom if it isn't there yet on read

dvcrn07:01:14

I wasn't sure which storage solution is the best and wanted the option to swap it out if needed

dvcrn07:01:43

> Fast > > Realm’s ease of use doesn’t come at a performance cost. Because of its memory mapping, lazy loading, and custom storage engine, Realm is usually faster than SQLite or AsyncStorage despite offering a rich object-based API. Although we always recommend everyone test their own use-cases, we usually see huge speedups when porting code to Realm. See benchmark results below.

dvcrn07:01:31

I'm too new to iOS to know whether it's a good idea to directly read from sqlite / asyncstorage 😛

paulspencerwilliams09:01:46

So it would appear that using the state atom as primary, with intermittent writes to AsyncStorage and initial load seem to be the best generic solution. Cheers guys.

Niclas16:01:00

(defn my-switch []
  (let [value (r/atom false)]
    (fn []
      [switch {:value           @value
               :on-value-change #(reset! value %)}])))
Whenever I create a switch element like this on Android there’s a short flicker before the value of the switch is updated. Does anybody know why this might be so unresponsive?

Niclas16:01:47

(defn my-time-picker []
  (let [time (r/atom (date-time "2016-06-01 17:00"))]
    (fn []
      [date-picker-ios {:date           @time
                        :on-date-change #(reset! time %)}])))
The same kind of flickering can be experienced with ex. a date picker. I suspect that it has something to do with the animation of toggling back to the previous state of the component before the value is updated, but what would be the correct way of structuring the state of this type of stateful component?

raspasov19:01:21

it’s actually not necessary to convert the ClojureScript data structure to JavaScript in order to pass it to the dataSource

raspasov19:01:57

I used to think it is, but actually the React Native ListView is designed to be data structure agnostic

pesterhazy19:01:43

@raspasov I found that out as well

pesterhazy19:01:12

It's just a pointer as far the data source is concerned

raspasov19:01:14

I do something like

raspasov19:01:26

(defn list-view-data-source [m] (ReactNative.ListView.DataSource. (cljs.core/clj->js (merge {:rowHasChanged (fn [x y] (not= x y)) :getRowData (fn [data-blob section-id idx] (nth (.-s1 data-blob) idx nil))} m))))

raspasov19:01:20

basically provide a :getRowData function that is ClojureScript-specific and get data from the vector (aka data blob) via (nth ...

raspasov19:01:07

not converting Cljs -> js -> Cljs really helps with performance (and memory usage!) I found

raspasov19:01:39

esp. on older devices like iPhone 6 and below is very noticeable difference

raspasov19:01:50

on newer ones you’d barely tell

misha19:01:50

older devices like iPhone 6 kappa

ejelome19:01:19

but I really don't notice it in my iPhone 8 troll

misha19:01:25

are you developing https://en.wikipedia.org/wiki/I_Am_Rich app, or something, @raspasov ? or are you just being realistic about your app's release date troll

raspasov20:01:04

our app is already live 🙂

raspasov20:01:52

it has been live for like almost 6 months now (all React Native + ClojureScript)

ejelome20:01:16

lmao, funny link XD

raspasov20:01:41

we’re only iOS currently, we advertise on Facebook and we do no specific device targeting, about ~20% of people are on iPhone 6; majority of users are on iPhone 6s generation

raspasov20:01:01

or newer...

raspasov20:01:17

not saying that those 20% are not important, to the contrary

raspasov20:01:23

that’s why I mentioned it 🙂

misha20:01:51

for faster clj->js rows conversion in DataSource, I just convert list ids, and later fetch actual row data from edn hash-map by those ids.

misha20:01:46

(does not fit every use case, obviously, but is good enough for many)

raspasov20:01:46

yes, same; only diff is I use a vector, but actually the hash-map can be even better now that you’re mentioning it!

misha20:01:35

at the very least, it saves the pain of roundtrip conversion of namespaced keywords

raspasov20:01:48

for simplifying a separate (get-in …) lookups or (update-in …) opearations

raspasov20:01:26

(defn clone-with-rows-and-gen-indices [a-list-view-data-source data-v] (.cloneWithRows a-list-view-data-source data-v (clj->js (into [] (range (count data-v))))))

raspasov20:01:36

this is how my cloneWithRows looks like

raspasov20:01:49

the only cljs->js conv. I do is to generate the indices

raspasov20:01:00

by which to lookup

ejelome20:01:14

I understand the good intent guys, but see, I only started cljs just this month, hahaha, so I can't comprehend that optimization fu

raspasov20:01:21

data-v gets passed in unchanged to the ListView

ejelome20:01:31

my only goal was to have 1:1 react native sample to re-natal

ejelome20:01:41

so I can easily digest what's happening XD

raspasov20:01:00

essentially the problem is that anytime you do (clj->js …) conversion or (js->clj …)

ejelome20:01:00

I even stripped re-frame so I can focus on cljs and reagent

raspasov20:01:03

it’s slow...

raspasov20:01:14

that’s all

ejelome20:01:46

but the good thing is that, I'm realizing that conversion is not always mandatory, like the example you show

raspasov20:01:03

yep 🙂 just know it’s there, if you need it later

raspasov20:01:18

I spent months without realizing you can do this, so that’s why I mentioned it

raspasov20:01:29

and I’ve been doing Clojure for years now

ejelome20:01:36

hahaha, that saved me months then, thanks 😛

ejelome20:01:07

but in any case thanks @raspasov, good thing I don't have an iPhone 6/s troll

raspasov20:01:39

@ejelome are you trying to do iOS or Android first?

ejelome20:01:56

I don't have a mac, so android is the only choice 😄