Both or niether, as needed.
Cache coherency is great, but it's trivial to design cache-coherent algorithms in a vacuum ("oh, just put all the components in a big array, update them in a loop, DONE"). It's much harder to design cache-coherent algorithms that adapt to actual practical use ("oh, it turns out that this component needs to read the position, which means now we might be blowing cache coherency to read that from a different component now, or blowing it to copy it into this component earlier," et cetera).
What you want to do is design how you store your data in memory in a fashion that is efficient for the way you will access and transform that data. "Access," importantly, includes more than just how the memory will actually be fetched by the CPU, but how you will actually get at and use, connect, et cetera, that data in your APIs.
If you bend over backwards to make some components stored in a big cache-coherent array, but you never actually need to update all those components at once, have you really gained anything? Worse, if by doing so you've made it vastly more complex to use those components at the API level, have you actually improved anything?
The reason that there are no generalized, broad, great answers to this problem is that the devil is in the details. So consider the purpose of each component or other piece of data or functionality you're adding to your system, and how you want to interact with it at the API level, and how you need to interact with it at the implementation level, and weigh the pros and cons of every available approach with that in mind. And make a decision for that problem that might be different than the decision you'll make for the next.
In general, I'd aim for cache coherency when I can, as long as it doesn't sacrifice usability in any fundamental way.