Developer efficiency is largely driven by the number and type of decisions to make. That number can be reduced by establishing solid (but balanced) conventions.
How do you measure efficiency?
That's simple, at least in theory. It's the amount of work accomplished over time.
Great. But how to you measure work accomplished?
Probably something like progress toward the end goal, assuming you know what the end goal is. That sounds good, right?
In software development, the end goal is usually some type of launch. That's open-ended, but in theory, we're striving to put the thing we're working on out into the world.
Therefore, efficiency could be considered how much progress a dev can make toward getting their thing launch-ready. So when it comes to efficiency, there's a lot riding on how a developer spends their time.
Pause for a moment ...
There are philosophical conversations to be had here around how much we should be working. It can be a dangerous line to dance around when it comes to balancing efficiency with burnout. What I'm talking about here is not how much we work, but how efficiently we work. Or how we spend our time wisest within whatever bounds we've established (or have been established for us).
Back to our regularly-schedule programming ...
Okay, so how does a developer spend their time?
Whether or not they are writing code, most of a developer's time is spent making decisions. That's why we're programmers, right? If our job was data entry and we were spending time plugging away, we're doing something wrong. We're developers and we probably could have built a thing that could complete the entry faster than we can manually.
If a developer spends most of their time making decisions, then the way in which they can work most efficiently is by making decisions that get them closer to the end goal. Or, by making fewer decisions.
One method to reducing the number of decisions a developer has to make is through convention. I'll explain ...
When you're writing code, you either have to make a decision or you don't. I know it seems like a silly thing to think about, but it's true. You either have to decide how to name a file or you don't — you just know what the file should be named. You either have to decide where images should go or you don't — you just put them where they go.
Enter the principle of convention over configuration. I originally read about this in the Ruby on Rails doctrine, and I love it. Rails does it perfectly. It's extremely opinionated, but once you learn how it works, you can fly through the process of building applications.
Once a convention is established and you've committed it to memory, there's no need to spend brain compute cycles thinking about it. You just go. Like riding a bike, as they say.
And if you can scale that convention — follow the same process across multiple projects — anyone who knows the convention can work more efficiently.
Consider the question of where you should put images in a project. In the end, it doesn't really matter (in most cases). What matters more is that you put them in the same place every time. You make that decision once, and then you know where they go in every (similar) project you work in the future.
And if, at some point, it makes sense to move image to a new location because you've encountered an issue with your convention, then that's fine. For example, maybe your project has grown and images shouldn't be local any more, but now get uploaded to some third-party service. That's fine, as long as that can be established as the new convention.
Establishing conventions is a balancing act, like anything else. Add too much and you've restricted your developers to the point where they can't solve unique problems because the system is too rigid. Add too little and every project will be so different from the next that it'll be like learning all over again when a new developer opens up the code.
On a similar note, conventions need time to be established. It doesn't happen overnight. The first project a practice is used on doesn't represent convention. It needs time to sit, to simmer, and to be documented.
Establishing good conventions doesn't mean making every decision for developers. It means providing a platform on which they can move with ease and happiness through your codebase(s). For example, it might not mean dictating where images are hosted, but maybe only how they are named, or how they are uploaded. It all depends on the problem you're trying to solve and the people you're working with.
In the end, it takes time to get this right. There will be bumps and bruises along the way. But if you stick with it, you'll feel it come together, and eventually you'll end up with a solid set of guidelines, and you and your developers will fly!