I recently had a great discussion regarding WebSockets and HTTP/2 with a former colleague. During the discourse, they uttered one line so deeply-set in truth that it must be shared. Repeatedly.
"It's all about trade-offs."
As someone who has been developing web applications for a little while (and as somebody who repeatedly rewrites them), I consistently find myself doubting the quality of the system at hand. It could be more performant. It could be more readable. It could be more developer-friendly or use the better (read: newer) technology X. These niggling thoughts often cause me to cave in and needlessly redesign a working system. Sometimes it's better, sometimes it's not.
Development as a whole is a mixed field. Its obscure mix of creativity and science is what attracts so many, yet it's that same trait that muddies the waters, encouraging bikeshedding and frequently instilling doubt in our minds. But remember, it's all about trade-offs.
For me, system design - and therefore development - is about achieving a balance between two distinct states of nirvana: performance and simplicity. Fulfilling both of these states is very possible, but we're most often limited by one ugly constraint: time.
Performance covers how fast it runs. If it's a service that delivers a response when asked a question, how quickly does it respond? How many questions can it handle at once?
Simplicity can be read as how understandable the system is. Does the system work in a clean and intuitive way? How easily would somebody else understand the system? Building something that's easily understood takes a lot more time and consideration.
Time is the major constraint. Deadlines, whether arbitrary or not, are everywhere and can't be ignored. Often, an application or feature is wanted to perform X and making the application prettier in ways the end user won't see isn't budgeted for.
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." - Martin Fowler
As a whole, we already abide by these forces unknowingly: the vast majority of developers use high-level languages like JavaScript and PHP that facilitate the creation of human-readable code. A program written in a high-level language will often be less performant than one written in low-level languages like C or Assembly, but readability, ease of use and ease of change counts for a lot, so we sacrifice these performance gains. Ergo, we trade performance for time and simplicity.
Very few projects, applications or architectures provide the freedom to reach the peak of performance and simplicity simultaneously, so we face trade-offs. We use X technology because its more well-known, so easier to find help with, though it may be less performant. We use a nasty-looking regex to perform a particular search because it's blisteringly quick, though it's insanely difficult to adapt to changing requirements. We use microservices because they're great for defining service boundaries and ownership, though they're hell to deploy.
Dynamically-typed versus statically-typed, relational versus non-relational, object-oriented versus procedural, monoliths versus microservices - there are no right answers. If you can reasonably justify the balance of performance, complexity and time in your application then your choices are correct. In most cases, a solution is not invalid because it fails to maximise a single aspect of its potential; it is the sum of its aspects.
Top comments (4)
I agree with you there, there are no right answers.
After struggling with the whole impostor syndrome / am I going down the right path in long run / older devs get stuck on legacy frameworks / justifying my stack choice to non-techies for quite some time - I have come to the conclusion (could be my subconsciously being in denial :) ) that it has to be about how you feel about technology and how does end user feel about what they've been delivered. It has to be enjoyable to you.
If the end product works well, helps user, there are no performance issues and it can pass basic tech and security scrutiny, who cares how exactly was it built?
One of the reasons I've stuck with PHP / CodeIgniter, well first, it would be insane to try to write 6-7 years worth of code in completely different language/framework, but because I know it very well and I do enjoy writing code iwth it, so delivering results to customers who pay for the service is much quicker.
Might not look that good on CV to some recruiters but hey ... it's a trade-off, right? :)
BTW not sure why you were worrying about posting your first article, you got a good point and your writing-style is nice, will expect more from now on ;)
Great article, I agree 100%. In my experience, as a web developer, the simplicity of the software almost always outweighs the performance trade off. I'm a huge advocate of writing clean, flexible code and addressing performance issues if/when they come up at their bottlenecks. I see this as a "best of both worlds" approach - you get code that's easy to refactor when the time comes while avoiding speculation about performance and micro-optimizations.
Amen.
Hides jsperf.com tab
Great article. All devs take note - it doesn’t matter how many cool toys you use, it’s the performance and maintainabilty of the end product that counts.