This page contains tips for issues that you may encounter while using custom widgets.
Custom widgets run inside an iframe and may crash if they consume too much memory or block the browser thread. When this occurs, the browser may become unresponsive or show a terminated state. Use the Performance tab in Chrome DevTools to record browser execution and look for performance anomalies.
Review the common anti-patterns described below to mitigate browser page crashing when working with custom widgets.
Infinite or effectively infinite loops and re-renders are a common class of bug that can cause page crashes.
In React ↗, beware of loops that could cause infinite re-renders. Check for:
useEffect hooks that update a dependency of the same hook, causing them to run again.setTimeout, setInterval, requestAnimationFrame loops that are never cleared.window.addEventListener, that cause updates which trigger the same handler again.Copied!1 2 3 4 5 6 7 8 9 10function InfiniteRender({ objects }: { objects: MyObject[] }) { const [data, setData] = useState<MyObject[]>([]); // BUG: updating data which is also a dependency useEffect(() => { setData([...objects]); }, [objects, data]); return <MyComponent />; }
Outside of React, avoid creating while loops that never exit:
Copied!1 2 3 4 5 6 7// BUG: infinite loop if condition is never met while (true) { doSomething(); if (myCondition) { break; } }
Additionally, you should not create while loops that are effectively infinite due to an unknown and unexpectedly large number of iterations:
Copied!1 2 3 4 5 6 7 8 9const minValue = min(myValues); const maxValue = max(myValues); let currentValue = minValue; // BUG: effectively infinite loop if bounds of myValues are unknown and unexpectedly large while (currentValue <= maxValue) { doSomething(currentValue); currentValue += 1; }
When an ontology object type has a large number of objects, do not load all objects into the browser for client-side processing. This can exhaust browser resources and transfer large amounts of data over the network, which can be slow for widget users.
Copied!1 2 3 4 5 6 7 8 9 10 11 12let pageToken: string | undefined; const allObjects = []; do { const page = await client(MyObject).fetchPage({ $pageSize: 1_000, $pageToken: pageToken, }); allObjects.push(...page.data); pageToken = page.nextPageToken; } while (pageToken != null);
Instead:
$select for object types with many properties..withProperties for calculations depending on values of other properties or links on objects.