cljsrn

https://github.com/drapanjanas/re-natal | https://github.com/drapanjanas/re-natal/wiki/FAQ | https://github.com/condense/mercury-app/wiki | https://github.com/seantempesta/expo-cljs-template/ https://www.npmjs.com/package/create-expo-cljs-app
Eric Ihli 2020-01-21T04:39:35.028200Z

Requiring the json file is about a 10x speedup over using a macro to slurp an edn file from the resources directory and then parse the edn into a map.

Eric Ihli 2020-01-21T04:41:53.030100Z

Still unacceptably slow, and I think the slowness is causing Android to think the app is crashing? It only locks up for about a second when I toggle it to/from the background. The first time I send it to the background, the phone freezes for a second and then continues. The second time I send it to the background, I get an android popup saying the app keeps stopping and asks if I want to close the app.

danielneal 2020-01-21T06:08:43.030700Z

What are you doing on app state change?

danielneal 2020-01-21T06:10:11.031400Z

Could it be your websocket code hanging?

vikeri 2020-01-21T09:56:19.032100Z

@ericihli btw, we’re using transit to encode the data. Vastly faster than reading the straight edn data.

Eric Ihli 2020-01-21T13:02:46.036Z

I'm trying transit now. I'm trying to avoid adding filesystem reads and instead getting all the data I need from a single JS bundle. So instead of having a file, data.transit with the raw transit, I have a file data.js with the content const data = "<escaped transit>"; export default data;. Then I planned on doing a (def data (js/require "path-to-data-module"))

vikeri 2020-01-21T13:03:25.036600Z

Sounds reasonable

Eric Ihli 2020-01-21T13:04:11.037300Z

Now I've hit a totally new problem that might be unrelated. Copy/pasting from beginners: Am I misunderstanding something about module resolution?

(defonce json-data (js/require "../../assets/number-to-word-tree.json"))
(defonce number-to-word-tree (js/require "../../assets/number-to-word-tree-module")) ;; This file has a .js extension. I've tried including the extension. Same result.
The first line works. The second line errors with:
Error: Unable to resolve module `../../assets/number-to-word-tree-module` from `app/index.js`:

None of these files exist:
  * ../assets/number-to-word-tree-module(.native|.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)
  * ../assets/number-to-word-tree-module/index(.native|.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx)
The first file is just plain json. The second is a module version of it.
const foo = <stringified-json>;
export default foo;
I'm using shadow-cljs and react native. Both files exist and have the same owner/permissions. I've cleared every cache and reset every process I can think to try. (edited)

thheller 2020-01-21T13:49:03.039100Z

@ericihli FWIW this is all metro/react-native. shadow-cljs isn't involved in resolving require calls. as a guess maybe react-native doesn't allow js files in assets? dunno if it has special rules for folders

💯 1
Eric Ihli 2020-01-21T14:05:36.048200Z

Thanks. I'll focus my attention there. I'm trying to break things down to chunks that I can verify. There's so many layers throughout this dev process, shadow, cljs, metro, babel, RN, nrepl, etc... and even just my plain-old javascript knowledge is out-of-date. The latest thing I've tried to simplify and verify is just my JS syntax and babel. test.js

const foo = "bar";
export default foo;
$ babel test.js <- Exit code 0. Success. big-file.js I'll paste the first and last 100 characters since it's too large.
➜  react-native git:(master) ✗ head -c 100 ../assets/number-to-word-tree.js
const numberToWordTree = "[\"^ \",\"~i0\",[\"^ \",\"~i0\",[\"^ \",\"~i0\",[\"^ \",\"~:terminals\",[[%
➜  react-native git:(master) ✗ tail -c 100 ../assets/number-to-word-tree.js
W\",\"V\",\"AY\",\"V\",\"IH\",\"P\",\"ER\",\"AH\",\"S\"]]]]]]]]]";
export default numberToWordTree;
$ babel big-file.js <- Exit code 1. Fail. No message. As far as I can tell the two files are syntactically equivalent.

thheller 2020-01-21T14:11:06.048700Z

maybe try eslint? maybe that provides some kind of error message?

thheller 2020-01-21T14:11:34.049500Z

does react-native not have support for loading files lazily? bundling a huge file into the startup process doesn't seem like a good idea?

Eric Ihli 2020-01-21T14:13:47.050300Z

Ah. Damn.

➜  react-native git:(master) ✗ eslint ../assets/number-to-word-tree.js

/home/eihli/code/ezmonic-mobile/assets/number-to-word-tree.js
  1:1268246  error  Parsing error: Expecting Unicode escape sequence \uXXXX

✖ 1 problem (1 error, 0 warnings)

Eric Ihli 2020-01-21T14:17:30.053300Z

There are ways to lazily load files but it would be strictly a UX thing in this case, like how Google Sheets display an uninteractable image of a spreadsheet and then lazily loads the interactivity. Makes it feel snappier but it's just as functional as if they showed a loading spinner.

Eric Ihli 2020-01-21T14:18:11.054Z

Lazily would be better, for sure. I thought this would be simpler.

Eric Ihli 2020-01-21T15:12:22.054200Z

This was the case. Moving the js file to the directory that everything compiles to (and addressing the unicode issue) was the fix.

Eric Ihli 2020-01-21T15:14:31.055500Z

Thank you everyone for the help. 10 seconds to parse 6MB EDN. 1 second to parse 6MB json. ~300ms to parse 8MB transit.

