From 9fd16e3c1fa650a295f24c0a202e7a78433f7e1a Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Fri, 8 May 2026 11:23:31 +0800 Subject: [PATCH] perf(grid): pre-stringify JSON/JSONB values and truncate cell display Serialize JSON/JSONB as strings in Postgres and MySQL drivers to avoid repeated JSON.stringify in the render loop. Truncate cell display to 256 chars so the browser doesn't lay out huge text nodes on scroll. --- crates/dbx-core/src/db/mysql.rs | 4 ++-- crates/dbx-core/src/db/postgres.rs | 4 ++-- src/components/grid/DataGrid.vue | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/dbx-core/src/db/mysql.rs b/crates/dbx-core/src/db/mysql.rs index aaa78e25a7..085e05437d 100644 --- a/crates/dbx-core/src/db/mysql.rs +++ b/crates/dbx-core/src/db/mysql.rs @@ -85,10 +85,10 @@ fn mysql_value_to_json(row: &MySqlRow, idx: usize, type_name: &str) -> serde_jso if upper_type == "JSON" { if let Ok(v) = row.try_get::(idx) { - return v; + return serde_json::Value::String(v.to_string()); } if let Ok(v) = row.try_get::(idx) { - return serde_json::from_str::(&v).unwrap_or(serde_json::Value::String(v)); + return serde_json::Value::String(v); } return serde_json::Value::Null; } diff --git a/crates/dbx-core/src/db/postgres.rs b/crates/dbx-core/src/db/postgres.rs index 86dd55dbcf..3e4a835945 100644 --- a/crates/dbx-core/src/db/postgres.rs +++ b/crates/dbx-core/src/db/postgres.rs @@ -33,10 +33,10 @@ fn pg_value_to_json(row: &PgRow, idx: usize, type_name: &str) -> serde_json::Val if upper == "JSON" || upper == "JSONB" { if let Ok(v) = row.try_get::(idx) { - return v; + return serde_json::Value::String(v.to_string()); } if let Ok(v) = row.try_get::(idx) { - return serde_json::from_str::(&v).unwrap_or(serde_json::Value::String(v)); + return serde_json::Value::String(v); } return serde_json::Value::Null; } diff --git a/src/components/grid/DataGrid.vue b/src/components/grid/DataGrid.vue index e9a0805d01..5d721d8eaf 100644 --- a/src/components/grid/DataGrid.vue +++ b/src/components/grid/DataGrid.vue @@ -470,11 +470,13 @@ function toggleSort(colName: string) { } } +const CELL_DISPLAY_MAX_LENGTH = 256; + function formatCell(value: CellValue): string { if (value === null) return "NULL"; if (typeof value === "boolean") return value ? "true" : "false"; - if (typeof value === "object") return JSON.stringify(value); - return String(value); + const s = typeof value === "object" ? JSON.stringify(value) : String(value); + return s.length > CELL_DISPLAY_MAX_LENGTH ? s.slice(0, CELL_DISPLAY_MAX_LENGTH) : s; } function quoteIdent(name: string): string {