Widgets can be managed efficiently by creating unmanaged widgets, and then using XtManageChildren. Do this instead of using XtCreateManagedWidget, or doing XtManageChild after each widget you create.
You may save considerable startup time by calling XmDropSiteStartUpdate at the beginning of the widget creation code and XmDropSiteEndUpdate when done.
Likewise, use these calls to bracket any code that causes substantial geometry management. In one demo, doing this gave a 70% improvement (from 10 seconds to 3 seconds for the operation).
Make sure you don't forget the XmDropSiteEndUpdate, otherwise your drag and drop won't work correctly.
This should only be done as a last resort, because it interferes with consistency of the application. The user is left wondering where DND works and where it does not.
However, some SGI applications have saved tens of seconds of startup time by completely turning off DND.
Avoid just bringing up the UI and then locking out the user for a long time either. Although this is slightly better than having nothing show up, it is not much better.
With proper use of polling for events and/or workproc(s), an application can generally get the time-consuming things done and still be responsive to the user.
Create UI components that will be wanted later in workproc's. If the component is already created when it is finally needed, simply mapping it on demand is very fast.
For example, creating any UI not initially needed (such as dialogs and menus) can be done in a workproc -- create them, realized and managed but unmapped, ready for mapping as needed. In most cases, if the application is careful about which order its workproc's are done, the gui item should be ready before the user actually gets around to asking for it.
The main code that brings up the dialog or menu needs to be something like:
if (already created) map it else set flag it is wanted
And the workproc code needs a section after the item is created that goes something like:
if (already needed) map it