Performance & Batching
In high-density maps or applications with frequent updates (like real-time tracking or interactive drawing), updating the map for every single model change can lead to "layout thrashing" and UI lag.
AurOpenlayers solves this using a built-in Scheduler. Instead of pushing changes immediately to the OpenLayers engine, the framework batches updates and "flushes" them to the map according to a specific policy.
Understanding Flush Policies
The framework supports two primary FlushPolicy strategies to control when the map re-renders:
microtask: Updates are applied at the end of the current JavaScript execution cycle. This is the fastest update cycle, ensuring changes appear as soon as possible without waiting for the next animation frame.raf(Request Animation Frame): Updates are synchronized with the browser's refresh rate (typically 60fps). This is the gold standard for visual smoothness, especially during animations or drag operations.
How to Batch Manual Updates
If you need to perform multiple operations—such as updating several models at once or changing styles across different layers—you should wrap them in a batch call. This ensures the map only recalculates geometries and styles once at the end of the block.
Step 1: Access the Map Context
When the map is ready, you receive a MapContext instance via the (ready) event on the mff-map-host.
onReady(ctx: MapContext): void {
this.mapContext = ctx;
}
Step 2: Wrap Logic in a Batch
Use the ctx.batch() method to group your updates.
updateAllPoints(): void {
this.mapContext.batch(() => {
// These multiple calls will only trigger ONE map refresh
this.pointLayerApi.addModels(newPoints);
this.routeLayerApi.removeModelsById(['old-route-1']);
this.pointLayerApi.updateModel(selectedPoint);
}, { policy: 'raf' }); // Optional: force RAF for smooth visual transition
}
Optimizing Interactive Drag & Modify
One of the most performance-intensive tasks is updating a model while the user is dragging a feature on the map. By default, the framework handles this, but you can optimize how your business logic reacts to these changes.
Step-by-Step: Smooth Dragging Implementation
- Use the
translateinteraction in your layer descriptor. - Apply a state (like
'DRAG') to simplify style recalculations. - Handle the changes in
onModelsChanged.
// In your VectorLayerDescriptor
interactions: {
translate: {
state: 'DRAG', // Automatically applies 'DRAG' style state while moving
onStart: () => {
// Optional: Trigger NgZone.run if you need to update Angular UI
return true;
}
}
}
By using the state: 'DRAG', the framework uses optimized internal paths to swap styles without triggering a full layer re-parse.
Global Configuration
You can define the default performance behavior in your MapSchema options. This sets the baseline for all layers unless overridden locally.
readonly mapConfig: MapHostConfig = {
schema: {
// Global options for the scheduler
options: {
// Use 'raf' globally if your app is highly interactive/animated
// Use 'microtask' if data integrity and immediate feedback are higher priority
defaultFlushPolicy: 'raf'
},
layers: [ /* ... */ ]
}
};
Summary of Best Practices
| Scenario | Recommended Policy | Why? |
| :--- | :--- | :--- |
| Initial Data Load | microtask | Gets data on the screen as fast as possible. |
| Animation / Interpolation | raf | Matches screen refresh rate for stutter-free movement. |
| User Dragging (Translate) | raf | Prevents the logic from outrunning the visual cursor position. |
| Bulk Style Changes | microtask | Ensures all elements change appearance simultaneously. |
Pro-Tip: Immutable Updates
The scheduler is most effective when you treat your models as immutable. When updating a model, always return a new object reference. This allows the framework to quickly "hit-test" which features actually changed and skip re-rendering those that didn't.