What's `nix-shell` doing while initializing?

I’ve started using nix-shell to distribute a development environment for a project. The first time someone enters nix-shell they’ll see nix downloading and building the derivation specified in nix.shell. Once that’s happened once subsequent calls to nix-shell drop you straight in the shell. This I understand.

What’s curious to me is that it takes something like 15 seconds between invoking nix-shell and getting a prompt. I’m wondering if this is typical or indicative of me doing something wrong, what nix-shell is doing in this time (shouldn’t the derivation to load already exist?). Is there anything I can do to speed this up?

The reason why it takes 15 seconds is that nix evaluates the code to find out if the derivations have changed. During the first run the derivation has changed so it will fetch/build the missing once before entering the shell. In the next runs the evaluation phase is still happening though.

One way to work around that is to point nix-shell to a .drv file. In that case no evaluation will happen and everything is loaded straight from the /nix/store. The downside is that you now have to track if any of the nix files have changed (which is not too hard if you only have a shell.nix).

See for example Nix · direnv/direnv Wiki · GitHub for a possible implementation of your own cache.