Hi there! I want to point the maintainer of kotlin...
# kotlinx-html
p
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:
Copy code
div {
    div { +"THIS IS A DIV IN A DIV" }
}
This will result in the following Javascript:
Copy code
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.
Copy code
@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
Copy code
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 are: 1. Remove the
inline
from all tag functions 2. Add @JsName to all props and methods in
interface Tag
and
HTMLTag
and
CommonAttributeGroupFacade
etc. to avoid name mangling, which also roughly doubles the code produced. I think the performance impact should not be measurable. • The HotSpot-JVM for example should inline things anyway. • On Javascript size does matter a lot and the V8 could also optimize here So how do we proceed with this? Is there a way to disallow inlining for a specific target platform?