Dash 3.1.0 버전부터 Flask의 안정적인 비동기 프로그래밍 지원을 바탕으로 서버 측 콜백 함수를 비동기 형식으로 작성할 수 있습니다. 이를 통해 계산 성능을 크게 향상시킬 수 있습니다.
비동기 의존성 설치
비동기 기능을 사용하려면 다음 명령어로 추가 의존성을 설치해야 합니다:
pip install dash[async] -U
동기식 콜백과 비동기식 콜백 비교
동기식 콜백 예제
먼저 전통적인 동기식 방식의 콜백 함수를 살펴보겠습니다:
import time
import dash
import random
from dash import html
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div([
html.Button('계산 실행', id='calculate', n_clicks=0),
html.Div(id='output')
])
def heavy_task():
time.sleep(1)
return random.randint(1, 100)
@app.callback(
Output('output', 'children'),
Input('calculate', 'n_clicks')
)
def sync_callback(n_clicks):
if n_clicks is None:
return ''
start_time = time.time()
# 5개의 병렬 작업 시뮬레이션
results = [heavy_task() for _ in range(5)]
elapsed = time.time() - start_time
return f'결과: {results}, 소요시간: {elapsed:.2f}초'
if __name__ == '__main__':
app.run(debug=True)
이 방식은 5개의 작업을 순차적으로 실행하므로 약 5초가 소요됩니다.
비동기식 콜백 예제
이제 비동기 방식으로 동일한 기능을 구현해 보겠습니다:
import time
import dash
import random
import asyncio
from dash import html
from dash.dependencies import Input, Output
app = dash.Dash(__name__)
app.layout = html.Div([
html.Button('계산 실행', id='calculate', n_clicks=0),
html.Div(id='output')
])
async def async_heavy_task():
await asyncio.sleep(1)
return random.randint(1, 100)
@app.callback(
Output('output', 'children'),
Input('calculate', 'n_clicks')
)
async def async_callback(n_clicks):
if n_clicks is None:
return ''
start_time = time.time()
# 비동기 작업 병렬 실행
tasks = [async_heavy_task() for _ in range(5)]
results = await asyncio.gather(*tasks)
elapsed = time.time() - start_time
return f'결과: {results}, 소요시간: {elapsed:.2f}초'
if __name__ == '__main__':
app.run(debug=True)
비동기 방식은 asyncio.gather()를 사용하여 작업을 병렬로 실행하므로 약 1초만에 완료됩니다.
주요 특징
- 비동기 콜백 함수는 async def로 정의
- await 키워드를 사용하여 비동기 작업 대기
- asyncio.gather()로 여러 작업 병렬 처리
- 기존 콜백 데코레이터 구문과 호환
이 기능을 활용하면 I/O 바운드 작업이 많은 Dash 애플리케이션의 성능을 크게 개선할 수 있습니다.