Kotlin / kotlinx.html

Kotlin DSL for HTML
Apache License 2.0
1.61k stars 131 forks source link

Generated Javascript too big due to too much inlining #215

Closed PeekAndPoke closed 1 year ago

PeekAndPoke commented 1 year ago

Hi there! I want to point the maintainer of kotlinx/html to an issue that I just spotted when using this great library with JS.

So the problem is: There is too aggressive inlining, which results in extremely large javascript being generated.

So here is an example. Say we have the following piece of code:

 div {
    div { +"THIS IS A DIV IN A DIV" }
}

This will result in the following Javascript:

var n=new _(i("class",null),e._get_consumer__1060829845_hjl9jp_k$());
n._get_consumer__1060829845_hjl9jp_k$().onTagStart_jhb705_k$(n);
try{var r=new _(i("class",null),n._get_consumer__1060829845_hjl9jp_k$());
r._get_consumer__1060829845_hjl9jp_k$().onTagStart_jhb705_k$(r);
try{r.unaryPlus_g7ydph_k$("THIS IS A DIV IN A DIV")}catch(t){if(!(t instanceof Error))throw t;
r._get_consumer__1060829845_hjl9jp_k$().onTagError_d07vof_k$(r,t)}finally{
r._get_consumer__1060829845_hjl9jp_k$().onTagEnd_f3ehek_k$(r)}}catch(t){
if(!(t instanceof Error))throw t;n._get_consumer__1060829845_hjl9jp_k$().onTagError_d07vof_k$(n,t)}
finally{n._get_consumer__1060829845_hjl9jp_k$().onTagEnd_f3ehek_k$(n)}

The reason for this that all the tags are inlined, e.g.

@HtmlTagMarker
inline fun FlowContent.div(classes : String? = null, crossinline block : DIV.() -> Unit = {}) : Unit = DIV(attributesMapOf("class", classes), consumer).visit(block)

And even the .visit() at the end itself is inlined

inline fun <T : Tag> T.visit(crossinline block: T.() -> Unit) = visitTag { block() }

This is leading roughly to an overhead in size of about 300 characters for EVERY single tag. If you have thousands of them, which is normal for single page application, this quickly generates mega-bytes.

So my suggestions is:

Remove the inline from this line:

inline fun <T : Tag> T.visit(crossinline block: T.() -> Unit) = visitTag { block() }

I think the performance impact should be neglectable:

e5l commented 1 year ago

Fixed with 0.9.0