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.
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.
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:
panel.Relayout();
g_ui.RefreshAll();
Prefer:
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:
BindRowCellText- 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:
if(label!=NULL)
label.Text("Connected");
Worse:
// 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.
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.