I fell in love with Stimulus and am refactoring our controllers one by one.
I’ve now had to make a tradeoff between
- Many controller instances with minimal scope, which leads to markup bloat due to common
data
attributes - Single controller instance with larger scope using event bubbling/delegation with minimal markup
Here’s a greatly simplified example to illustrate the tradeoff.
<ul>
<li
data-controller="delete"
data-delete-id-value="1"
data-delete-confirm-prompt-value="Really delete?"
data-action="delete#go"
>
1st
</li>
<li
data-controller="delete"
data-delete-id-value="2"
data-delete-confirm-prompt-value="Really delete?"
data-action="delete#go"
>
2nd
</li>
<!-- ... -->
</ul>
versus
<ul
data-controller="delete"
data-delete-confirm-prompt-value="Really delete?"
>
<li
data-action="delete#go"
data-delete-id-param="1"
>
1st
</li>
<li
data-action="delete#go"
data-delete-id-param="2"
>
2nd
</li>
<!-- ... -->
</ul>
The real case had even more value attributes which did not vary across controller instances. It also involved a large, dynamic <table>
with lots of markup in a large template. Every row has a bunch of “action” icons, which will use separate controllers (e.g., hide row, delete model, compose message popup, etc)
Stylistically, my team very much prefers the first approach. The controller markup is localized, making it way easier to reason about.
I refactored it to the second approach because the markup bloat surely carries a penalty. gzip
will compress it wonderfully, of course, but the browser will need to parse it and will have to handle a bigger DOM tree. Won’t this get out of hand?
Any advice and/or heuristics are very welcome.