Generated Javascript too big due to too much inlining
PeekAndPoke opened this issue · 1 comments
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:
- The HotSpot-JVM for example should inline things anyway.
- On Javascript size does matter a lot and the V8 could also optimize here
Fixed with 0.9.0