# Performance

## Minimum framerate

When rendering the scene, HOOPS Communicator will sort visible objects by projected screen size and render the largest items first. The system aims to maintain a minimum interactive framerate by interrupting the rendering and returning control to the user so that they may continue to interact with the viewer. You can set the framerate that the system will maintain by using the WebViewer.setMinimumFramerate function.

However, the increased performance gained by setting a higher minimum framerate comes at a cost. When interacting with the system, less of the scene will be rendered in order to maintain interactivity. The images below illustrate the effects of rendering the same view with different minimum framerates while flying though the model.

Interior scene rendered with minimum framerate set to 15

Interior scene rendered with minimum framerate set to 30

## Incremental updates

The scene will be incrementally rendered to preserve interactivity with large scenes. Building from the example above, when the user has stopped interacting with the model, the scene will incrementally render the remaining objects without performing a full redraw until the entire scene has been rendered. When interaction resumes, the incremental update is interrupted, and the minimum framerate is maintained again. You can enable or disable incremental updates using the WebViewer.setDisplayIncompleteFrames method.

Incremental updates are enabled by default and are useful when rendering very large models containing many parts. This feature prevents the system from producing noticeable pauses during the rendering process and allows the user to move the camera at all times.

Note

Tip: When modifying the scene during an update it can be desirable to turn off incremental updates to avoid unnecessary redraws.

## Stream cutoff scale

The default behavior of HOOPS Communicator is to cull items that appear very small in the view. The goal is to avoid spending bandwidth and rendering resources on geometry that does not significantly contribute to the current scene. The decision to cull an object using this technique is made by looking at its projected bounding diameter as a percentage of screen space. If this percentage is less than the stream cutoff value, the object is culled, and no draw call is made.

The default stream cutoff value is `0.0125`. This means that for an object to be rendered, its projected screen space bounding diameter as a percentage of screen space must be at least this value. You can tweak performance in your application by applying a scale factor to this value using the WebViewer.setStreamCutoffScale method. The value passed to this method identifies a scale clamped between 0.0 and 2.0, which will be applied to the default value. Setting the scale factor to 0 will completely disable stream cutoff culling.

The images below show the effects of setting the `streamCutoffScale` on part of an assembly. Notice the varying levels of detail around the machine housing.

StreamCutoffScale: 0 (disabled)

StreamCutoffScale: 1

StreamCutoffScale: 2

## Bounding previews

When loading very large models, it will take some time for the relevant data to be streamed from the server to the client. Bounding previews provide a visual approximation of the portions of the model that are waiting for data to arrive. The image below shows bounding previews for a partially loaded airplane model.

Bounding preview for a partially loaded model.

Refer to the documentation on Communicator.BoundingPreviewMode for details about each mode. The bounding preview mode should be set before the viewer is started.

Bounding previews can be used with the `OnDemand` loading mode to get a performance boost when working with large models. They can also be used to give context as to how the loaded portion fits into the entire context of the model. You can set OnDemand using Communicator.StreamingMode.

## Memory limit

Memory limiting allows you to exercise some control over the amount of GPU resources that are used on the client at a given time. This is useful when trying to view models with a large amount of geometry on models that have limited graphical resources. To enable memory limiting, specify the `memoryLimit` option when creating your `WebViewer` object. The following code shows an example of creating a web viewer that imposes a limit of 256 Megabytes:

    let viewer = new Communicator.WebViewer({
            container: "viewer-div",
            model: "my_big_model",
            endpointUri: "ws://mysever.com",
            memoryLimit: 256
    });

    viewer.start();

When the viewer is started, data will begin streaming as normal. If the system detects that streaming additional data to the server would put it over the limit, existing data will be ejected from the client to make room for the new, more relevant data. The order of ejection is governed by a priority queue of currently loaded meshes projected bounding info. Should the ejected data become relevant again, it will be re-streamed from the server as needed.

## Show framerate

You can enable real-time rendering statistics by using the setStatisticsDisplayVisibility method. The statistics information provides insight into how your model is performing.

Statistic information display in the top-left corner of WedViewer.

This table describes the data that is included in the statistics display panel:

Property name | Description
--- | ---
frames_per_second | Current framerate
draw_call_count | The number of draw calls during the last rendered frame. Draw calls are expensive and doing your best to minimalize them will lead to better performance.
triangle_count | The number of triangles rendered in the last frame.
line_segment_count | The number of line segments rendered in the last frame.
point_count | The number of points rendered in the last frame.