Debugging & Performance
Step-by-step checklists to diagnose and fix slow UI loading, unresponsive pages, and NetLogic bottlenecks in FTOptix projects.
Work through each phase in order. Every check below links directly to the source that supports it. Critical checks are the highest-impact items first.
0 / 0 items checked (0%)
Phase 1
0 / 0 checked
Baseline and scope
-
Scan runtime logs for the 2000 ms Start() warning Find every
Start method on <NodeName> took too long to execute...message and list the node names. This warning is an explicit startup bottleneck indicator. Source: 2-second Start() warning -
Record project-level node count from Project Information Use Tools -> Project Information and store the total node count as your baseline before changing the project. Source: Project Information
-
Measure node count on the affected page with Nodes Counter Dialog Add and bind Nodes Counter Dialog to the problematic page or loader target, then capture the runtime node count for that specific page. Nodes Counter Dialog docs
-
Document baseline startup and page-load times before tuning Capture timing before and after changes so optimizations are evidence-based and reversible. Source: Performance optimization
Phase 2 · Critical
0 / 0 checked
Start()/Stop() lifecycle on behavior thread
All
Start() calls are sequential on the behavior/core thread. One slow Start() delays all later behaviors in the queue.
-
Assume Start() is serialized and remove blocking work from it Review each
Start()for file I/O, DB/network calls, long loops, synchronous waits, and sleeps. Any of these blocks the behavior thread. Source: Start() lifecycle -
Offload heavy initialization to LongRunningTask Keep
Start()fast: register observers/state immediately, then launch heavy setup in a background FT Optix task. Source: Avoid cascading Start() delays -
Do not modify page tree in Runtime Start() Runtime NetLogic
Start()should not add/remove nodes from the page tree. If needed, restructure at type level or defer safely. Source: Runtime Start() warning -
Validate Start()/Stop() order assumptions Startup order is deeper-first on the behavior tree; shutdown is reverse order. Do not rely on same-depth execution for deterministic behavior. Source: Execution order
-
Dispose observers and tasks in Stop() Dispose
LongRunningTask,PeriodicTask, and observers inStop()to prevent leaks and stale background activity. Source: Stop() lifecycle
Phase 3 · Critical
0 / 0 checked
ExportMethod and caller thread
[ExportMethod] runs on the thread that called it. UI-triggered methods run on UI thread and must return quickly.
-
List every UI-triggered ExportMethod and enforce fast return Any button-click method with blocking work will freeze UI. Start a background task and return immediately. Source: ExportMethod execution
-
Verify caller context for non-UI ExportMethods When called by Start(), LongRunningTask, or PeriodicTask, method execution follows that caller thread. Audit for thread-safe assumptions. Source: Trigger to thread mapping
-
Protect shared C# objects accessed from multiple task threads If multiple threads touch plain C# state, use synchronization (for example a lock) to avoid races. Source: ExportMethod thread safety
-
Use FT Optix task types for node access, not native async/await Use
LongRunningTask,PeriodicTask, orDelayedTaskfor operations touching project nodes. Source: Async tasks and their threads
Phase 4 · Critical
0 / 0 checked
Node count and model complexity
Model complexity and node count are primary drivers of runtime performance and page load latency.
-
Count DynamicLinks and identify complex converters A basic DynamicLink adds at least +3 nodes in the object-type example table; complex links are heavier. Audit count and necessity, not only function. Source: Optimize object structure node impact
-
Limit Complex DynamicLinks and centralize transforms Where possible, replace repeated Complex DynamicLinks with centralized script processing and then expose simple links to consumers. Source: Replace complex links with centralized scripts
-
Replace design-time-only links with static values If a value does not change at runtime, keep it static and remove unnecessary dynamic infrastructure. Source: Model complexity guidance
-
Use Types/instances and minimize instance-level overrides Reduce duplicated structure and per-instance property materialization to lower node count. Source: Optimize object structure
-
Remove redundant containers and flatten deep UI hierarchies Eliminate non-functional groups/panels to reduce traversal and rendering overhead. Source: UI objects best practices
-
Prefer stylesheet-driven state when it replaces many repeated bindings Centralized style logic reduces repeated per-object property handling. Source: Stylesheets
-
Aggregate shared variables to remove repeated logic Reduce overhead by sharing transformed values across multiple objects instead of duplicating similar logic per object. Source: Overhead reduction
Phase 5
0 / 0 checked
Rendering and heavy widgets
-
Treat heavy widgets as UI-thread load Large DataGrid/Trend views can make pages feel sluggish because rendering runs on the UI thread. Source: Practical implications for complex pages
-
Prefer optimized SVGs for symbols and scalable graphics Use vector assets where suitable and keep them clean to reduce rendering overhead. Source: Graphic rendering impact
-
Compress and resize raster assets before import Keep PNG/JPG dimensions and file size aligned with actual runtime display usage. Source: Graphic rendering impact
-
Simplify complex SVG exports Remove hidden layers, unused metadata, and excessive path complexity from source drawings. Source: Graphic rendering impact
-
Use dynamic object loading for pages with many preloaded objects When pages preload many objects, load time increases; instantiate non-essential objects only when needed. Source: Dynamic object loading with NetLogic
-
Apply lazy loading to improve initial loads and page transitions Render essentials first, then instantiate additional objects while the page is already usable. Source: Lazy loading benefits
Phase 6 · Critical
0 / 0 checked
Task cadence and cleanup
Recurring tasks that overrun their period accumulate pressure and degrade responsiveness over time.
-
Ensure PeriodicTask work completes within its interval Measure execution time and increase interval or reduce workload if the task duration approaches interval length. Source: Async tasks and their threads
-
Dispose and recreate long tasks deliberately Before reusing a task field, dispose stale task instances to avoid multiple active workers on the same logic state. Source: ExportMethod LongRunningTask pattern
-
Account for Stop()/Start() overlap during page navigation Do not assume the previous page has fully completed
Stop()before the next page beginsStart(). For shared resources, release as early as possible inStop(), acquire as late as possible inStart(), and use a handoff flag when strict sequencing is required. Source: Stop() ordering during page navigation
Phase 7
0 / 0 checked
DesignTime NetLogic safety
-
Confirm no runtime UI calls target DesignTime ExportMethods DesignTime assemblies are reloaded on every call. Accidental runtime invocation creates severe and repeatable slowdowns. Source: DesignTime NetLogic and ExportMethod
-
Remember DesignTime Start() is not part of runtime startup Do not rely on DesignTime
Start()for runtime behavior, because runtime startup sequence does not invoke it. Source: DesignTime Start() behavior -
Keep blocking logic out of DesignTime ExportMethods DesignTime methods run synchronously (typically on Studio UI thread). Long operations freeze Studio until completion. Source: DesignTime ExportMethod execution model
-
Review complete FT Optix best-practices index for cross-check Use the index as a final audit to ensure no relevant optimization area was skipped. Source: FT Optix best practices index