Skip to content
ModernUI A DaneTrades developer library

Performance Best Practices

Use these rules when building real EA and indicator panels with ModernUI.

1. Keep the lifecycle correct

Every ModernUI EA should forward timer and chart events.

Reference excerpt
void OnTimer()
{
  g_ui.OnTimer();
}

void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
  g_ui.OnChartEvent(id,lparam,dparam,sparam);
}

void OnDeinit(const int reason)
{
  g_ui.Shutdown();
}

A panel cannot be responsive if the root does not receive events and timer updates.

2. Do not relayout for paint-only changes

Use Refresh() for visual changes. Use Relayout() for geometry changes.

Change Prefer
colour change Refresh() on the control
status text update Refresh() or a control setter
hover/press state RefreshArea(...) if the area is known
new child added Relayout()
padding/font/row-height change Relayout()
theme/scale change root-level layout/paint update

3. Prefer a targeted refresh when safe

If only one stable control changed, refresh only that control.

UI build fragment
if(statusLabel!=NULL)
{
  statusLabel.Text("Updated");
  statusLabel.Refresh();
}

Use RefreshAll() only when the area that changed is unclear.

4. Do not refresh twice after a layout

This is usually unnecessary:

Incorrect
panel.Relayout();
g_ui.RefreshAll();

Prefer:

Correct
panel.Relayout();

Relayout() already schedules the redraw it needs.

5. Keep row binding cheap

For virtualized lists and tables, binding code can run often.

Avoid expensive work in:

  • BindRow
  • CellText
  • sorting callbacks
  • high-frequency selection updates

Cache formatted strings when they do not change.

6. Reset every field in recycled rows

Virtualized rows are reused.

In BindRow, reset all visible row fields:

  • primary text
  • secondary text
  • meta text
  • badges
  • icons
  • colours
  • visibility
  • enabled/disabled state

Do not rely on the row’s previous state.

7. Use the right data control

Data size / need Use
Small string list Mui::ListBox
Small string table Mui::SimpleTable
Large dynamic list MuiListView with custom source
Large dynamic table MuiTableView with custom source
Hierarchy MuiTreeView

Do not use a simple helper for a large dynamic dataset if a source-backed virtualized control is the right tool.

8. Avoid rebuilding UI trees unnecessarily

Prefer updating existing controls.

Better:

UI build fragment
if(label!=NULL)
  label.Text("Connected");

Worse:

Incorrect
// Rebuilding the whole panel every time a status value changes.
BuildFullPanelAgain();

9. Keep native text hosts stable

Text boxes and text areas are heavier than labels and buttons.

Use them where real editing is needed, but avoid constantly destroying and recreating them.

Always call g_ui.Shutdown() in OnDeinit.

10. Use performance counters during testing

Enable stats only when you need them.

UI build fragment
g_ui.PerfStatsEnabled(true);
Print(g_ui.PerfStatsSummary());

Watch for:

  • lost input events under heavy traffic (sometimes called event queue drops)
  • unexpected full repaint count
  • high paint durations during simple interactions
  • repeated layout passes while scrolling

11. Test on a real chart

Always test on:

  • a normal chart
  • a resized chart
  • your target dark/light chart template
  • the Windows/VPS display scale your customers use
  • a chart with other common objects if your users often have them

12. Keep trade panels compact

For trade-manager-style panels:

  • avoid huge dashboards
  • show only the controls needed for the task
  • use status rows for simple states
  • use toasts for short feedback
  • keep confirmation UI clear
  • separate UI from trading execution logic

13. Keep icon assets cached

Built-in atlas icons are small and are loaded lazily from Images/ModernUI. Do not load, decode, or recolour custom image files on every paint.

For custom image features, prefer a cache-by-path model: load once, reuse many times, and fall back gracefully when a file is missing.

Common mistakes

Calling Relayout() from high-frequency handlers

Slider drag, hover, and mouse move paths should avoid layout churn unless geometry truly changed.

Formatting table strings repeatedly

If the value does not change often, pre-format it.

Ignoring MT5 limitations

ModernUI is a serious MT5 UI layer, not a browser or native Windows toolkit.

Related pages