mithril.js icon indicating copy to clipboard operation
mithril.js copied to clipboard

Feature request: Custom renderer support

Open dead-claudia opened this issue 5 years ago • 2 comments

My proposal here is that we should see if we can create an alternate renderer that supports pluggable renderers, rather than just rendering to the DOM directly. There's a few reasons why we should support it in core:


For obvious performance and size reasons, we shouldn't place this in the core bundle. Instead, we should create an alternate render implementation specialized for custom renderers.

I do get the concern of a lot of duplicate code, but I feel there's enough different fundamentally that the duplication and added complexity is a little more tolerable:

  • Namespace tracking doesn't need to exist. If necessary, the custom renderer can just infer from the parent and tag name itself. (It's not that hard, just a little edge case-y.)
  • Element-specific hacks like for contenteditable, value and selectedIndex for <select>, and the document.activeElement IE hack are not necessary custom renderers enter the equation.
  • Event listener management could be made slightly different - we aren't bound to the traditional event interface, so we could get a little creative there.
  • Most of the mess that's setAttr and removeAttr could be streamlined without all the edge cases that flood that part of the code.
  • We would need to address how to model assigning the vnodes to the root "element".

The only other modifications required are to 1. move the redraw service to accept a render service parameter instead of creating it directly unnecessarily ($window is only used in that one place), and 2. move all the redraw service factory's callers to pass it a render service instead of a raw window value. Incidentally, this would provide a couple benefits of its own:

  • It would simplify testing the redraw service, since it'd just be testing how it calls a few methods.
  • The redraw service wouldn't need to return its renderService.render, just returning the hooks that actually deal with redrawing. This consequently makes the code less brittle.

Yes, there is a lot of extra complexity, but it's not like some of it couldn't be abstracted out pretty easily - there's a lot of code not touching the closure at all that we could reuse, many of which are already highly tuned:


This is not something I want to block v2 (maybe v3), but it's designed to be non-breaking.

dead-claudia avatar Aug 28 '18 10:08 dead-claudia

For those of you reading, apologies for the large wall of text. 😄

dead-claudia avatar Aug 28 '18 10:08 dead-claudia

Oh, and something I just remembered: this is a revival of a few prior issues here:

  • https://github.com/MithrilJS/mithril.js/issues/10
  • https://github.com/MithrilJS/mithril.js/issues/722
  • https://github.com/MithrilJS/mithril.js/issues/830
  • https://github.com/MithrilJS/mithril.js/issues/856 (by me)

It's a near-dupe of all but #10 (which is mostly focused on strings), but I'd rather keep this one alive since it's the most detailed of them all.

dead-claudia avatar Sep 01 '18 06:09 dead-claudia