There are generally two approaches. You can eager load the Xap files during the bootstrapping of the application or in your case after the login, since you need the user's roles, or lazy loading the Xap file when the user first tries to enter a certain module.
It sounds like the best approach for you is to load them after the login. Similarly to TempHire, where it pre-loads some data using the PreLoader, you can have a coroutine at that point with a number of Compositon.AddXap calls that load the appropriate modules based on the user's roles. You can use a parallel coroutine to load them in parallel.
On a side-note I'm going to rename Composition.AddXap to Composition.AddXapAsync. Just noticed that I forgot to add the Async postfix to this method.