zsh sources startup files in a fixed order and only some of them run in a given invocation. .zshenv is read for every shell, interactive or not, login or not. .zprofile is read only for login shells, .zshrc only for interactive shells, and .zlogin only for login shells after .zshrc. Each has a system-wide counterpart under /etc read first.
The practical rule: environment variables that non-interactive shells need, including PATH entries used by editors, cron jobs, and tools that spawn 'zsh -c', go in .zshenv. Prompt, aliases, key bindings, and completion setup go in .zshrc because a non-interactive shell should not pay for them.
On macOS there is an extra wrinkle. /etc/zprofile runs path_helper, which rebuilds PATH from /etc/paths and /etc/paths.d and moves the system directories to the front. Because .zshenv is read before /etc/zprofile for a login shell, PATH prepends made in .zshenv end up after the system paths in a login terminal. Set them in .zprofile or .zshrc if front placement matters.