Gradio 月活用户破百万之旅!

阅读更多
Gradio logo
  1. 附加功能
  2. 客户端函数

客户端函数

Gradio 允许你通过在事件监听器中设置 js=True,直接在浏览器中运行某些“简单”函数。这将自动将你的 Python 代码转换为 JavaScript,通过避免简单的 UI 更新往返服务器,从而显著提高应用程序的响应速度。

当服务器负载过重、连接延迟较高或许多用户同时访问应用程序时,在托管应用程序(如 Hugging Face Spaces)上,响应速度的差异最为明显。

何时使用客户端函数

客户端函数非常适合更新组件属性(如可见性、占位符、交互状态或样式)。

这是一个基本示例

import gradio as gr

with gr.Blocks() as demo:
    with gr.Row() as row:
        btn = gr.Button("Hide this row")
    
    # This function runs in the browser without a server roundtrip
    btn.click(
        lambda: gr.Row(visible=False), 
        None, 
        row, 
        js=True
    )

demo.launch()

局限性

客户端函数有一些重要的限制

  • 它们只能更新组件属性(而不是值)
  • 它们不能接受任何输入

以下是一些可以使用 js=True 的函数

# Simple property updates
lambda: gr.Textbox(lines=4)

# Multiple component updates
lambda: [gr.Textbox(lines=4), gr.Button(interactive=False)]

# Using gr.update() for property changes
lambda: gr.update(visible=True, interactive=False)

我们正在努力扩大可以转译为 JavaScript 并在浏览器中运行的函数范围。关注 Groovy 库以获取更多信息

完整示例

这是一个更完整的示例,展示了客户端函数如何改善用户体验

"""
This is a simple todo list app that allows you to edit tasks and mark tasks as complete.
All actions are performed on the client side.
"""
import gradio as gr

tasks = ["Get a job", "Marry rich", "", "", "", ""]
textboxes = []
buttons = []
with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=3):
            gr.Markdown("# A Simple Interactive Todo List")
        with gr.Column(scale=2):
            with gr.Row():
                freeze_button = gr.Button("Freeze tasks", variant="stop")
                edit_button = gr.Button("Edit tasks")
    for i in range(6):
        with gr.Row() as r:
            t = gr.Textbox(tasks[i], placeholder="Enter a task", show_label=False, container=False, scale=7, interactive=True)
            b = gr.Button("✔️", interactive=bool(tasks[i]), variant="primary" if tasks[i] else "secondary")
            textboxes.append(t)
            buttons.append(b)
        t.change(lambda : gr.Button(interactive=True, variant="primary"), None, b, js=True)
        b.click(lambda : gr.Row(visible=False), None, r, js=True)
    freeze_button.click(lambda : [gr.Textbox(interactive=False), gr.Textbox(interactive=False), gr.Textbox(interactive=False), gr.Textbox(interactive=False), gr.Textbox(interactive=False), gr.Textbox(interactive=False)], None, textboxes, js=True)
    edit_button.click(lambda : [gr.Textbox(interactive=True), gr.Textbox(interactive=True), gr.Textbox(interactive=True), gr.Textbox(interactive=True), gr.Textbox(interactive=True), gr.Textbox(interactive=True)], None, textboxes, js=True)
    freeze_button.click(lambda : [gr.Button(visible=False), gr.Button(visible=False), gr.Button(visible=False), gr.Button(visible=False), gr.Button(visible=False), gr.Button(visible=False)], None, buttons, js=True)
    edit_button.click(lambda : [gr.Button(visible=True), gr.Button(visible=True), gr.Button(visible=True), gr.Button(visible=True), gr.Button(visible=True), gr.Button(visible=True)], None, buttons, js=True)

demo.launch()

幕后原理

当你设置 js=True 时,Gradio 会:

  1. 将你的 Python 函数转译为 JavaScript

  2. 直接在浏览器中运行该函数

  3. 仍然将请求发送到服务器(为了保持一致性并处理任何副作用)

这提供了即时的视觉反馈,同时确保你的应用程序状态保持一致。