👍 1
😀 2
danielneal 2020-01-21T15:15:39.055800Z

wow that’s interesting

2020-01-21T15:19:11.056Z

indeed!

Eric Ihli 2020-01-21T16:00:12.059200Z

Might need to go the lazy read from FS route anyways. Still takes about half a second to launch the app and toggle it to/from the background. Also, it works fine the first time I open the app and send it to the background. But the second time, I get an OS popup that says "Eric's App keeps stopping" and gives me buttons for app info or close app. Logcat around that time looks like this:

01-21 09:27:26.264  4206  4229 D SoLoader: libreactnativeblob.so not found on /data/data/com.ezmonic/lib-main
01-21 09:27:26.264  4206  4229 D SoLoader: libreactnativeblob.so found on /data/app/com.ezmonic-Qr6sh3jyh-i-JC1fXszKWw==/lib/arm64
01-21 09:27:28.441  3218  3376 I clp-JNI : CLP add process info start. (channel) cfbead2 NavigationBar (server) (pkg) AppWindowToken{4dfcc04 token=Token{feed017 ActivityRecord{153dc96 u0 com.ezmonic/.MainActivity t8722}}} (action) 0
01-21 09:27:28.558  3218  3376 I clp-JNI : CLP add process info start. (channel) cfbead2 NavigationBar (server) (pkg) AppWindowToken{4dfcc04 token=Token{feed017 ActivityRecord{153dc96 u0 com.ezmonic/.MainActivity t8722}}} (action) 1
01-21 09:27:28.601  4206  4230 E AndroidRuntime: Process: com.ezmonic, PID: 4206
01-21 09:27:28.626  3218  9647 W ActivityManager: crash : com.ezmonic,0
01-21 09:27:28.627  3218  9647 W ActivityManager:   Force finishing activity com.ezmonic/.MainActivity
01-21 09:27:28.633  3218  3256 I ActivityManager: Showing crash dialog for package com.ezmonic u0
01-21 09:27:28.650  1733  4276 D AppErrorNotification: errorType : 24, process : com.ezmonic , uid : 0
01-21 09:27:28.654  3218  3721 V WindowManager: Relayout Window{6ed731b u0 com.ezmonic/com.ezmonic.MainActivity}: viewVisibility=4 req=1080x2220 {(0,0)(fillxfill) sim={adjust=resize forwardNavigation} ty=BASE_APPLICATION wanim=0x10302fe
01-21 09:27:28.659  3218 12832 I ActivityManager: Activity reported stop, but no longer stopping: ActivityRecord{153dc96 u0 com.ezmonic/.MainActivity t8722 f}
I think the relevant message is "Activity reported stop, but no longer stopping". But is that related to the serialization of lots of data when the app goes to background? I'm assuming.

dotemacs 2020-01-21T16:16:35.062Z

@ericihli Maybe at this point you can try to dump the thread and dump the heap and analyse it?

$ adb shell ps | grep com.ezmonic
$ adb shell run-as com.ezmonic kill -3 &lt;pid you got from the line above&gt;
$ adb pull &lt;file of the thread dump&gt;
or for the heap dump
$ adb shell am dumpheap &lt;pid from the above&gt; &lt;heap dump file path&gt;
$ adb pull &lt;heap dump file path&gt;

dotemacs 2020-01-21T16:19:23.064200Z

Also, when you open the app, do you let it “settle”, as in wait a bit or do you put it in the background and then try to open it straight away? I’m asking only because your app could just start going into the background and then you’re trying to bring it to foreground to use it, without it actually stopping in the first place. (Obviously, this is just a theory.)

Eric Ihli 2020-01-21T16:22:28.065700Z

Pretty sure it happens regardless of timing. I'll check on next install. First I've heard of the heap dump debugging stuff. Thanks. Exploring that now.

alidlorenzo 2020-01-21T19:13:50.067600Z

what offline database solution are ppl using for react native? anyone have success w watermelondb or realm

vikeri 2020-01-21T19:15:31.068700Z

@alidcastano We used to use Realm but worked very poorly with Chrome devtools so now we’re on SQLite. Not very sexy but very reliable.

alidlorenzo 2020-01-21T19:16:31.069400Z

@vikeri watermelondb is built on top of sqlite, did you consider it at all?

vikeri 2020-01-21T19:18:35.070600Z

Nope, I don’t think it was released when we switched. Looks interesting if you need observable data.

alidlorenzo 2020-01-21T19:19:09.071900Z

yea I'm considering it, just not sure how to use decorators with cljs 😅

vikeri 2020-01-21T19:19:37.072600Z

My hunch says that if you don’t need the fancy features, go with vanilla SQLite.

alidlorenzo 2020-01-21T19:22:14.073900Z

yea it just has lots of optimizations, such as fast startup time, lazy data loading, etc. plus built in sync primitives but the benefit of sqlite, aside from one less dependency, is I don't have to eject from expo

vikeri 2020-01-21T19:23:00.074600Z

Yeah that’s a pretty big one

vikeri 2020-01-21T19:23:45.075600Z

I’d try SQLite and if it doesn’t cut it then eject and try watermelon

👍 1
alidlorenzo 2020-01-21T20:55:50.075900Z

what do you think of datascript+async storage 😬😎

joshmiller 2020-01-21T22:33:16.076100Z

My app uses < 100 kb for storage, and I just persist my re-frame app-db to AsyncStorage as edn.