การแนะนำ

หากคุณทำตามส่วนก่อนหน้าของบทช่วยสอนนี้ และโต้ตอบกับแถบนำทางผ่าน "ลิงก์" ที่ให้มา คุณอาจสังเกตเห็นว่าแถบนำทางมีความล่าช้าบ้างหลังจากคลิกปุ่มต่างๆ น่าเสียดายที่ความล่าช้านี้อาจส่งผลเสียต่อประสบการณ์ผู้ใช้ ทำให้เกิดความหงุดหงิด ลดการมีส่วนร่วม และส่งผลให้ผู้ใช้ละทิ้งแอปพลิเคชันในที่สุด

โชคดีที่ Dash มอบวิธีแก้ไขปัญหานี้ด้วยการโทรกลับฝั่งไคลเอ็นต์ ในส่วนนี้ เราจะสำรวจการใช้การเรียกกลับฝั่งไคลเอ็นต์ และดูว่าเราจะสามารถนำไปใช้เพื่อปรับปรุงประสิทธิภาพของส่วนประกอบแถบด้านข้างของเราได้อย่างไร

ปัญหา

เมื่อคลิกปุ่ม มันจะทริกเกอร์การสื่อสารกับ dash-renderer จากนั้น dash-renderer จะระบุการเรียกกลับที่เหมาะสมซึ่งจะต้องดำเนินการเพื่อตอบสนองต่อการป้อนข้อมูลของผู้ใช้

โดยทั่วไปกระบวนการดำเนินการโทรกลับประกอบด้วยสามขั้นตอน: การส่งคำขอไปยังเซิร์ฟเวอร์ รอให้เซิร์ฟเวอร์ตอบสนอง และการดาวน์โหลดเนื้อหาที่อัปเดต กระบวนการทั้งหมดนี้ใช้เวลาประมาณ 300+ ms โดยใช้เวลาส่วนใหญ่ในการรอการตอบสนองของเซิร์ฟเวอร์

สารละลาย

ทางออกหนึ่งที่จะแก้ไขความล่าช้าและปรับปรุงประสิทธิภาพของแอปพลิเคชัน Dash คือการใช้การโทรกลับฝั่งไคลเอ็นต์ ด้วยการใช้การเรียกกลับฝั่งไคลเอ็นต์ เราสามารถลดเวลาที่ใช้ในการรอการตอบสนองของเซิร์ฟเวอร์ และมอบประสบการณ์ผู้ใช้ที่ตอบสนองและราบรื่นยิ่งขึ้น

การเรียกกลับฝั่งไคลเอ็นต์ช่วยให้เราดำเนินการเรียกกลับได้โดยตรงบนฝั่งไคลเอ็นต์ โดยไม่จำเป็นต้องเดินทางไปกลับที่เซิร์ฟเวอร์ ซึ่งหมายความว่าเฉพาะข้อมูลที่จำเป็นเท่านั้นที่จะถูกส่งไปยังเซิร์ฟเวอร์ ส่งผลให้เวลาตอบสนองเร็วขึ้นและลดภาระของเซิร์ฟเวอร์

หากต้องการใช้การเรียกกลับฝั่งไคลเอ็นต์ใน Dash เราจำเป็นต้องกำหนด Output และ Input เหมือนที่เราทำ แต่ยังต้องกำหนดฟังก์ชัน JavaScript เพิ่มเติมเป็นอาร์กิวเมนต์แรกของ @app.callback มัณฑนากร

มารหัสกันเถอะ

เราสามารถเริ่มต้นด้วยการมุ่งเน้นไปที่การโทรกลับที่สอดคล้องกับการคลิกปุ่มที่แสดงขนาดของแถบนำทาง การโทรกลับนี้เป็นตัวเลือกที่ดีสำหรับการปรับให้เหมาะสมฝั่งไคลเอ็นต์ เนื่องจากเกี่ยวข้องกับการอัปเดตค่าเดียวเพื่อตอบสนองต่ออินพุตของผู้ใช้

@dash.callback(
    Output("sidebar", "width"),          #what we wanted to change
    Input("sidebar-button", "n_clicks"), #width will change when btn is triggered
    State('sidebar','width')             #store inital width
    )
def sidebar(opened, width):
    if opened:
        if width['base'] == 300:         #if initial width is 300 then return 70
            return {"base": 70}
        else:
            return {'base':300}


# will update it to

app.clientside_callback(
    ClientsideFunction(namespace='clientside',
                       function_name='handle_click_sidebar_width'),
    Output("sidebar", "width"),
    [Input("sidebar-button", "n_clicks")],
    [State('sidebar','width')]
)

อาร์กิวเมนต์สามตัวเหมือนกันและมีฟังก์ชันฝั่งไคลเอ็นต์หนึ่งฟังก์ชัน ClientsideFunction(namespace='clientside',function_name='handle_click_sidebar_width'): อาร์กิวเมนต์นี้ระบุฟังก์ชันฝั่งไคลเอ็นต์ที่ควรถูกทริกเกอร์เมื่อมีการเรียกกลับ พารามิเตอร์ namespace ระบุเนมสเปซของฟังก์ชัน JavaScript (ในกรณีนี้คือ 'clientside') และพารามิเตอร์ function_name ระบุชื่อของฟังก์ชัน ('handle_click_sidebar_width')

สร้างไฟล์ใหม่ script.js ในโฟลเดอร์ assets/ มันจะมี Javascript ทั้งหมดที่เราจะใช้

const handle_click_sidebar_width = (n_clicks, width) => {
  const current_width = parseInt(width.base)
  if (n_clicks > 0 & current_width == 300) {
   return {base:70};
  } else {
    return {base:300};
  }
}

เราได้สร้างฟังก์ชัน JavaScript ชื่อ handle_click_sidebar_width ต้องใช้พารามิเตอร์สองตัว: n_clicks และ width

ขั้นแรกฟังก์ชันจะแยกความกว้างปัจจุบันของส่วนประกอบแถบด้านข้างจากพารามิเตอร์ width ซึ่งเป็นพจนานุกรมที่มีคีย์ base โดยใช้ parseInt() และจัดเก็บไว้ใน current_width

ถัดไป จะตรวจสอบว่าจำนวนคลิก (n_clicks) มากกว่าศูนย์หรือไม่ และความกว้างปัจจุบันเท่ากับ 300 หากเงื่อนไขทั้งสองเป็นจริง ก็จะส่งคืนออบเจ็กต์ที่มีค่าความกว้างใหม่เป็น 70 สำหรับคุณสมบัติ base ซึ่งจะช่วยลดความกว้างของแถบด้านข้างจาก 300 เป็น 70 เมื่อคลิกปุ่มแถบด้านข้าง

หากไม่ตรงตามเงื่อนไข หมายความว่าความกว้างปัจจุบันของแถบนำทางคือ 70 ดังนั้นฟังก์ชันจึงส่งคืนออบเจ็กต์ที่มีค่าความกว้างใหม่เป็น 300 สำหรับคุณสมบัติ base วิธีนี้จะคืนค่าความกว้างเดิมของแถบด้านข้างเมื่อมีการคลิกปุ่มอีกครั้ง

ในทำนองเดียวกัน การเรียกกลับสำหรับปุ่มที่สองซึ่งแสดงผลลิ้นชัก ยังสามารถได้รับประโยชน์จากการปรับให้เหมาะสมฝั่งไคลเอ็นต์อีกด้วย เนื่องจากการโทรกลับจะส่งกลับค่าบูลีนเพื่อตอบสนองต่ออินพุตของผู้ใช้ จึงสามารถดำเนินการได้อย่างมีประสิทธิภาพมากขึ้นในฝั่งไคลเอ็นต์

@dash.callback(
    Output("drawer-simple", "opened"),
    Input("drawer-demo-button", "n_clicks"),
    prevent_initial_call=True,
    )
def drawer_dem(n_clicks):
    return True

# will update it to
dash.clientside_callback(
    ClientsideFunction(namespace='clientside', function_name='handle_click'),
    Output("drawer-simple2", "opened"),
    [Input("drawer-demo-button2", "n_clicks")]
)

และในจาวาสคริปต์ เราจะเพิ่มฟังก์ชัน handle_click และอ็อบเจ็กต์ใน JavaScript ที่ให้วิธีการกำหนดฟังก์ชันฝั่งไคลเอ็นต์ที่สามารถเรียกใช้จากแอปพลิเคชัน Dash คุณสมบัติ clientside ของวัตถุนี้ใช้เพื่อจัดเก็บวัตถุที่มีฟังก์ชันฝั่งไคลเอ็นต์ ในกรณีของเรา วัตถุมีคุณสมบัติสองประการ: handle_click และ handle_click_sidebar_width ซึ่งสอดคล้องกับฟังก์ชันฝั่งไคลเอ็นต์สองตัวที่ใช้ในแอปพลิเคชัน Dash

const handle_click = (n_clicks) => {
  if (n_clicks > 0) {
    return true;
  } else {
    return '';
  }
};

window.dash_clientside = { clientside: { handle_click,handle_click_sidebar_width }};

ผลลัพธ์ที่ได้นั้นยอดเยี่ยมมาก สามารถตรวจสอบได้ ที่นี่

บทสรุป

โดยสรุป การใช้การเรียกกลับฝั่งไคลเอ็นต์สามารถปรับปรุงประสิทธิภาพและประสบการณ์ผู้ใช้ของแอปพลิเคชัน Dash ได้อย่างมาก ด้วยการเพิ่มประสิทธิภาพการโทรกลับบางอย่างที่จะดำเนินการในฝั่งไคลเอ็นต์ แอปพลิเคชันสามารถลดเวลาที่ใช้ในการรอการตอบสนองของเซิร์ฟเวอร์และให้การโต้ตอบที่รวดเร็วและตอบสนองมากขึ้น องค์ประกอบ ClientsideFunction และ window.dash_clientside วัตถุมีเครื่องมือที่มีประสิทธิภาพสำหรับการกำหนดและจัดการฟังก์ชันฝั่งไคลเอ็นต์ภายในแอปพลิเคชัน Dash ดังนั้นจึงขอแนะนำอย่างยิ่งให้สำรวจและใช้เครื่องมือเหล่านี้เพื่อสร้างแอปพลิเคชัน Dash ที่มีประสิทธิภาพสูงและใช้งานง่าย

สามารถดูโค้ดได้โดยไปที่ GitHub ลิงก์ ฉันหวังว่าคุณจะพบคู่มือนี้ให้ข้อมูลและเป็นประโยชน์ในการสร้างแดชบอร์ดที่ดึงดูดสายตาด้วย Dash

โปรดอย่าลังเลที่จะแสดงความคิดเห็นด้านล่าง ข้อเสนอแนะหรือคำถามใดๆ จะช่วยเราปรับปรุงเนื้อหาในอนาคตและตอบสนองความต้องการของคุณได้ดียิ่งขึ้น ขอบคุณที่อ่านและปรบมือจะไม่เจ็บใช่ไหม?