Currently, as soon as a flow graph is deserialized, its units are “defined”, which means the code in the Definition method runs to create the required port objects based on the settings and the codebase. This is necessary because of the order of deserialization: because ports are not serialized, connections cannot be deserialized until the ports are created. Thus, definition has to run during deserialization, after units and before connections.

In a lot of cases, definition implies reflection. For example, an Invoke Member unit will reflect its deserialized data to find a matching MethodInfo, then analyze this MethodInfo to determine which input ports to create based on the parameters of the method.

While this has yet to be benchmarked to evaluate its impact, we know that reflection -- especially member fetching -- is slow, and that may be a cause of the initialization delay.

The problem is dual:

The proposed changes are:

  1. Rework the deserialization routine so that connections can be deserialized without ports
  2. Remove Define from the deserialization routine
  3. Add an Initialize method to graphs and graph elements that calls Define for units
  4. Add an initialized boolean and an EnsureInitialized method
  5. Determine cases where initialization needs to be ensured and call EnsureInitialized:
  6. Initialize individual graph elements after they get added to a graph from the editor