when building a naked “hello world” in kotlin/js i...
# javascript
p
when building a naked “hello world” in kotlin/js is getting a 500k webpack bundle in build/distributions/{myproject}.js the lowest I can get or is there an option like “treeshaking”, “optimize”, etc. I am missing?
🚫 1
😵 1
j
worth looking at discussion in https://twitter.com/HandstandSam/status/1369852373674426373?s=20 (from @handstandsam)
I think main change that brought it down was use of Kotlin 1.4.30 and selecting use of IR backend
😎 1
👍 1
p
wow using IR instead of LEGACY made a huge difference — thanks John
👍 1
I also discovered gradle task “browserProductionWebpack” which makes it even smaller
t
One more option -
-Xir-property-lazy-initialization
Example
m
@turansky that should make it larger again, but faster to execute in specific cases 🤔
But yeah, it quickly becomes ridiculous. My index page has a 1.4 MiB JS file (287 KiB compressed).
But still, Lighthouse is quite happy with my optimizations :)
👍 1
t
-0.5 MB
in Ktor cases
m
Yeah, Ktor and Coroutines are gigantic, in Browser JS terms
I load them lazily.
You can test performance for yourself. But page (and startup) are still in development 😜 It’s Kotlin/JS with my own React+CSS libs on top. https://hobogenki.com (test domain)
s
Lazy property initialisation, while adding a small flat overhead, can drastically reduce code size in some cases. It allows compiler to eliminate initialisers for unused properties. In eager property initialisation mode they are always kept alive including all the code referenced by them.
m
Hmm. I’ll make a quick test to compare 🙂
s
This would be noticeable when using only a small part of some third-party library with a lot of top-level properties.
m
Every single React component is a top-level property. And I guess `object`s are lazy too now, so an additional +1 per component.
Without `-Xir-property-lazy-initialization`: 12M pre-webpack, 4.5M post-webpack With `-Xir-property-lazy-initialization`: 12M pre-webpack, 4.6M post-webpack
s
object declarations are initialized lazily regardless of compiler flags, including legacy compiler
p
12M?! omg!
is it 12MB for a full-blown app ?
or is it still growing?
m
It’s what you see on that domain: Some static pages, the sign-up process and a simple membership center. 12 MB mostly because the input JS for webpack aren’t optimized for size at all. The code looks like that:
Copy code
var tmp42__get_fixed__0_175 = null;
    var tmp41_unsafe_0_176 = 'fixed';
    var tmp40_unsafe_0_177 = null;
    var tmp43_position_0_174 = tmp41_unsafe_0_176;
    var tmp0_unsafe_0_2_179 = null;
    var tmp1_unsafe_0_3_180 = 'position';
    var tmp2_property_0_1_178 = tmp1_unsafe_0_3_180;
    var tmp_24 = tmp2_property_0_1_178;
    $this$style.p(tmp_24, tmp43_position_0_174);
    var tmp11_with_0_2_182 = null;
    var tmp10_build_0_3_183 = null;
    var tmp0_unsafeCast_0_6_186 = [];
    var tmp1_apply_0_5_185 = tmp0_unsafeCast_0_6_186;
    var tmp0__get_percent__0_20_189 = 50;
    var tmp2_of_0_1_21_190 = null;
    var tmp0_unsafe_0_2_22_191 = null;
    var tmp1_unsafe_0_3_23_192 = '' + tmp0__get_percent__0_20_189 + '%';
    var tmp1_unaryMinus_0_19_188 = tmp1_unsafe_0_3_23_192;
    var tmp2_translateX_0_18_187 = times_2(tmp1_unaryMinus_0_19_188, -1);
    var tmp0_add_0_1_24_193 = '' + 'translateX(' + tmp2_translateX_0_18_187 + ')';
It depends on Terser optimization or alike. Unfortunately some code that the Kotlin compiler spits out doesn’t get optimized well by Terser. For example around String concatenation.
It just looks so funny.
And the compiler creates an insane amount of anonymous objects for passing functions around. I guess all that is yet to be optimized once the IR compiler is stable.
s
Doesn’t look very nice indeed. yet to be optimized.
p
so would you again choose kotlin/js or instead go with typescript + bundler if starting again?
m
Definitely Kotlin. It’s immature yes, but I still love it so much more than struggling with TypeScript. Or having to jump between different languages in a single project (back-end & front-end). And for example the data model and serialization code is shared between back-end and front-end in my project.
But I also have the benefit of not depending on a lot of 3rd party libraries. These can be a hassle to integrate.
p
I really enjoyed watching this:

https://www.youtube.com/watch?v=Pf6PG26gM2Y&t=13919s

