Being permissive lowers the barrier for non CS people, one of the main target of the language, to start using the language, especially in the REPL/Notebook, even if they are not the most effective at the language.
A highly tuned kernel function can be inlined into a not so finely tuned outer function and vice versa, our metaprogramming tools see both functions the same, etc.
But since fast and slow code are so similar, and both give the same ultimate result, it becomes less obvious for someone who is reading someone's code to see what was made to make it fast (even if it's easy to see what the code does because of it's high level nature). I think that's something that could improve over time with better tooling, using the meta-capabilities of the language to create linters and compiler suggestions that guide the users into making the small changes in the code that makes the most difference.
I wouldn't say it's non-obvious: the things you have to do would be obvious to any programmer who's written code in something like C++. The problem usually tends to be that MATLAB, R, and Python tend to train people to want to use sub-optimal programming styles, like something heavy on array allocations, even if writing a function that does a loop is perfectly optimal. If someone is always told that mapping one function at a time ("vectorization") is the optimal way to do things, then they will try it when they go to a more optimal language. So it's really just a re-education issue.
Most performance tips are similar across most fast languages: minimize OS-managed allocations, use cache and SIMD friendly memory layouts, better algo design in general. I find that these optimizations are typically easier in Julia than in most languages.