When to component in the front-end with frameworks



  • Note: This isn't in coding help because it's more a discussion topic.

    Second note: If you're hand-rolling HTML rather than using one of the fancy frameworks, this doesn't apply to you. I wish I could be like you sometimes, however. But I can't.

    So. You (hypothetically) have a fancy front-end HTML/JS framework. React. Angular. Vue.js. Etc. They all do things in terms of "components"--effectively custom HTML tags backed up with framework generated glue code to handle things like reactivity (change one piece of data and the relevant pieces refresh without manual fiddling), events, interactivity, reusability.

    The question that's been in my mind a lot (we use Vue.js) is "what justifies creating a new component"? Also, are there costs for creating components (performance, developer, etc)?

    Anyone got good rules of thumb, considerations, or links on this matter?



  • Well, the most obvious one to "component out" would be iterations / maps. Reacting to events to, say, a button click otherwise can become a nightmare.

    Then there's the repainting to consider: Your component should repaint only for a change in one or two variablest, maybe three at the most (thinking of a form field here). So instead of having your whole form rerender because one field errored out, you only rerender that one field because you put it into a component.

    Then I'd also go for depth - if you're five or six levels deep it's high time to think of componenting stuff out.

    And another one would be separation of duties - navigation gets its own component, as does the body, as does the popup banner.



  • Most of those track with what I'm thinking, although there are some edge cases I still need to think about. One question though:

    @Rhywden said in When to component in the front-end with frameworks:

    Then I'd also go for depth - if you're five or six levels deep it's high time to think of componenting stuff out.

    One question here--at least in Vue, adding components ADDS depth to the DOM tree faster-than-linearly. That is, components tend to introduce extra container-type elements. Is that a problem? I know most profiling tools start screaming when the DOM gets too deep. So components tend to make that worse. Does that matter?



  • @Benjamin-Hall said in When to component in the front-end with frameworks:

    Most of those track with what I'm thinking, although there are some edge cases I still need to think about. One question though:

    @Rhywden said in When to component in the front-end with frameworks:

    Then I'd also go for depth - if you're five or six levels deep it's high time to think of componenting stuff out.

    One question here--at least in Vue, adding components ADDS depth to the DOM tree faster-than-linearly. That is, components tend to introduce extra container-type elements. Is that a problem? I know most profiling tools start screaming when the DOM gets too deep. So components tend to make that worse. Does that matter?

    Well, that's the tradeoff you have to make between legibility / maintainability and speed.

    Flutter was a nightmare for me in that regard: Everything is a component. Animation? Component. Event? Component. Styles? Component. Sometimes you'd get seven or eight levels of nesting because you wanted a button that has an appearing animation, turns red when you click it and needs a data-binding because you don't want it enabled if condition == foo



  • @Benjamin-Hall My coding style for making components has changed considerably over the years. I once made "thick" components, with the business logic and the display logic right next to each other. I have made 1000-line components, and maintained 2000-line components.

    But I'm allegedly reformed now. I've switched over to "mostly-thin" components, with the logic living over in a store and/or a bunch of loose functions grouped in reasonably-named files. I'm still not a Perfect Component Developer, because I prefer to pass in the store (with both business data and business logic in it) into the component, rather than passing in a pile of callbacks and values. This is because we already have a mostly-decent component library, so when I'm writing new components now, it's always for a terribly-specific page and a terribly-specific reason. So the odds of reusing my components are slim. (And, on the rare occasion where it happens, it's not too hard to refactor those components to take callbacks and values rather than a store. So I go for YAGNI.)

    All this to say I'm an awesome developer.

    Oh, right, you asked a question of some sort.

    My new limit is about 400 lines in a component. If I hit that, it's definitely time to refactor it into multiple pieces. I almost always break things down smaller than that, but 400 lines is my hard limit. After that, it depends on whether the component is reusable, or whether it's a one-off for a particular feature.

    • I make reusable components at whatever size gets reused; I have a component for both a section-heading-with-features (with underline and optional expand/collapse), and also one just for the section-heading font, because both of those get reused in various places. Those are pretty small. But I also have a component for modal dialogs (large-ish), plus a couple of specialized modal dialogs that fill in a bunch of the params for that ultra-general modal dialog. (I think that might be the only place where I have a component for a font; everywhere else, we just use MergeStyles or CSS to set fonts. You might be thinking that the codebase I work on has a fair amount of technical debt, and you'd be right.)
    • I make one-off components at whatever size is logical, but erring on the large size because I don't expect them to be reused. So a form that has ten inputs might just get one component, because I don't expect the form to be reused. (The inputs are, of course, from our component library, not raw <input> tags.)

  • ♿ (Parody)

    @Benjamin-Hall said in When to component in the front-end with frameworks:

    The question that's been in my mind a lot (we use Vue.js) is "what justifies creating a new component"? Also, are there costs for creating components (performance, developer, etc)?

    We use Angular, so that's where I'm coming from:

    • Each route (page) is mapped to a component
    • Anything you want to reuse. Especially custom controls.
    • On complex pages I'll often have components for each grouping (on a tab, accordion, etc). If nothing else, it prevents having to work with components that have thousands of lines of code. This often makes testing easier, too.

    I'm not really aware of any performance issues. I would think that mostly disappears when it's all compiled. Is this a big deal with Vue?

    Pretty much all of my performance issues are DB related (pulling lots of data from complex queries, etc).


  • Considered Harmful

    Real answer requires doing bounded-context inspection over the interactions. Then you should component such that you can fill to your contexts without gap or overlap. This may mean abstract or behavioral component limins within the visual design limins. Your tests (haha, usage) will show you where you got the limins wrong.


Log in to reply