Hi all, this is just a post out of curiosity (and a little bit frustration) to see how other front end developers do their thing... I'm a FED working mainly as a contractor and freelancer, so I work on a ton of different projects and teams. However, I notice that most of the time, developers (and myself included) seem to just "wing it" when it comes to developing.
A client gives requirements (which are usually not complete), you have a wireframe or design, you have a half baked API (that needs input from you) and off you go... 90% of the time I find myself going straight to writing code and just figuring it out as I go... In small pieces of UI this can work OK. But as soon as things start to become complex and layered with different components and states and responsive styles, things start to get hairy.
I usually just end up plowing my way through, getting the job done, but never happy with the end result. Surely there is a better way, I think to myself all the time.
What I'm interested in knowing, is if there is a pattern, or a formula to go about designing, planning, developing in a way that is predictable, scalable and reliable? What tools or techniques do you use to ensure a piece of UI, big or small, can be done in a way that ensures you (and the client) are satisfied?
I know this is a pretty open-ended question, but I'm just keen to find a better way of doing things. I'd love to hear your thoughts!
Getting my first 100 users with $0: what actually worked
What's the point of AI generated comments?
Why I’m building an AI marketplace instead of another SaaS
Why good products are often hard to understand at first glance
Why can't your target customers always find your product? - Experience sharing
The exact prompt that creates a clear, convincing sales deck
Thanks for the response @peachweb yeah it's hard to niche down as I work on a variety of contracts in different domains, which I love to do as I get exposure to different industries and solutions. But yeah, I should take a "complex first" approach, I like that :)
I think what I am looking for is kind of like a checklist to mentally run through before starting on any UI. Things I especially get tripped up on is remembering to take a mobile-first approach when styling, naming variables and mocking data, and including state diagrams to really myself and others understand whats going on.
In a perfect world there would be time for refactoring - sometimes I have that luxury, but oftentimes not.
It sounds like you're saying missing a level of code optimization best practices. Because if you knew the best practices, you'd just practice them because you'd intuitively understand the tradeoffs between not doing them as soon as possible in a project and you wouldn't have any choice but to do them out of habit.
Let me know if I'm misreading somewhere. If I'm not, I think this is the best path forward:
• Read books and online resources on code optimization
• Analyze and refactor existing code
• Collaborate with experienced developers (this has worked best for me)
• Practice with side projects
Your goal being to form good coding habits. A checklist won't do anything but spot check your thinking. If you instead focus on forming good thinking habits with how you handle logic and other parts of code, less things will go wrong.
On speed vs quality by Bob Marks (whose books you should look into): “The only way to go fast is to go well. Every time you yield to the temptation to trade quality for speed, you slow down. Every time.” http://butunclebob.com/ArticleS.UncleBob.VehementMediocrity
🤯 woah this is great advice. Thank you so much. I really agree with you, it's about a mindset, habits and recognising (early) code quality/patterns/optimisations and when things are veering off track. Thanks for pointing out that a "checklist" won't solve things, and encouraging me to think more critically about it.
That quote is great, and I think it comes down a lot to my work habits and process in general. I think I add extra stress (unnecessarily) with just my own thoughts (ie) I need to get out of my own way.
A calmer approach to work, trusting everything will be OK, and everything will be delivered on time, would lead to a more relaxed flow of creative energy.
I completely agree with your last paragraph. If you're doing your best, what else is there? By the way, the Bob I quoted is Robert C. Martin, not Bob Marks. I accidentally gave you the name of one of my favorite astrologers 😆
Yeah I know a lot of it is mindset, so in essence, that's what I am trying to achieve. That, along with a solid foundation of best practice approaches, good quality coding techniques and methodologies.
I think moving fast works when you hit the sweet spot of a task that sits just within, or slightly beyond your limits. It needs to be something one is confident in solving quickly, which means the more deliberate practice one does, the better they will be able to move fast.
Furthermore, the more I think about it, the more I realise there are distinct phases to a piece of work. eg. the investigation phase, the estimation/planning phase, the initial development and figuring out if it will work phase, then if all is well, the execution phase where all the ifs and buts and what ifs are answered. Similar to what Basecamp does with the hill chart (https://basecamp.com/hill-charts).
Speed might come in ebbs and flows depending where you're at in each phase...
Thoughts?
Thanks @jsimons that's really helpful. I've always wanted to use Storybook more but just found it a bit of a pain to get set up.
Same for data fetching, libs are the way to go and I prefer to also extract as much of the fetching logic away from the consumer components as possible.
When you say "keep nesting shallow", are you referring to components or files in a directory? Also, are there any hard rules on the size of a component before it needs breaking down?
I'm finding using Vue 3 a lot more that I am starting to write a ton more spaghetti code, similar to React, whereby you import a million bits and bobs, use state everywhere, and before you know it, 50 - 100 lines of code are just imports and constants.
I think I want to explore tools like XState more, where you can create state flow charts, which I think would go down really well with managers/stakeholders, so then they can clearly see the flow of state through the UI / component. I think it might also remove a lot of that fluff as you can declare state inside the state machine.
Re: nesting I'm mostly talking about conditionals in your code - returning early from functions, avoiding long switch statements and deeply nested ifs / ternary statements. Those are things that tend to really slow me down cognitively.
Funnily enough I saw Dan Abramov was speculating about having first class state machine support in React the other day https://twitter.com/dan_abramov/status/1644759833550135299
XState is a good shout - I'm using it in production to co-ordinate a post composer and video capture / review widget which have quite complex state requirements. I found it quite nice to work with, though I suspect I'm only tapping into a bit of the full power of it. It did a great job of making explicit the complexity that can get a bit buried using lower level state primitives.
State management sounds like an important part of the puzzle though - can I ask what approaches you've tried so far?
Yeah I agree there, less conditionals the better, I know when I work with react and have code complexity linters on it really helps. I know there is some hype around the "5 lines of code" rule, which I somewhat agree with, but also think it's a bit of a trap, leading to extensive abstraction, leading to more files and folders to stuff util functions in.
Yeah I really should invest the time into XState, similar to you I've only just scratched the surface of it's potential. Have you found the state charts help other members of your team (especially non-technical folks)?
For state management, I've used redux slices a lot, and I love Vuex for Vue. I know Pinia is all the rage now with Vue 3, but I really like the way you time traveled with mutations in Vue, and I'm finding now a lot of devs (myself included) don't really follow that pattern with Pinia. It makes it harder to track state when things just "update".
Since reading this article (https://dev.to/davidkpiano/no-disabling-a-button-is-not-app-logic-598i) I've come to appreciate the use of reducers a lot more in React.
Still, I find React much more complex than Vue when it comes to state management.
This sounds really familiar, IMO frontend code is particularly prone to feeling 'out of control' once you hit a certain complexity threshold.
Here are a few rules of thumb that I find help with this - maybe a little React-specific but should be generally applicable:
Separate components by feature - use one core directory for commonly re-used components (Button, List, Card) etc, but split the rest out by application areas (Settings, Auth, Dashboard)
Use composition and be strict about naming conventions. List of users in Settings? Call it SettingsUserList. Every component with a globally unique name.
Keep nesting shallow. The further to the right of the editor your code gets, the harder it is to keep in memory.
Break everything down - as you add more functionality into components you can lose control of them. Breaking them up into sub-components each with a single responsibility helps.
Use established patterns and libraries for state management and networking - I like Apollo and React-query as they remove a lot of complexity from my code.
Use Storybook / Chromatic or similar to do visual regression testing - manual UI QA is pretty labor intensive.
Hope this is useful!
Could you try approaching the project as a complex UI from the start? That way you’ll code as if it needs to be optimized.
You could also try leaving time in the project for tidying up or refactoring.
Another option is niching down so you’re only building one type of site. You’ll be able to systematize your process if you’re not building an ecommerce site one month then a landing page the next.