It's also complexity - added more than necessary, and @ a faster pace than hardware can keep up with.
Take font rendering: in early machines, fonts were small bitmaps (often 8x8 pixels, 1 bit/pixel), hardcoded in ROM. As screen resolutions grew (and varied between devices), OSes stored fonts in different sizes. Later: scalable fonts, chosen from a selection of styles / font families, rendered to sub-pixel accuracy, sub-pixel configuration adjustable to match hw construction of the display panel.
Yeah this is very flexible & can produce good looking fonts (if set up correctly). Which scale nicely when zooming in or out.
But it also makes rendering each single character a lot more complex. And thus eats a lot more cpu, RAM & storage than 8x8 fixed size, 1bpp font.
Or the must-insert-network-request-everywhere bs. No, I don't need search engine to start searching & provide suggestions after I've typed 1 character & didn't hit "search" yet.
There are many examples like the above, I won't elaborate.
Some of that complexity is necessary. Some of it isn't, but lightweight & very useful. But much of it is just a pile of unneeded crap of dubious usefulness (if any).
Imho, software development really should return to 1st principles. Start with a minimum viable product, that only has the absolute necessary functionality relevant to end-users. Don't even bother to include anything other than the absolute minimum. Optimise the heck out of that, and presto: v1.0 is done. Go from there.