[this is a placeholder and prone to change - please ask questions in comments]
The MobileFrontend View class encourages the overriding of a template partials by exposing a templatePartials attribute. Now the extension is mature, this seems to actually make things more difficult. Rather than having generic reusable templates we end up with many near identical templates. This is most notably observed in the classes which extend Overlays - overlays often have to replace entire template partials for headers which contain very similar HTML. It also encourages inconsistent mark up and class names.
Another sign this is a bad approach is the inconsistent use of toHtmlString and iconOptions / buttonOptions. On many occasions, specifically with Button and Icon classes - we want to include them inside a template partial. This is usually done by one of these two methods - the template for Button is used as a partial or we render a class with a template and then extract the outputted HTML. As Timo pointed out in T129943 this is very wasteful (full text below).
If you look at OOjs UI it handles this by appending elements where needed. We could replicate such an approach by using the following kind of pattern:
var btn = new Button();
this.$( '.btn-holder' ).append( btn.$el );
We could also make many of our templates - in particular overlay headers more generic so that it is easier to create new overlays (see T139798). This work would benefit the work Joaquin and Sam have been doing with turning this code into a reusable library mfui.
Original report by @krinkle:
> Disclaimer: I've only run through the code once and may've misunderstood parts.
> Typical usage:
// Via icons factory
// Or directly
new Icon( .. ).toHtmlString();
> * Constructor (View#initialize)
> ** Given that Icon has a Hogan template set, `View#initialize` takes the `if template` path where possible and precompiles the template for later use.
> ** The Icon class still has a tagName configured (not sure why, since it uses a template) and View creates an empty DOM element to be never used.
> ** Further down the constructor it calls `View#render()`. I'd expect a consumer to have to all render() or indirectly by another method, not in the constructor already.
> * Render (View#render)
> ** Icon has a template and isTemplateMode, so `render()`:
> ** Calls Hogan to produce an HTML string.
> ** Discards the previously created DOM element.
> ** Implicitly parses the HTML into a new DOM element with jQuery.
> * Embed (Icon#toHtmlString)
> ** Creates another DOM element.
> ** Appends the rendered node.
> ** Calls on jQuery to let the browser serialise the node back to an HTML serialised string.
> ** Embed the string in a larger HTML template, or call on jQuery to let the browser parse the HTML back into (another) DOM node.
> This all seems quite wasteful.