# Advanced > Performance optimization and client-side functions. --- .. llms_copy::references/advanced .. toc:: ### Overview Advanced features for optimizing performance and extending functionality with client-side JavaScript. ### Performance The grid uses canvas-based scrolling to handle large datasets efficiently. This doc is hosted on a free and low memory machine, so demo here is limited to 50,000 rows for now. If the app freezes due to exceeding memory, it will reboot in about a few seconds. Performance is buttery smooth via gunicorn, but not on local development server > 10,000 rows. .. exec::examples.reference.advanced.performance :code: false ```python # File: examples/reference/advanced/performance.py import dash_glide_grid as dgg import dash_mantine_components as dmc from dash import callback, Input, Output columns = [ {"title": "ID", "id": "id", "width": 60}, {"title": "Product", "id": "product", "width": 150}, {"title": "Category", "id": "category", "width": 120}, {"title": "Price", "id": "price", "width": 90}, {"title": "Stock", "id": "stock", "width": 80}, {"title": "Rating", "id": "rating", "width": 90}, {"title": "Reviews", "id": "reviews", "width": 90}, {"title": "SKU", "id": "sku", "width": 120}, {"title": "Warehouse", "id": "warehouse", "width": 120}, ] def generate_data(num_rows): return [ { "id": i + 1, "product": f"Product {i + 1}", "category": ["Electronics", "Clothing", "Home", "Sports"][i % 4], "price": round(10 + (i * 0.5) % 500, 2), "stock": (i * 7) % 1000, "rating": round(3 + (i % 20) / 10, 1), "reviews": (i * 13) % 500, "sku": f"SKU-{i + 1:05d}", "warehouse": ["East", "West", "Central", "North", "South"][i % 5], } for i in range(num_rows) ] component = dmc.Stack( [ # select to choose number of rows: dmc.Select( label="Select number of rows to display", id="row-count-select", data=[ "1000", "10000", "25000", "50000", ], value=str(1000), style={"width": 200}, allowDeselect=False, ), # enable/disable smooth scrolling: dmc.Group( [ dmc.Switch(id="smooth-scroll-x", label="Smooth Scroll X", checked=True), dmc.Switch(id="smooth-scroll-y", label="Smooth Scroll Y", checked=True), dmc.Switch( id="prevent-diagonal", label="Prevent Diagonal", checked=True ), ] ), dgg.GlideGrid( id={"type": "glide-grid", "index": "advanced-performance"}, columns=columns, data=generate_data(1000), height=300, smoothScrollX=True, smoothScrollY=True, ), ] ) @callback( Output({"type": "glide-grid", "index": "advanced-performance"}, "data"), Input("row-count-select", "value"), prevent_initial_call=True, ) def update_row_count(row_count_value): return generate_data(int(row_count_value)) @callback( Output({"type": "glide-grid", "index": "advanced-performance"}, "smoothScrollX"), Output({"type": "glide-grid", "index": "advanced-performance"}, "smoothScrollY"), Output( {"type": "glide-grid", "index": "advanced-performance"}, "preventDiagonalScrolling", ), Input("smooth-scroll-x", "checked"), Input("smooth-scroll-y", "checked"), Input("prevent-diagonal", "checked"), prevent_initial_call=True, ) def update_smooth(x, y, diagonal): return x, y, diagonal ``` :defaultExpanded: false :withExpandedButton: true ### Client-Side Functions Execute JavaScript functions in the browser without server round-trips. Define functions in an assets file. .. exec::examples.reference.advanced.clientside :code: false :defaultExpanded: false :withExpandedButton: true ### Custom Cell Drawing Render custom cell content using the Canvas API with the `drawCell` prop. .. exec::examples.reference.advanced.custom_draw :code: false :defaultExpanded: false :withExpandedButton: true ### Props Reference #### Client-Side Function Props All client-side functions use the format `{"function": "functionName(args...)"}`. | Property | Type | Example | |----------|------|---------| | `validateCell` | dict | `{"function": "validateAge(cell, newValue)"}` | | `coercePasteValue` | dict | `{"function": "smartPaste(val, cell)"}` | | `getRowThemeOverride` | dict | `{"function": "rowThemeByStatus(row, rowData)"}` | | `drawCell` | dict | `{"function": "drawProgressBar(ctx, cell, ...)"}` | | `drawHeader` | dict | `{"function": "drawCustomHeader(ctx, column, ...)"}` | | Column `valueFormatter` | dict | `{"function": "formatCurrency(value)"}` | #### Experimental Props | Property | Type | Default | Description | |----------|------|---------|-------------| | `experimental.renderStrategy` | string | "single-buffer" | Render mode: "single-buffer", "double-buffer", or "direct" | | `experimental.kineticScrollPerfHack` | boolean | False | Performance optimization for kinetic scrolling | | `experimental.hyperWrapping` | boolean | False | Enable hyper wrapping mode | | `experimental.paddingBottom` | number | 0 | Extra padding at bottom | | `experimental.paddingRight` | number | 0 | Extra padding at right | #### Span Behavior | Property | Type | Default | Description | |----------|------|---------|-------------| | `spanRangeBehavior` | string | "default" | How spans interact with selections: "default" or "allowPartial" | --- *Source: /reference/advanced* *Generated with dash-improve-my-llms*