Skip to content

Slow text widget #4290

@dracic

Description

@dracic

The slow text widget is still present, and i did some research, so if anyone is willing to examine this.

Detailed suggestion can be found here

Investigation Report: Slow Text Widget Performance

1. Issue Summary

Users experience significant latency (2-3 seconds) when typing in text fields (MMFormTextEditor) within the mobile application. This makes data entry unresponsive and frustrating.

2. Investigation Methodology

  • Code Path Analysis: Traced the execution flow from the QML frontend (MMFormTextEditor.qml) to the C++ backend (AttributeController.cpp).
  • Performance Profiling (Static): Analyzed the computational complexity of functions triggered during text input.
  • Web Research: Checked for known Qt/QML text rendering performance issues.

3. Root Cause Analysis

The investigation identified synchronous, heavy C++ logic execution on the main thread as the primary cause of the performance bottleneck.

3.1. The Hot Path

The following sequence occurs for every single character typed by the user:

  1. QML Input: User types a character in MMFormTextEditor.qml.
  2. Signal Emission: The textEdited signal fires immediately.
    // app/qml/form/editors/MMFormTextEditor.qml
    onTextEdited: function ( text ) {
        // ... logic ...
        root.editorValueChanged( val, val === "" )
    }
  3. C++ Invocation: editorValueChanged is bound to AttributeFormModel, which calls AttributeController::setFormValue.
  4. Heavy Recalculation: AttributeController::setFormValue updates the value and immediately calls recalculateDerivedItems.
    // app/attributes/attributecontroller.cpp
    bool AttributeController::setFormValue( const QUuid &id, QVariant value )
    {
        // ... set value ...
        recalculateDerivedItems( true, false );
        return true;
    }
  5. Global Form Re-evaluation: recalculateDerivedItems is a resource-intensive function that:
    • Iterates through all form items (not just the changed one).
    • Constructs a QgsExpressionContext.
    • Evaluates QGIS expressions for:
      • Virtual fields (recalculateVirtualFields)
      • Default values (recalculateDefaultValues)
      • Rich text widgets (recalculateRichTextWidgets)
      • Tab visibility
      • Field visibility (item->visibilityExpression())
      • Editability (item->editableExpression())
      • Field names (item->nameExpression())
      • Validation (FieldValidator::validate)

3.2. Complexity

This process is effectively O(N) where N is the number of fields and expressions in the form. Since QGIS expression parsing and evaluation can be CPU-intensive, running this full cycle synchronously on the UI thread for every keystroke causes the observed freeze.

4. Discarded Hypotheses

  • Qt Rendering/Layout Issues: While QML layout thrashing can occur, the magnitude of the delay and the direct correlation with the C++ expression logic strongly point to the backend calculation as the dominant factor. Simple text rendering in Qt Quick is generally performant enough for typing.

5. Recommendations

5.1. Immediate Fix (Recommended)

Implement Debouncing in QML:
Modify MMFormTextEditor.qml (and potentially other editors) to introduce a delay (debounce) before sending updates to the C++ backend.

  • Approach: Start a Timer (e.g., 500ms) on textEdited. Only call editorValueChanged when the timer triggers or editingFinished occurs.
  • Benefit: Reduces the frequency of recalculateDerivedItems calls from "per character" to "per burst of typing".

5.2. Long-term Optimization

  • Dependency Graph: Instead of recalculating the entire form, build a dependency graph to only re-evaluate fields that actually depend on the changed attribute.
  • Asynchronous Evaluation: Explore moving expression evaluation to a background thread, though this is architecturally complex due to QGIS/Qt threading constraints.

If this doesn't make any sense, just close it...

Metadata

Metadata

Labels

android 🤖Relates to Android app versionbugperformanceTickets related to performance issues in loading, rendering maps, syncing, etc

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions