我是Dash的n00b,我正在尝试从WebSocket提要更新DashTable。当feed不太多的时候,代码似乎可以工作,但是一旦有了feed,Chrome就会开始向我的服务器发送垃圾邮件,发送fetch请求(来自dash_update_component)。
有没有什么方法可以让它更有性能?
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import json
import pandas as pd
from dash import callback, Dash, dash_table
from dash.dependencies import Input, Output, State
from dash_extensions import WebSocket
symbols = ["BTCUSDT"]
columns = ["symbol", "bid_volume", "bid_price", "ask_volume", "ask_price"]
def create_data():
data = {}
for col in columns:
if col == "symbol":
data[col] = symbols
else:
data[col] = [None] * len(symbols)
return data
df = pd.DataFrame(data=create_data())
# Create example app.
app = Dash(prevent_initial_callbacks=True)
app.layout = html.Div([
dash_table.DataTable(df.to_dict('records'), [{"name": i, "id": i} for i in df.columns], id='tbl', editable=True),
dcc.Input(id="input", autoComplete="off"), html.Div(id="message"),
WebSocket(url="wss://fstream.binance.com/ws/", id="ws")
])
# Write to websocket.
@app.callback(Output("ws", "send"), [Input("input", "value")])
def send(value):
sub_msg = {
"method": "SUBSCRIBE",
"params": [],
"id": 1
}
for ins in symbols:
sub_msg["params"] += ([f"{ins.lower()}@bookTicker"])
return json.dumps(sub_msg, indent=0)
# Read from websocket.
@app.callback(Output('tbl', 'data'), [Input("ws", "message")])
def on_feed(message):
if "data" not in message:
return dash.no_update
else:
data = json.loads(message["data"])
print(data)
symbol = data["s"]
row_idx = df.index[df['symbol'] == symbol].tolist()[0]
df.loc[row_idx, columns] = [symbol, data["B"], data["b"], data["a"], data["A"]]
return df.to_dict('records')
if __name__ == '__main__':
app.run_server(debug=True)
1条答案
按热度按时间ghhkc1vu1#
要提高性能,你可以做的一件事是将回调转换为clientside callbacks:
客户端回调在客户端以JavaScript执行代码,而不是在服务器上以Python执行代码。
https://dash.plotly.com/performance
如果你查看网络选项卡,你可以看到现在没有WebSocket相关的请求了。
在这种情况下,我们仍然会为每个进入的有效消息更新表。您可能还希望通过使用
dcc.Interval
来限制这一点:您可以尝试调整间隔。较低的间隔使结果更“真实的”/准确,但较高的间隔意味着需要执行的更新较少。