You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dash点击按钮重复重载main.py:如何避免慢模块重复加载?

解决Dash背景回调导致模块重复加载的问题

问题场景

使用Dash背景回调实现进度条实时更新功能时,每次点击"Run Process"按钮,控制台都会多次打印"Importing slow utils",说明fake_utils模块被重复加载。该模块因读取大文件需要3分钟以上加载时间,重复加载严重影响性能,需保留进度条实时更新的同时解决此问题。

原因分析

Dash的DiskcacheManager为背景回调启动了多个工作进程,每个进程都会重新导入整个main.py脚本,包括顶层的fake_utils模块,导致重复加载。

解决方案

核心思路

将慢加载模块的导入逻辑放到工作进程初始化阶段,确保每个工作进程仅加载一次fake_utils,而非每次触发回调都重新导入。

修改后的代码

main.py

import dash_bootstrap_components as dbc
from uuid import uuid4
import diskcache
from dash import Dash, html, DiskcacheManager, Input, Output

# 工作进程初始化函数:每个进程启动时仅执行一次
def init_worker():
    global foo
    from fake_utils import foo

launch_uid = uuid4()
cache = diskcache.Cache("./cache")

# 配置背景回调管理器,指定进程初始化函数
background_callback_manager = DiskcacheManager(
    cache, 
    cache_by=[lambda: launch_uid], 
    expire=60,
    worker_initializer=init_worker
)

app = Dash(__name__,
           background_callback_manager=background_callback_manager,
           external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = html.Div([
    html.Button('Run Process', id='run-button'),
    dbc.Progress(id="progress-component", value=0, max=10),
    html.Div(id='output')
])

@app.callback(
    Output('output', 'children'),
    Input('run-button', 'n_clicks'),
    background=True,
    progress=[
        Output("progress-component", "value"),
        Output("progress-component", "label"),
    ],
)
def run_process(set_progress, n_clicks):
    if n_clicks is None:
        return html.Div()
    results = []
    for i in range(10):
        res = foo()
        results.append(res)
        set_progress((i+1, f'{i+1}'))

    return 'Done'


if __name__ == '__main__':
    # Debug模式下建议关闭自动重载,避免额外进程重复导入
    app.run_server(debug=True, port=100, use_reloader=False)

fake_utils.py(保持不变)

import time

print('Importing slow utils')

def foo():
    time.sleep(1)
    return 0

额外优化建议

  1. 缓存预加载数据:如果fake_utils需要读取大文件,可在初始化函数中加载数据并存入diskcache,避免重复读取:
    def init_worker():
        global foo
        from fake_utils import foo, load_large_file
        large_data = load_large_file()
        cache.set("preloaded_data", large_data)
    
  2. 关闭Debug自动重载:Debug模式的自动重载会启动额外进程,设置use_reloader=False可避免此问题,同时不影响断点调试。

内容的提问来源于stack exchange,提问作者david serero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:29:52