Hello all,
I am in the process of transforming a plain Dash app into a multi-page Dash app. Here is how I’m setting up my app to get this done:
dashboard_data_reader = SqlalchemyDashboardDataReader(SqlAlchemyDB(proj_path))
""" Creating and setting up the Dash app """
app = Dash(
__name__,
external_stylesheets=[theme_stylesheet],
update_title=None,
suppress_callback_exceptions=True,
)
app.title = f"Entropy - {project_name(proj_path)} [{project_path(proj_path)}]"
app.layout = html.Div(
[dcc.Location(id="url", refresh=False), html.Div(id="page-content")]
)
""" Registering callbacks used in pages """
main_callbacks.register_callbacks(app, dashboard_data_reader)
param_store_callbacks.register_callbacks(app, dashboard_data_reader)
""" Callback to route between page layouts based on URL """
@callback(Output("page-content", "children"), Input("url", "pathname"))
def display_page(pathname):
if pathname == "/":
return main_layout.build_layout(proj_path, dashboard_data_reader)
elif pathname == "/param_store":
return param_store_layout.build_layout(proj_path, dashboard_data_reader)
else:
return "404"
You’ll notice that the registration of callbacks is done in functions imported from page-level modules. This is because the instantiation of my data source (dashboard_data_reader
) is heavy and I’d rather cache it at the app level. Likewise layouts are imported from page-level modules.
When I run the app initial transitions between pages through NavLink
s work fine. But after a few clicks I get an elaborate yet cryptic error message in browser window:
Node.removeChild: The node to be removed is not a child of this node
(This error originated from the built-in JavaScript code that runs Dash apps. Click to see the full stack trace or open your browser's console.)
removeChild@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:7724:20
unmountHostComponents@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:20584:22
commitDeletion@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:20635:28
commitMutationEffects@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:22917:27
callCallback@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:182:16
invokeGuardedCallbackDev@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:231:18
invokeGuardedCallback@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:286:33
commitRootImpl@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:22644:32
unstable_runWithPriority@http://localhost:8050/_dash-component-suites/dash/deps/react@16.v2_2_0m1646581418.14.0.js:2685:14
runWithPriority$1@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:11174:12
commitRoot@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:22516:22
finishSyncRender@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:21942:15
performSyncWorkOnRoot@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:21928:25
flushSyncCallbackQueueImpl/<@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:11224:26
unstable_runWithPriority@http://localhost:8050/_dash-component-suites/dash/deps/react@16.v2_2_0m1646581418.14.0.js:2685:14
runWithPriority$1@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:11174:12
flushSyncCallbackQueueImpl@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:11219:26
flushSyncCallbackQueue@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:11207:5
batchedUpdates$1@http://localhost:8050/_dash-component-suites/dash/deps/react-dom@16.v2_2_0m1646581418.14.0.js:21997:9
notify@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:85223:12
notifyNestedSubs@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:85293:15
handleChangeWrapper@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:85298:20
dispatch@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:86293:7
./node_modules/redux-thunk/es/index.js/createThunkMiddleware/middleware/</<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:85964:16
applyProps@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:1609:15
./src/observers/executedCallbacks.ts/observer/</<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:1650:40
forEach@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:76508:7
./node_modules/ramda/es/internal/_checkForMethod.js/_checkForMethod/<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:77185:119
f2@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:77418:14
./src/observers/executedCallbacks.ts/observer/<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:1637:58
forEach@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:76508:7
./node_modules/ramda/es/internal/_checkForMethod.js/_checkForMethod/<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:77185:119
f2@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:77418:14
observer@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:1619:54
./src/StoreObserver.ts/StoreObserver/</<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:415:9
forEach@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:76508:7
./node_modules/ramda/es/internal/_checkForMethod.js/_checkForMethod/<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:77185:119
f2@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:77418:14
./src/StoreObserver.ts/StoreObserver/<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:413:54
dispatch@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:86293:7
./node_modules/redux-thunk/es/index.js/createThunkMiddleware/middleware/</<@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:85964:16
_callee$@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:1854:25
u@http://localhost:8050/_dash-component-suites/dash_bootstrap_components/_components/dash_bootstrap_components.v1_0_3m1645349989.min.js:2:7133
e</c/s._invoke@http://localhost:8050/_dash-component-suites/dash_bootstrap_components/_components/dash_bootstrap_components.v1_0_3m1645349989.min.js:2:6922
e</w/</<@http://localhost:8050/_dash-component-suites/dash_bootstrap_components/_components/dash_bootstrap_components.v1_0_3m1645349989.min.js:2:7562
asyncGeneratorStep@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:1775:103
_next@http://localhost:8050/_dash-component-suites/dash/dash-renderer/build/dash_renderer.v2_2_0m1646581418.dev.js:17
When I look in the browser dev tools console I also see:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in s (created by s)
in s (created by s)
in div (created by s)
in s (created by s)
in s (created by s)
in s (created by c)
in Suspense (created by c)
in c (created by CheckedComponent)
in CheckedComponent (created by BaseTreeContainer)
in ComponentErrorBoundary (created by BaseTreeContainer)
in BaseTreeContainer (created by Context.Consumer)
in Unknown (created by BaseTreeContainer)
in div (created by Col)
in Col (created by ea)
in ea (created by CheckedComponent)
in CheckedComponent (created by BaseTreeContainer)
in ComponentErrorBoundary (created by BaseTreeContainer)
in BaseTreeContainer (created by Context.Consumer)
in Unknown (created by BaseTreeContainer)
in div (created by Row)
in Row (created by Xd)
in Xd (created by CheckedComponent)
in CheckedComponent (created by BaseTreeContainer)
in ComponentErrorBoundary (created by BaseTreeContainer)
in BaseTreeContainer (created by Context.Consumer)
in Unknown (created by BaseTreeContainer) react-dom@16.v2_2_0m1646581418.14.0.js:82:32
printWarning react-dom@16.v2_2_0m1646581418.14.0.js:82
error react-dom@16.v2_2_0m1646581418.14.0.js:54
warnAboutUpdateOnUnmountedFiberInDEV react-dom@16.v2_2_0m1646581418.14.0.js:23296
scheduleUpdateOnFiber react-dom@16.v2_2_0m1646581418.14.0.js:21304
enqueueSetState react-dom@16.v2_2_0m1646581418.14.0.js:12774
setState react@16.v2_2_0m1646581418.14.0.js:557
hideTooltipId index.tsx:31
Does my app really have memory leaks? Are they related to the way I am registering callbacks or rebuilding the layouts?
Can anyone share info on how I can debug this further?
Thanks,
urig