building kysely makes the package size very large
hi. i'd be more than happy to figure this out because i like kysely a lot more than drizzle. the thing was that the package size was so much larger with drizzle. i made a repro here. when running
bun build --minify --outfile
, i get kysely to be 340.40kB whilst drizzle is 55.35kB, meanwhile the functional code besides the database is identical40 Replies
the demo is essentially just a post and comments api with very basic functionality
Hey 👋
Which bun version?
1.0.25
same thing happens on 1.1.2 though
I see stuff in the output file that should'nt be there. e.g. PostgresDriver implementation, while SQLiteDialect is in use
the same issue occurs when using esbuild, so it's not just bun. i tried adding a
sideEffects: false
field to kysely's package json, but it still seems to import everything for some reason
Figuring out some dependencies, the CJS was included because of kysely-d1
requiring it. reduced the import of kysely by ~200kB by changing that to esm and changing it to use type imports only in some casesThere's a separate package.json file in
esm
and cjs
folders inside dist
. What happens if you add sideEffects: false
there?Also, #props and bundlers don't live together happily
shrunk the bundle by like 20kb by changing #props to _props
Also immediately invoked
freeze(...)
calls. we might want to hint that they're pure
it still bothers me, that all dialects are bundled
even if you only imported oneWe could move to separate imports, but how much would that really save? Vast majority of the code is in the core that always gets imported. The whole thing is like a hairball. If you pull the
Kysely
class, pretty much everything comes with it.I think it gets bundled due to side effects, and other stuff
It'd be cleaner to have separate imports for sure, but I don't think the bundle size is affected that much
The hairball is due to
Kysely
class actually depending on pretty much everything. There's no way to tree-shake most of it
Well if the tree shaker is smart enough then it's definitely possible, but if it can't tree-shake the current "import everything" index file, then it can't do it even if we split that to separate imports right?
due to side effectsWhat side effects? We don't have many of those
we can add pure hints
on immediately invoked functions
yeah i think thats the main issue
No it's not
Just try to manually remove the other dialects to see how much it affects
okay
ill fiddle with it
but no matter what i dunno why dialects would take up 100kB
but not sure, might be mistaken
You can see all the code the dialects have in the repo. It's a couple of tiny classes per dialect.
https://github.com/kysely-org/kysely/tree/master/src/dialect
All code in kysely (not minified) 1.6MB the whole dialects folder 148KB
All dialects combined only explains 10% of Kysely's size.
hmm
whats so big?
is it the various query types?
A lot of documentation is one thing
like alter table etc
The whole schema module is 132KB
damn
The types are also super complex and take up some space. But the most wasteful thing is probably the operation nodes
lemme check
i mean complex types get eradicated in any bundling process
Unknown User•8mo ago
Message Not Public
Sign In & Join Server To View
since it then becomes only js
Yep, 456k just the operation nodes
🤯
i mean complex types get eradicated in any bundling processThat's true. And most of the operation node files is just types
hmm
ill check it all out when im back
seems that the operation nodes files aren't just types, looks much more like an AST declaration to me (might be confused here)
i'd guess its still only for TS to have valid typings though, which is not something should be necessary when actually running kysely
tsup is for libraries, it excludes node_modules.
Unknown User•8mo ago
Message Not Public
Sign In & Join Server To View
oh that would probably optimize the hell out of this
maybe a typescript transformer?
cant you already compile queries with kysely
i mean yeah adds a build tool but it would work
main issue i think of is conditional queries, need to have separate compiled queries for each branch
wym?
i was thinking pretty much along the lines of the existing query compilation. essentially you would have a query as below within your code
then using some TS magic, the build step would infer that
db
is an instance of Kysely, compile the query (as is in the docs), and then some essentially "basic" instance of Kysely could be used to execute the compiled query, so essentially after it would look like this
are we talking about the same thing? because if we are then that would actually be insane to haveYou should really profile things before you build a plugin like that. You'll save the CPU time of building the query, which is nanoseconds. Microseconds at best
The query builder is a lot faster than running JSON.stringify
not the time of building the query, but you don't need to import any of the operation nodes
since those aren't relevant at that point - assuming my previous assumption about them being only for TS type inference was correct
No the nodes are used internally to represent the query.
They are the very thing that makes kysely work internally
ah my bad
thought a compiled query could be executed simply from the sql and parameters
And how would you transform this query:
yeah, that relates to my previous point here
you would need to have two queries, execute the basic one if !foo and the second one (first name check) if foo
since they expand factorially for every if statement it would not be fun to debug with say 5 statements, since thats 5! = 120 queries
Unknown User•8mo ago
Message Not Public
Sign In & Join Server To View