at around 40000 they tell about jetbrains spaces … using websocket, kotlin/react and stuff… I must admin I am impressed
m
Yeah me too. That’s why I’ve asked them to make Space open source as a reference 😄 But they said it’s too messy to share 😛
p
could be an excuse or the truth 🙂
m
Building entire websites or apps in KJS is relatively new. We’re all trying to figure out what good ways are to build things with it.
p
however, using websocket and one single language would be an perfect fit for my current problem… having an administration frontend for an automated service serving various trading platforms
^ not requiring any seo visibility
m
Something that unfortunately won’t scale well is sharing data model in server and client. Over time you’ll get issues with migration and when some clients/server sees more/different things than the others. It’s also not really helpful if you want to build something (partially) open. GraphQL makes more sense then.
For closed systems where you have control over everything it makes most sense.
You don’t have to care about public API nor about data model evolution.
p
yeah, exactly my use case … having kx-serializable data classes and an react client would be just great
m
I just haven’t figured out yet how to make breaking website updates without breaking those clients that are currently on the website. 😛
p
deploy a second app and switch requests via frontend proxy
m
Just expect a lot of rough edges at the moment, esp. if you want good size and performance. I’m using so many hacks and workarounds in my project it’s amazing that it works.
p
are the hacks something I should be scared of?
m
@Peter Ertl the problem is the back-end. Data model changes for example. Or API endpoints.
p
currently I generated typescript classes for my requests which works pretty well over an generic /rpc endpoint
but I hate to have two languages
👍 1
m
Depends on what you need. If you accept current limitations when it comes to size, performance or how flexible DSLs you can build then you should be fine mostly. Once you start focusing on size & performance (lazy loading, making things more minifyable, etc.) then you enter the dark side.
but I hate to have two languages
Yeah me too
Even PDF creation uses Kotlin (kotlinx-html for now)
p
server or client side? itext / pdfbox / etc . ?
m
Server-side using Chrome. https://github.com/fluidsonic/fluid-pdf
p
oh wow never heard of this one … nice
m
I’d probably would have much more work wouldn’t I build my own libraries for almost everything 😅
p
just the attitude I share.. most things are just not worth to introduce another dependency
r
You could just install and run
wkhtmltopdf
on the server 🙂 It probably works very simillar.
m
Nooo don’t do that. I’ve been there
The technology it uses is so incredibly outdated it can barely handle CSS2 properly.
r
I've been using it years ago so I don't know they are doing now 😉
m
Barely any difference since then 😕 They depend on some Qt stuff that’s not really developed anymore.
p
jetbrains compose will be nice, too, but I miss some kind of upgrade mechanism like java web start had
m
Some of the funny hacks you may come across.
I think Compose Web is still too early stage.
p
probably yes …
they really need a solid compiler 1st
multiplatform
r
@Peter Ertl If you are interested in fullstack Kotlin (Kotlin/JS, shared data model, different supported backends, websockets support) you can check KVision (https://kvision.io) (disclaimer: I'm the author 😉)
m
Yeah and tooling. There are boatloads of IDE issues. Many fixed, many more to go.
Oh there’s one thing you need to keep in mind when developing with K/JS and the project grows. I see it just now again. The build -> run cycle tends to be quite long.
For me approx. 1 minute from change in IDE to seeing it on the page.
r
a minute?!
m
yup
r
no way 😆
p
a darn … that’s insane
m
I had to turn off incremental compilation due to compiler bugs.
p
you just made me reconsider my decision 😛 I really don’t want to wait for 1min
I can’t compile my current jvm code with the new IR
compiler bails out with an error dumping a huge AST diagnostic context
m
Report it in #jvm-ir-backend-feedback 🙂
And YouTrack
p
I still need to figure out how since I can’t share the company code publicly
m
maybe it’s already reported? find a similar ticket
p
I am in no hurry … just mentioning it since legacy works fine so far … but I try to find a way to contribute
m
I’ve moved all my libraries and projects to JVM/IR. There were a few issues but most easy to work around.
p
is there a noticeable speedup for k/jvm?
m
I’ve never measured. And I didn’t notice anything in day-to-day life. My MacBook’s performance is inconsistent anyway ¯\_(ツ)_/¯
r
@Marc Knaup how big is your Kotlin/JS app (files/lines of code)?
m
ugh. Is there a plugin to measure that for me?
r
cloc
command line perhaps?
I've got this on linux
m
I’ll try the MetricsReloaded plugin
image.png
r
Is this for Kotlin/JS only?
m
K/JS and the multiplatform modules it uses
Back-end is in the same ballpark.
r
It's larger than my. But still for my 6K lines project I wait about 3 seconds with legacy and about 10 seconds with IR till browser refresh.
m
With incremental builds disabled?
r
no
I'll test
m
Copy code
kotlin.incremental.js.klib  = false
Not sure if that works for you though
I have a multi-module K/JS setup with
-Xir-per-module
It compiles and links very differently
r
I've tested with
kotlin.incremental.js=false
but it didn't make any significant difference (at least with IR).
m
Maybe you do need the
.klib
at the end?
Haha, me trying to compile without `-Xir-per-module`:
Copy code
e: java.lang.OutOfMemoryError: Java heap space: failed reallocation of scalar replaced objects
🤭 1
☠️ 1
I have to live with the compile time for now ¯\_(ツ)_/¯
I hope 1.5 comes soooon
p
time will be working in your favor
m
exactly
p
o yes, pls god, give us 1.5 stable - soon
m
I’m investing in [and betting on] the future of Kotlin 😛
p
it’s the way to go
it’s sad that scala did not make it … i really like the more functional approach but that’s about everything that scala has to offer for me
when doing real work scala is no more an option for me
I always hated how they broke everything when switching onto another major version e.g. 2.11 -> 2.12
all binaries need to be rebuilt … it’s just a damn jike
joke
m
yeah that breaking was super annoying
I’ve used so many different languages by now. Kotlin was the first that just feels right. Like, the right balance between things.
p
scala had a lot of potential .. kotlin just did it right
I first found it awkward they did not encapsulate null with an option monad .. but now I really like the nullable approach
jetbrains just cares about people and their work
m
Yeah and the team is super approachable
p
they are the only company that I love to transfer money to
☝️ 1
m
It’s so scary to hear people using Kotlin with… Eclipse…
p
oh yuk
same with kotlin and spring boot
when there’s ktor
r
kotlin.incremental.js.klib
is apparently for IR. Disabling incremental compilation makes the cycle almost twice as long for me.
m
@Robert Jaros still sounds faster than it is for me
@Peter Ertl yeah I also don’t like Spring. But also not really Ktor for application setup. It’s great for HTTP but not for high-level organization of applications.
That’s why I’m building my own, based on ideas from Gradle and Ktor
r
I do work with quite nice machine 😉
m
Which once? 🙂
one*
p
indeed, web workflows are a little tough with ktor
m
No idea what that means 😅
p
I mean managing complex application logic over various web pages and components
m
Ah, that’s client-side though. I haven’t solved that either. Only server-side.
p
me too … but I want to do it client side now and tried so many options … react, svelte, vue and others with loads of bundles and options and typescript … just sic
k
they all suffer one way or another
none of them is a perfect fit for me
so I tried kotlin/js
m
I love the approach of React. Just DI & organizing data loading is hell.
p
svelte is just great but the typescript plugin in IDEA is not fully functional and I just can’t get my head around using vscode 😞
m
I’m really looking forward for React Suspense and hope that Compose will have a similar feature based on coroutines.
p
that is my favorite client side stack : https://www.snowpack.dev/tutorials/svelte
m
I’ve coded a lot with TS in IDEA 🤔 Rarely had issues
p
but they are not fully ready for prime time
though very close
Bildschirmfoto 2021-03-17 um 18.59.04.png
it’s good but for typescript there are still some issues
they do NOT use a shadow dom which is an advantage
r
@Marc Knaup I work with Lenovo ThinkPad Gen2 (i7-9750H/32GB) and it feels really comfortable (I still work with legacy compiler during development because I like 3 seconds even more then 10 😉)
😀 1
m
Yeah when it comes to not using virtual DOM I just wait for Compose.
I have i9 32GB MacBook Pro from 2018 🤔
Yeah I cannot use legacy. Nor incremental builds. Such a pity.
p
here’s a good talk about svelte - doing async data loading is a no-brainer with it:

https://www.youtube.com/watch?v=BzX4aTRPzno

using svelte with ktor server side would be a good match
I auto-generated typescript interfaces of my data classes so writing rpc requests is completely typesafe
r
I would like someone to create svelte for Kotlin 🙂
They say it's just a compiler. It should be possible to make something like that for Kotlin.
m
Why spend time on that with Compose on the horizon though?
I’d prefer a Kotlin-first solution.
r
I'm talking about Kotlin-first
Not a binding for running svelte
m
So what’s the main benefit of Svelte over Compose?
r
but a svelte-like compiler for Kotlin
Isn't compose a Kotlin/JS library?
p
I also prefer a kotlin-only solution but svelte would be like my second best choice
m
Compose is the basis of the new Android UI framework. And because it’s so reusable and Kotlin-only it’s basically multiplatform, leading to Compose Web.
And Compose Desktop
r
But it still produces Kotlin/JS output, with all Kotlin stdlib overhead and so on.
m
Not once Kotlin/WebAssembly is ready :)
r
I'm not sure how svelte really works, but I've read it's a compiler that takes some svelte JS code and generates other JS code.
m
So basically like React, Angular and Vue? 🤔
r
I thing it could just take svelte kotlin code and do the same ;-)
Not like React. It works at compile time and not at runtime.
m
I’m not sure what you mean. Neither framework compiles anything at runtime
r
React doesn't compile. Svelte does.
With React (or others) the JS code you write is just executed. With svelte your code is compiled.
m
Well the Babel do the compilation for React.
<div>
etc. to
["div", …]
r
I'm not svelte advocate nor user so I'm out of arguments 😉
m
I just don’t get the difference yet 😅
look at the JS Output tab
m
I don’t know what the output if the other frameworks so I cannot compare. But looks nice.
h
I can’t see it mentioned, but I’d recommend taking a look at #fritz2 - it’s pretty darn awesome!
e
Basically, with svelte you don't program in JS but in a custom language which looks like JS with extra features, which in it's turn transpiles to JS