Fork me on GitHub
#reitit
<
2024-02-26
>
Shahwarcoder08:02:04

Hello @ikitommi I am using Reitit frontend for my routing but I am seeing the build size goes very high when including reitit coercion which brings in the clojure analyzer.cljc file which is almost 200Kb size. Is there a way to minimise this or use Reitit without the coercion itself?

dumrat08:02:27

You can opt out of coercion

Shahwarcoder08:02:50

so if I opt out then I will also loose parsing of prams or body from routes, isn't it?

dumrat08:02:54

You should be able to hand-roll your own coercer that makes use of the same route data if that's a concernt

juhoteperi08:02:28

Not sure what is the dependency source for clojure analyzer.cljc

Shahwarcoder08:02:30

(def router
  (rf/router routes {:data {:coercion rcs/coercion}}))
@U061V0GG2 not sure, this line adds the analyzer to my build somehow. I removed the coercion and then analyzer got removed

Shahwarcoder08:02:57

@U061V0GG2 Here is the screenshot of my report file

juhoteperi09:02:36

aha you are using spec instead of malli

Shahwarcoder09:02:16

so what should we use then?

juhoteperi09:02:15

Depends on what you want. Due to Spec implementation spec-tools needs to use Cljs analyzer and there is probably no way around that.

Shahwarcoder09:02:26

I don't use spec anywhere except while defining the router which I showed above

juhoteperi09:02:08

Malli doesn't need the cljs analyzer but the Reitit coercion implementation isn't very optimized for frontend use, so I'm not sure if Malli coercion implementation is much lighter than Spec.

juhoteperi09:02:38

I'd say Malli is the preferred one, but examples are probably from time before Malli. And it depends a lot if you are already using one of the "schema libs" elsewhere.

Shahwarcoder09:02:19

So are you suggesting to use router without any coercion? how much will that affect my code. I haven't yet reached to very complex route definitions with query params and stuff, but will use then in later stage.

Shahwarcoder09:02:52

> I'd say Malli is the preferred one, but examples are probably from time before Malli. And it depends a lot if you are already using one of the "schema libs" elsewhere. I don't think I am using schema libs too.

juhoteperi09:02:03

I use Reitit frontend with Malli coercion

juhoteperi09:02:20

Query parameters could be inconvenient without coercion usually

Shahwarcoder09:02:53

ok. let me try with malli

juhoteperi09:02:45

I can add a new example quickly

Shahwarcoder09:02:24

sure, that would be helpful, but here is the gist of what I have done

Shahwarcoder09:02:21

...(:require [reitit.coercion.malli :as rcm])...

(def routes [....])

(def router
	(rf/router routes {:data {:coercion rcm/coercion}
										 ;:controllers [{:start (js/console.log "start" "root-controller")
											;							:stop (js/console.log "stop" "root controller")}]
										 }))

(rfe/start!
							 router/router
							 (fn [matched-route]
								 ;(swap! router/routes-state (fn [old-match] (if matched-route (assoc matched-route :controllers (rfc/apply-controllers (:controllers old-match) matched-route)))))
								 (when matched-route
									 (set-active-name! (-> matched-route :data :name))
									 (set-active-view! (-> matched-route :data :view))))
							 ;; set thi to "false" to enable HistoryAPI
							 {:use-fragment false})

juhoteperi09:02:07

Just to show the basic :parameters format for FE use

Shahwarcoder09:02:26

Its still huge though, almost 167Kb

Shahwarcoder09:02:26

How can I remove swagger and other stuff not needed from here?

Shahwarcoder09:02:32

@U061V0GG2 Can you share me an implementation to use linear-router? I guess that would be the most optimised one.

juhoteperi09:02:20

I don't think I have that anywhere in use

juhoteperi09:02:14

But IIRC you could just call Reitit/linear-router instead of reitit/router. The reitit.frontend/router is just merging one option into the call, so you would need to add that yourself: https://github.com/metosin/reitit/blob/master/modules/reitit-frontend/src/reitit/frontend.cljs#L89-L95

juhoteperi09:02:57

so (rf/router routes {options}) -> (r/router-linear routes {:compile ... options})

juhoteperi09:02:49

But also the optimization isn't always working very predictably, there are cases when not calling a function doesn't remove all the code that function uses (like -get-apidocs and swagger code)

Shahwarcoder09:02:03

Ok, let me try to implement this and see if I face any issue.

juhoteperi09:02:40

We haven't had cases where the JS artifact size would have been super important, so optimizing Reitit-frontend size hasn't been a priority. If you are building a app for intranet like use, and you have just a few users it isn't super important. Or if you are using large JS libs.

Shahwarcoder09:02:36

I am using it for my internal users and it won't harm us to use large libraries but, I would very much want to use reitit on production apps too. I have spent quite deal of my time to setup multi level nesting with reitit for pages and subpages and would want to use this as a replacement for react router.

Shahwarcoder09:02:14

I think there should be a plan to improve reitit frontend to minimise the bundle size

Shahwarcoder09:02:02

{:name :routes.fms.events
									:comp-level 2
									:view ($ events/Events)
									:parent [:routes.fms]
									}
If you see my routes, have added comp-level for which level a components needs to be rendered and parent to show under which parent the component can be rendered. Removing all this will just be waste of time.

lwhorton15:03:25

i was looking to similarly optimize my bundle size. after quite a bit of work i realized that it's kind of a fool's errand for a lot of applications. you cant depend on basically any javascript library; most of them are bloated with transient deps. you have to find ways to optimize your css with tailwinds-like stripping of unused classes, or some other strategy. you have to be particular about which parts of cljs core and other cljs you end up using. a lot of code has to be annotated for proper tree-shaking. then, after working really hard to cut a few kbs at every opportunity... one of the first xhr fetches to a backend service returns 500kb. all those gains in payload size and first render time are immediately lost. :x i think for most apps i've ever written it's a much better strategy to make my caching as efficient as possible, which is quite simple with something like shadowcljs and a static assets server