Minimalism – An undervalued development skill
volument.com
volument.com
Minimalism makes for a clean, easy to understand codebase, that avoids some of the performance pitfalls associated with bigness.
But sometimes it’s easy to build 80% of what you need, and then massively difficult to get to 100%, and the ease of getting to 80% can lead you astray.
For instance, I can write a pretty fast matrix multiplication algorithm in maybe a few dozen lines of code. But then you look at OpenBLAS, Eigen, MKL, FBGEMM, etc. and you see thousands of lines of code. And it’s not because I’m 100x better at programming than the developers of these libraries, it’s that they’ve really put in effort to getting the best performance, in all corner cases, on all platforms.
You could argue that matrix multiplication is an extreme case, and it is, but I think it’s still valuable to critically think about what you give up by opting for minimalism before you write off other people’s software as aimless bloatware.
—Tom Cargill, Bell Labs
I suspect that part of the reason for feature bloat is that a when product is assigned dedicated, long-running teams, it tends not to reach an 'end state'. The team would rarely say "okay, now the product is mature, let's place it on maintenance and go on to build something else". Instead, they may (unconsciously) continue to justify their existence by continuing to 'improve' the product.
I am still unsure of how I should have approached this, but I know I messed up because at the end it was just way too much effort to fix bugs and add features, but I didn’t have the time to refactor. If anyone has advice, I would be grateful.
Also if it’s your first time and you need the cash and experience, you can overdeliver a little. But if nobody is ever unhappy with you then be aware that you probably are overdelivering.
It is the power base of personal change.
2. It's ok to make the client responsible for everything in writing. Especially if you do not have a deep committed relationship with them.
I have clients I have worked with for over 15 years and they don't even need a quote from me to start work, and they send me a check for any reasonable amount up front.
I have other clients where I spell out every single detail before I start and I do not deviate (add or subtract) from this list (for both our benefits) without written request from them and possibly a fee change.
3. I give away free work to many clients for many reasons. Some I don't even let them know, and others I make sure to put it on the invoice as a discount and rate. This way they know that I did the work, I did it for free, and they should recognize that. Also so that it's easy to charge for this work in the future.
A lesson I learned hard was a few failures:
1. When to start: I did a bunch of work when a client said ok on the phone. When I invoiced he was mad because he didn't remember saying "ok" to start work. So, now I only start work with an email record, period. Even if it's annoying, even if it delays work, even if it makes the client annoyed. Every single time I ask "can you send me an email with the ok to start this work?" (or I prompt them with an email and they reply) Again, some clients verbal is ok, but only if I know them really really well. (ie, lots of previous work with them)
2. Extra work: I did a bunch of extra work/features on one project, and they wanted me to support the extra work also for free forever. (forever... sigh) And were angry when I said I couldn't...
3. Accountability for timelines: I had a project that every weekly meeting more features got added to the project. We spent half to over half our budget in meetings. (yes that bad) So I made sure to document all time spent on everything one month. The next month the lead project manager started cutting back the meetings instead of us devs complaining about not having enough time, the project manager _knew_ we didn't.
4. Specs and Expectations: Numerous times I "imagined" what the client actually wanted because I knew better than them. I would build something expecting to be paid for it (or at least appreciated) and it would be presented and the client would ask for it to be _removed_ from the project.
This was the last kick in the teeth I would ever take from this, ever, ever again.
Then later a new client (a state university) had visual layouts of interfaces given to me. I had learned some lessons about being screwed over before, so I was going to stick to their layouts no matter what. After it was built, they were _really_ pissed, and had the gaul to say to me:
"Why did you build it this way?" And I said "Because it was how it was designed and specced out". Their reply?
"That isn't what we wanted, you were supposed to make what we wanted."
Unreal, but I won this argument hands down. No one can read minds and people who expect you to don't have a reasonable argument if you provide your experience on why you will never do this again. What can they say to you?
My long term clients _never_ give me a hard time about anything extra I do, ever. I know them, they know me and they say "make something that solves this problem the best way you can", and we may tweak, but we respect each other and I fix my errors, and they pay for theirs and we meet happily in between no matter what.
Also, I will no longer support software for free indefinitely, I say I offer free bug fixes for 6 months. Any new features is paid work. And support after 6 months will need to be negotiated. (all this depending on the client and project)
I state as much as possible up front about everything (in writing) so there are as few arguments as possible (I hate arguments with clients they really suck). Doing this extra work kinda sucks sometimes, but the older I get the less I have to do this. The first time it saves your ass you will be happy. And as soon as you write it and hand it over you will have instant peace of mind.
It may take you a few projects to get the handle of these ideas, but it's obvious you recognize there is a problem. But communication and clear expectations is the solution. I have also learned to say "Sorry, I meant to state this up front, I failed to do so, so I will give you X for free for my screw up, but I still need Y to do Z"
Keep at it, what you are facing is normal, and your desire to do good work is commendable and will pay off in the long term in ways you can't imagine.
Cheers!
In the process of building something if I added say a color picker or a calendar date selector, but the client wanted just a text field. Then the color picker/calendar date selector has an issue with a really, really old browser and I have to spend time debugging it at their request. (again because "young and inexperienced" me can't explain it properly)
My current self would just remove it, and/or explain it will cost extra. Soo 100% of the problems I described above are solved with mature communication that I learned the hard way.
--Features requested vs features built--
A client will ask for 100 features up front, we build 10 and by the time we have an alpha, he bails on 90 of them, and adds 20 new ones. Of those we bail on half again. This is so normal that I now bring this up at meetings to help us prioritize development.
I have had very long term clients ask me to remove something, then later ask "where did that feature go?", ha. I have to laugh at this, and I explain to them "I don't remove features without written request, if you want me to spend time looking up why this is removed (likely from an email) I can do that..." But they never have me do this.
I have built extra templates/views, sorting features, even tools to add/remove things the client didn't want users to have access to, so I had to delete them. (no one would pay for a toggle to disable a feature they didn't request, hence the delete on my dime)
One client even went so far as to say he didn't want _his_ clients (it was a CMS for web sites) to see how easy it was for him to build sites using the software. (his clients had access to the software for content maintenance)
I had built an LMS (Learning Management System) with a group once (again, I was young and eager to impress) and I vaguely recall adding some features for working with quizzes or something, but because I had at least 2 PhD's on the team, that mightly protested something about "that isn't how that process is supposed to work...blah blah", that I had to remove it.
I was the sole developer on a project with at least 2 designers and 6 (yes 6) project managers... ugh. They asked for the dumbest things and I would protest a little by building it a "smart" way that wouldn't piss off the users. But I had to revert everything and try to hack my way through making their overly complex visual designs work on web 1.0 _and_ support super old versions of IE at the same time... because project managers know what users want best.
--Design alterations on the fly--
When CSS was still immature, and many layouts were very hard to build, I made some complicated things in a mapping program that insurance workers would use to map out and plan routes and such. Google maps was very new (so maybe 2006/7 ish) and we were building on top of this. And I would build layouts that I thought were ideal for users, because the client was just the business guy he left the design work up to me. And I had to rework the design a few times. Even after I had already specced everything out, and the client agreed.
The lesson here was that the client blamed me for bad design decisions based on our poor communications. I had visually laid out the entire app before building it, but because we kept redesigning the visuals, doing a visual spec for each change was overwhelming. So I just made changes sorta willy-nilly based on meetings. And the client would come back and call a design decision a "bug" so he expected me to fix it for free... ugh.
--Verbal change requests--
I had a client freak out on me (he had a temper and I was young and didn't have courage) claiming I had "told him to do X & Y" on a phone meeting 6 months prior. And therefore I was on the hook to fix it for free. I don't even recall what it was, but I remember the verbal bashing I got.
This is where I learned to stand up for myself in a mature manner. I told him I don't recall saying that, and that I make a point to only make changes like he was describing in writing. And I pointed out that it was unfair and unreasonable to expect me to remember what I said on a phone call last month, let alone 6 months ago. And this is one the reasons I get do changes like this in writing, to avoid these exact conflicts.
He was angry, and I weathered the storm, but it was a valuable lesson. Not everyone is nice and reasonable, but you may have to work with some people this for a time. And having a good set of communication and process rules keeps you from getting blamed for something that isn't your fault.
This is getting long, but I didn't mean to imply "support" was some huge on-going thing for some giant feature I had spent days on. But more edge cases that the OP was bringing up, but seriously impacted my motivation on the work and affected my relationship with the client.
If it's a large corporation with no relationships possible (ie, this is a hard learned lesson in itself), I'd likely want as much in writing as possible.
If you are working with a small shop with people you know well, maybe it doesn't matter so much?
> focus on building a few key features extremely well.
This. You nailed it.
To Microsoft, minimalism means:
Rebuild a popular piece of software from scratch
Release the NEW improved shiny app that follows a new design fad. Gloss over the fact that it's unreliable, slower, more crash prone & lacks over 50% of the old apps features by promising fix the 'issues' and missing features with future updates.
Retire the old but fully featured (still working) app while the new stuff still lacks basic functionality.
Retire this NEW stuff when it's still lacking promised features. And replace it something that lacks even more features.
Windows 10's attempts at minimalism means that a feature you rely on today might be gone forever with the next update or hidden - requiring a treasure hunt.
There's just one app that MS didn't screw up by going minimal -- OneNote. I still can't figure out the Win32 version. The store version just clicks for me. They once included an excellent RADIAL Menu for OneNote but removed it inexplicably.
(Radial Menu of OneNOte https://www.youtube.com/watch?v=Job4Rg-sbDo)
*
Developers pursing minimalism tend to release software that:
Require too many steps to accomplish simple tasks because controls are HIDDEN away behind hamburger menus and/or frustrating gestures. Example - windows 8's charm bar that required moving the mouse off screen to the top right corner to reveal the settings menu.
Have too much white space - and have tiny text (self explanatory)
Replace intuitive, native, user friendly controls with a Minimal but frustrating version - example removing the Underline of hyperlinks in webpages, even changing the mouse icon on hover. Sometimes, links and normal texts are indistinguishable. Another example super tiny (or hidden) scroll bars
Going mobile only - even when the site / service doesn't use any mobile only features.
Mobile first - Mobile first and minimalism are often mentioned together and is an excuse to release featureless but bloated websites or apps.
Small case in point - the search bar in Excel 365. Until recently it was a text box next to a magnifying glass, and you could type into it.
Now it's just a magnifying glass. You have to click on it to reveal the text box. Only then can you type your search term.
This change produces absolutely no user benefit. There is no rational reason to add an extra click. Long-term users now have to go through "Wait, what...?", where previously muscle memory would just work.
Another example: the AutoSave switch in Office 365. Users quite understandably assume that "AutoSave" means the file is saved automatically.
In fact this is a OneDrive-only form of AutoSave. AutoRecover - a different and much older local drive auto-save feature - is unrelated, and has a separate setting in Preferences.
Providing a minimal switch in the UI which doesn't mention the distinction is guaranteed to confuse anyone who doesn't already understand the difference - especially when clicking the switch tells you AutoSave isn't available because of your privacy settings, and doesn't mention OneDrive at all.
Now? I see things differently. I look at the problem and evaluate existing solutions. 90% of the time, there's a battle-tested open-source (or cheap) solution which fits our requirements that I can quickly integrate without burning piles of company cash building and supporting my custom crap. Yes, it's not minimalist. But it's overwhelmingly a better decision most of the time.
(Mind, I suspect one's experience is highly dependent on the developer ecosystem one is in. Just my 2c.)
We use Heroku instead of a custom AWS setup We use Sentry instead of a hand rolled exception tracking system We use Postgres instead of a custom
We are minimalist in the sense that we minimize the code we have to maintain in house.
It would be ideal if you could start with the tactic the article advocates and then easily switch from a stripped down custom approach to a more common denominator standard approach exactly when it begins to have better ROI. But in the real world, switching costs are high, ROI is impossible to measure perfectly, and there are other variables that matter a lot (like your future employees' familiarity with tools). My personal preference is in line with the article's suggestion - I strongly prefer building little purpose built things to reading documentation for and hacking around inconvenient parts of standard tools - but I tend to think it makes better business sense to go with the standard tools for things that aren't directly in your project's core competency.
Should one build their own database? Probably not. That introduces more complexity.
What about an npm package to pad strings? It's simpler to write that logic than to deal with one more dependency.
Giving two extreme examples to illustrate that "minimalism" may not be a useful criteria.
So seems like we're in agreement :)
What pushed me back was the current JavaScript landscape, with endless breaking changes to the major UI frameworks and constant security vulnerabilities being reported in our code bases by GitHub (they're even doing auto pull requests now).
In my experience, updating any decently sized web app project is a huge pain, and very time consuming. Everything is constantly moving. Libraries, frameworks, build tools, node, etc etc. These are all dependencies.
There is extremely bloated software that can be replaced by a few lines of code but, in general, minimalism is hard to get right and requires a high level of expertise.
Some of the transition from rolling your own to just using something else probably comes naturally from gaining sway over a project to the point that you can actually make the call to import a new package.
How often are breaking changes introduced to the APIs of OpenBLAS or LAPACK? I would guess approximately never (I could be wrong though. I'm actually surprised and a bit disturbed how much activity the GitHub repos are still getting).
Beyond that, how much of the API do you need, or are likely to need in the future? Why not implement that matrix multiplication yourself to start, but abstracted in a way where you can drop in OpenBLAS in the future? You can even copy their API if you don't want to abstract, and include a bit of profiling to warn you if it suddenly gets very slow on a certain platform.
In my experience the chances are good you'll never need that last 20%.
Often these systems grow according to that greedy approach, sprouting a feature here and there as sales tells the team to add things, and then you're left with a system that was more grown than designed.
Minimalism without sacrafice in performance
Look at kx.com, shakti.com
J replaced their matrix multiply with a good BLAS-based implementation a few years ago but only supports double-precision floats and tends to be slower than Dyalog for other operations. I don't know about K's performance.
I agree with you -- that's why I think clean code is less important than clear boundaries. All that messy code for matrix multiplication poses a lot less risk for consumers of it when the API is clear. eg. Pass in a 2D array of integers, receive an integer in return.
That's pretty obvious for me to say, I think, but you run into situations where an app, for some reason or another (the main culprit IMO being Not-invented-here-syndrome), couples code like these matrix calculations to constructs unique to the codebase (objects, database structure). That's when it turns to hell.
Those projects are organized around one monolithic package of code that could be broken out into there separate libs and composed together in novel ways.
A GUI is just the set of default compositions an opinionated team felt would connect best with an abstract perfect customer in mind.
Each chunk of code could be managed then by smaller teams, and the inputs/output spec more easily understood by all.
Unix composability at scale is what the web and devops has been peddling philosophically, IMO.
Lots of people like the desktop metaphor. Personally more of a “computer is a text editor I use to compose interesting outputs”.
At a previous employer (whom I cannot talk about), we were working on an ASIC. The ASIC team was new, brought in for the job, and was eager to include every possible feature that stakeholders wanted. The stakeholders seem to view this as a "its my birthday" kind of scenario, and so asked for lots of features (it wasn't going to cost them anything, after all). We had one senior hardware engineer, who was not on this ASIC team that was asked to sit in on meetings, and he was the "no" man. Somebody would request a feature, and he'd sketch out on the whiteboard what it would cost in chip area, power, and verification time. The ASIC was delivered more or less on time, and was wildly successful (I think, I'd left the company by this time). If it wasn't for this "no" man, I think they'd still be trying to verify all the features other teams had asked for.
I never worked at Intel, and I don't know the inside story, but I'm guessing the same thing happened with their server NICs. The original 10G and its respin (82598, 82599) were simply brilliant in their simplicity, and they were one of the first full speed 10G NICs in terms of packet rate. Flash forward to the 40g / 10g xl7xxx series, where you have a kitchen sink worth of features, and the host has to do crazy things to deal with limitations in a basic core feature of an ethernet NIC (no more than 8 DMA s/g segs per emitted TSO packet). Flash forward again to the 100g columbiaville, which seems to be more of the same -- with the same TSO bug!
Or __i40e_chk_linearize in the Linux i40e driver: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
And their 100g NIC has the same bug (at least according to the FreeBSD driver that's in review now).
ARGH!
I'm so fed up that my new year's resolution is to make a new NIC that's like the 82599 but more so.
When I was young, I used to scoff when old programmers told me not to include external/3rd-party libraries. What did they know, these libs are so convenient! Today, I clearly see the downside of doing that and the slippery slope that it introduces.
Rather than do the hard work myself upfront and pay that cost, I let someone else do it for me and simply included their work. Great, right? Not really. Now, I'm at their mercy. They break things all the time, don't address security issues, abandon the code I rely on, don't support OpenBSD armv7 (or whatever you run on), etc.
Now, I'm much older and only include when there is absolutely no other way (very rarely).
That's me. I also avoid plug ins in things like our bug tracker and build system. I'm the person that maintains our Redmine and Jenkins machines and over the years I've gotten lots of requests for plug-ins that do pretty neat things. I almost always refuse just because it makes updating such a pain in the ass.
Generally, I do as little custom configuration as I possibly can these days. Twenty-five years ago customizing Enlightenment was how I spent about 30% of my time at the computer.
On the reverse when I own a project, dependencies are kept to the minimum, often code I own too.
This stuff was supposed to make our lives easier...
That said, there is some interesting nuance I am starting to see in various communities. For instance, in .NET land, the Newtonsoft.Json library is extremely popular and was eventually scooped up into the official Microsoft API (and then further enhanced performance-wise). As a result, we had a clean migration path from a 3rd party library to the 1st party's API implementation of the same functionality. This is the most ideal situation from my perspective, and I would really like to see more of this.
Perhaps a new system from various vendors where a 3rd party library author can apply for 1st party sponsorship and/or certification of their library. Since Microsoft owns GitHub now, this could be something they consider integrating directly into the product. GitHub already has quite a few features that could help to support such capabilities (I.e. static code analyzers, action pipelines, etc). Additionally, if you are using a CLR language like C#, exceptionally powerful tools like Roslyn are available.
I realize this may create certain perverse incentives, but seeing a "Certified by Microsoft" or similar label affixed to a GitHub repository would give me a substantial boost in confidence when using this author's library. This would also serve as an excellent canary (i.e. if this status is revoked based on malicious activity, too many incidents, lack of maintenance, etc.).
If you can account for all the problems with the basic functionality the original big library tried to solve, this might work. But, if you're rediscovering all the problems again, and trying to solve them again, it's probably not the best use of your time.
Further, if something is big enough to become a norm (like Disqus for comments) - creating yet another sign-up form for comments has enough friction to discourage at least me from commenting. (And the one on this blog is broken).
I'm not saying your approach is wrong, but there's pros and cons to both, which don't seem to be captured here.
This "everything sucks (from my myopic viewpont)" thing is like a bizarre form of learned helplessness. And I say that as someone who complains a lot about the quality of tools and libraries. Only about 10% of the time do I think that means we should write our own. 40% we should pick a different tool, and half the time we should try to convince the author to fix the worst aspects (when the problem is deeper than a PR can address).
Code you wrote is easier to understand for you. Of course you're going to be more productive with your code but what about everybody else? Are you making any compromises for the comprehension of others? Do you remember nothing about middle- and high-school coaches complaining about 'ball hogs'?
The optimists think all of their code is amazing and bug free and hence cheap. But it costs everyone else time, respect (either for you, or themselves), but perhaps most importantly, resume material and independent support options. You are hijacking the project to fluff your own ego.
For me, the worst quartile of my jobs have been NIH that turned into codependent bullshit drama, and it causes a pretty intense histamine reaction (as is evidenced in my phrasing in this comment) for me with people who are not self-aware enough to allow at least the possibility that maybe 50 people who have been thinking hard about a problem for five years are better equipped to solve it than you can in a week of bravado, followed by months or years of dodging responsibility for the problems you created by substituting your judgement for the rest of the team and the entire Internet. Just get over yourself and be a team player for once in your miserable narcissistic life.
Certainly, though, it's disastrous to assume that some existing library/product/whatever is going to be superior to home-grown, just because a lot of people use it, there's a big company behind it, or etc. That piece of software was written to cover a certain area of design and business space, and that may not intersect very well with the design and business space you need covered.
For myself, I do start with the hope that I'll be able to avoid writing some big chunk of code (by using some existing piece of software). But I'm very wary, as external software comes with costs, even if it's "free".
I joined on the brink of this decision i.e. moving to ginkgo. I was the first and only person to ask what does ginkgo do that "go test" does not for us? Nobody could really answer that.
Turns out, much like myself, and most engineers who weren't Googlers at the time, didn't really know golang and its environment. They all kinda assumed that like any other popular language, esp. for system programming (like C++) golang in its infancy requires a test framework supplement.
Well, no it doesn't. "go test" is standard which if we're lucky, means we never have to re-write tests 10-20 years down the line because it's the standard.
Part of the value-prop for Ginkgo is that it gives you a standard BDD DSL which if you're doing BDD is half the battle... describing and testing the behavior with a human-friendly programmatic interface.
On the other hand if none of the team could articulate why they needed Ginkgo that probably means they don't actually know what BDD and your point still stands.
Sounds like it was dismissed without evaluation, your comments seem to support this, you seem to think it offers little or nothing over Go’s standard bare-bones testing.
Ginkgo doesn’t re-invent the wheel regarding Go’s out-of-the-box testing, it builds upon it. Ginkgo tests run just fine with ‘go test’, except the output is a little less detailed/pretty. And you can still use standard Go tests alongside Ginkgo, they play just fine together.
Go’s OOTB test story is pretty good. But one cannot easily have hierarchically structured tests, the output doesn’t clearly describe what a failed test was testing, one cannot easily enable/disable whole sections of tests (while getting reminders that tests are ‘pending’ so one doesn’t forget about them later), randomised test ordering, clean/easy before(after test methods. And those are just the features I use, from the top of my head — it does much more.
And Ginkgo is usually paired/installed with Gomega. Assertions written with Gomega are very easy/nice to read, no matter what kinds of values one is checking, and Gomega also includes all manner of helpers for assertions and matchers.
Go’s OOTB testing is pretty good. But eventually one will realise that one is re-inventing wheels when writing yet another bunch of testing helper funcs — then the path either leads to building one’s own library of helpers, or realising that someone has already done a good job of this already.
I’ve been programming Go for a few years now. For some smaller projects, I just use the standard testing stuff, but for others I can write more readable tests, test more thoroughly, and write such tests in much less time when I use Ginkgo and Gomega.
Does it really?
But golang tooling is often simple and "good enough", which IMO is sometimes the best option available :)
Never underestimate "good enough" - it's good enough :D (But don't try to explain that to someone you're dating, LOL)
To be fair, one of those I introduced, because the oldest one we were using was demonstrably broken and prone to human error. I followed it up by shopping it around and getting others on board. One guy I deputized got a promotion in part from finishing what I started. The old one is just barely hanging around due to inertia and fear of breaking changes, but the coverage (% of overall, and I'm pretty sure LoC as well) continues to dwindle.
These guys picked a new one and then did nothing. Never talked about it, never pitched it to anybody, just forked our testing process. If that was the biggest problem with this code I'd just roll up my sleeves and fix it, but they broke so many other rules too - ours and ecosystem rules - that this is the least of the problems with the code. I might get around to looking at it in six months. I've been working on it for three months already.
In an ideal world, we should be focusing only on our core business, not the tooling around the product. OK, you just set up a hook for your error events in your front-end code that lets you collect the errors as events but Sentry is doing much more than that. If it is the only feature that you need, that's OK but the reality is that as your application code grows, you will need many more features for your error tracking.
Eventually, you will need the UIs that lets you understand the context of the user, aggregate multiple events as one exception, send the errors to the relevant people, etc. and you will spend much more time building out these features and the switching cost to a real error tracking tool will be much higher.
The tools such as Sentry and Google Analytics provide an opinionated way to accomplish specific set of tasks for typical use-cases. The advantage is that they have seen many customers, use-cases and edge cases so adopted their product in order to cover them all. You don't need to the same unless it's your core business.
Sometimes I don't know how to solve my problems with tiny amounts of code. It often takes skill and effort to come up with an elegant solution. But I agree it is something we should try to do when we can.
Friendly amendment: This has been attributed as being originally from Blaise Pascal in 1656 [0]
* I get better at writing code. * Better understanding of the problem, the feedback from the first iteration usually tells me what the code actually had to do, not what my boss thought it needed to do. * A working but messy and bloated first iteration shows me that I can solve the problem at all, the rewrite let's me do it with some grace.
The hard part is minimizing the time spent on the first messy implementation so more work can go into the good final iteration.
Happy holidays!
https://volument.com/blog/minimalism-the-most-undervalued-de...
... but what you want is:
https://volument.com/blog/minimalism-the-most-undervalued-de...
Two things suggest you've still got some work to do cutting out the crap:
1. The commenting widget manages to foil my ability to select text and keep it selected.
2. If I disable JS (see #1) and reload the page, I just see one big blob of gray-green-blue.
This applies to everything I've worked on, from personal projects up to 10KLOC to 3MLOC commercial systems. It's just never a good idea from my experience.
The code [0] I write these days tends to be pretty raw, but every single line fills a fundamental purpose.
When I spend a lot of time building potential future features or creating a bunch of abstractions, I pretty much always never end up using any of them and it ends up as a (potentially huge) waste of time.
When I'm building something and thinking about whether or not to make it more abstract / support potential future features, and decide "nah, ain't gonna need it", inevitably within a week or month I get some feature requests for those exact things, often requiring me to do a lot of rewriting from the ground up which I wouldn't have otherwise needed to do if I had started off with a more abstract model or added those features when I was initially considering them.
(Obviously this isn't literally always true, and I'm getting better at it over time, but those are the ones that stick out.)
There is minimalism and there is punting the issue down the line, and this is an example of the latter.
The article kinda uses a language of a sentiment I share to an extent (I think most devs are far too eager to pull dependencies — avoiding NIH doesn't mean you have to pull the entire 3rd party dependency, not if you can read a paper and implement it in a dozen lines), but while a completely in-house analytics package could be smaller, there's a reason why commercial packages are big.
But are those reasons your reasons, and do some of them warrant questioning in the first place?
Bugs should not be a reason to give up rolling your own stuff, but I'm sure you didn't mean it that way.
Thank you for reporting this issue!
Ah, but what's really discussed in the article is speed
How fast a page loads. How quickly a tool can be understood. How quickly a tool can be used.
How quickly the user can understand the product. How quickly they can figure out what they're doing wrong.
Speed is the one true killer app.
It's one of the few things that, when it's better than user expectations, will illicit stunned vocalizations of "bullshit, do it again. Oh shit, it's really that fast" from nearly everyone.
https://volument.com/blog/spa-the-biggest-website-performanc...
https://volument.com/blog/spa-the-biggest-website-performanc...
Wrote my own dirt simple lazy loader & slider libraries, because I didn't need many of the features other libs had.
On the flip side, if I need a reasonably complex component that would take quite a while for me to implement, like say. A date picker. I just grab the lightest weight, good looking one that I can find. (That also doesn't appear to be abandoned)
Minimalism in everything, even minimalism.
There's an old quote I can't remember the exact source of, that "Microsoft Word users only use 5% of its features... but each user uses a different 5%."
It's not bloated. It's just that other users have different needs from yours, and you're ignoring other users, assuming they're the same as you. But they're not.
It's easy to write a minimal version that works on your dev machine in your browser. But now get it to work on all browsers on all devices on all OS's. And now build in all the little feature that big clients require for legitimate reasons. And now ensure it works with several legacy versions of API's, etc. Is it "bloated"? No. It does what it needs to do.
A minimal phone with just enough functionality to be useful, then an app store to get all of other functionality you need via downloadable apps.
Its a model that works well, providing an ecosystem to anyone who wishes to extend.
Code is kind of the same now.. Get the basic thing going, then people fork it, improve it, submit patches, sometimes over decades.
The worst software imho, is a closed architecture that has the kitchen sink included that nobody can extend.
Modularism and a pluggable architecture is much better than just minimalism on its own.
It’s easy to keep adding stuff (especially if your customers are requesting it) but you should evaluate if it’s truly necessary.
I think finding the optimal solution to any problem usually requires delving through a lot of crap, trial and error etc. Maybe this is why I find the trend towards minimalism a little bit condescending, if that's the right word.
Once you've done that, you might gain that foresight. It's also known as experience.
Too bad there are so many places where you're just constantly rushing to add new features on top of old stuff without ever having time to take another look at the design, fix it, and learn from it.
The argument against Entity Framework, and for micro-ORMs. - https://pknopf.com/post/2019-09-22-the-argument-against-enti...
You don’t need Cake anymore; the way to build .NET projects going forward. - https://pknopf.com/post/2019-03-10-you-dont-need-cake-anymor...
My blog is also written from scratch, using a stupid tool.
https://github.com/pauldotknopf/pauldotknopf.github.io/tree/...
I don't understand how exactly the Volument product actually performs A/B testing (or distinguishes between different variants). The only code docs [0] I've found are very, very light on details and doesn't mention how the active variant is detected. To be fair, the product hasn't launched yet so perhaps the docs are currently internal-only.
That being said, very interesting idea of linking engagement to eventual conversion to get "results" faster. It certainly seems reasonable that there is a causation relationship (increased engagement, e.g. more scrolling and longer visit duration, eventually leading to increased conversion), but I don't know how statistically valid that is.
A/B testing in Volument is quite different from, say Optimizely. You can compare a lot of things in apples-to-apples fashion: landing pages, inner pages, market segments, campaigns, site versions, etc. And you can compare both how much traction something generates, or how engaging a page is.
The causation thing is just something we measure. We measure how people behave on their first visit, how intensively they return, and how much they convert. It's not about the statistical validity, it's about choosing metrics that are essential for conversion optimization.
I get the point that having too many developers writing too much code can make it too much to handle. But I've seen what one person operating alone in a vacuum can do as well, and it is not pretty. It seems like really you want maybe 3 people to really understand some code. That gives you a good bus factor, but not so many people injecting ideas and patterns that the code becomes unwieldy. More important, it gives you extra code reviewers who can push back against bad code smell and hopefully find bugs, or at least try to test it. 1 might be better than 20, but 3 is better than 1.
- [PO] A/B testing says button must be outside table
- [DEV] But that makes the code unreliable and overcomplicates things the framework is not designed to do that, maybe if we include a regular link...
- [PO] BUT AB TESTING, ACQUISITIONS, CRITICAL MISSION, bla bla bla
Still in the 15th percentile on https://www.websitecarbon.com/website/volument-com-blog-mini... . Can it be improved?
Something in the html/CSS prevents displaying the page until it's complete (observed on Firefox on Android). You should investigate, this will provide better impact to visitors.
Is the whole web page some kind of advertisement?
Overall, I agree. Perhaps you should make clearer that you compare bytes client side, not server-side handling (e.g. for error collection).
Keep up the good work!
There's a reason most apps are complex: because the world is complex. Making software that does nothing and pretending it's as useful as real software in the name of fashion, "minimalism" is frankly unimpressive and uninteresting. There are no shortcuts in real life. No matter how good their sentry backend is, I guarantee it's not nearly as useful because they almost certainly left out the ui that makes sentry the useful tool it is.
So tired of articles about fashion.
For one of my hobbies I have a little speech about how you could get started with only 5 specific tools. And the punchline of that story is that it's actually 4 tools + 1 duplicate. Because the 4 are that useful on their own, and one of them wears out much faster than the rest.
The classic example of this is Word which started out as a small clone of Bravo but kept adding features that some subset of customers found indispensable until the whole codebase and UI became a mudball.
I don’t really like MS software but a big part of the reason is a consequence of something I admire: their strong attempts at backward compatibility and preserving features that are actually used even if by a small minority. In other words: you can’t win.
Or there's an address widget you used, but it kept being updated because even though you only serve the USA, other sites need support for various foreign countries...
I don't want to write everything, but sometimes indeed these 3P packages are a moment of convenience leading to a lifetime of regret.
I tend to be very stubborn about adding features to libraries, though. A handful of times I got pull requests that almost duplicated the size of small libraries just to cover some weird corner cases. One was support for an ORM discontinued since 2012. Another was someone who wanted a build tool to inline their assets during development phase. After asking, most people admitted that they don't really need the feature, but were simply trying to make the app complete.
We use senrty and we rely on many of the features you miss out on by just posting minimal exception information.
Religion implies dogma, and I don't like dogma in my field.
Side note: the biggest takeaway for me here is: be careful when writing such self-confident articles. The general public doesn't take kindly to such displays.
For a moment I thought this was about real life minimalism.
A few months ago I wanted to add an issue reporter to the help page of our open source genetics data visualization tool https://bam.iobio.io. I threw something together in less than 100 lines of code [1]. It doesn't even include any rate limiting or security measures. A couple weeks back I ran into a slight wrinkle that brought into question whether to keep using the tracker. I quickly analyzed the number of issues that had been submitted (including a recent influx of layman users), and simply removed it. Email support works fine for us based on our usage data. The decision was made easier because I didn't invest a bunch of time up front integrating with some external service, or building a 100% solution the first time around.
> It certainly didn't help, that our former A/B testing tool emphasized short-term wins. When we added a huge sales overlay, it appeared to bring more conversions — since the return visitors were ready to take action. The new visitors probably hit the back button as soon as they arrived.
This is great. All of your analytics insights are completely dependent on a) measuring the right thing and b) interpreting it correctly over the long term.
EDIT:
I do want to mention that these articles always point out downloaded code size as a primary factor in the decision, but I rarely see any data showing how the reduction in code size translates into an improved user experience, based on the principles of human perception. In my experience, the really big gains come from techniques like background fetching.
Not that code size isn't important, but I think the main point should be the reduction in complexity that comes with it. That pays dividends in developer time and avoiding bugs, which translates directly to an improved user experience.
Size is a huge factor when you're on a limited data plan. Maybe one website won't make a difference, but it adds up.
It appears to be because the BODY element has a CSS rule setting "opacity: 0", which appears to be for the purpose of enabling a CSS transition to fade in the page on load. Not exactly minimalism in terms of complexity, but it does appear minimalist in terms of content when the page is blank. :P
Presumably the transition is triggered by some JavaScript. However, that JavaScript fails to execute because cookies are disabled, which causes an error:
Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
at new u (https://volument.com/v1/volument.js:17:858)
at window.volument (https://volument.com/v1/volument.js:17:133)
at https://volument.com/global/index.js?b:1:14673
at https://volument.com/global/index.js?b:1:60085
As a result, when cookies are disabled and JavaScript is enabled, the page appears blank.If I had a dollar for every time nowadays that I see a blank Web page because of invisible-by-default content that's made visible by JavaScript that fails to execute because it can't handle blocked cookies...
I guess the author should have made a minimalist static HTML page instead.