Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions devel/0146.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# [0146] 新建文档性能优化

## 1 相关文档
- [dddd.md](dddd.md) - 任务文档模板

## 2 任务相关的代码文件
- `src/Texmacs/Data/new_buffer.cpp`
- `src/Texmacs/Data/new_view.cpp`
- `src/Texmacs/Data/new_window.cpp`

## 3 如何测试

### 3.1 确定性测试(单元测试)
```
xmake b stem
```

### 3.2 非确定性测试(文档验证)
启动 Mogan,新建文档,直观感受响应速度是否提升。

## 4 如何提交

提交前执行以下最少步骤:

```bash
bin/format
git add .
git commit -m "[0146] 新建文档性能优化"
```

## 5 What

优化新建文档(`create_buffer`)的启动性能。当前基准测试数据:

| 任务 | 耗时 |
|------|------|
| `make_new_buffer` | 1 ms |
| `get_new_view/init_buffer` | 773 ms |
| `get_new_view` | 781 ms |
| `create_buffer` | 3387 ms |
| `typeset` | 1 ms |

`create_buffer` 总耗时约 3.4 秒,其中 `get_new_view/init_buffer`(执行 Scheme 初始化脚本)约 773 ms。剩余耗时主要来自图标栏等 UI 组件的同步初始化。

## 6 Why

新建文档是高频操作,3.4 秒的等待时间严重影响用户体验。主要瓶颈在于:

1. `init_buffer` 阶段执行 `init-buffer.scm` Scheme 脚本,耗时约 773 ms
2. 图标栏等 UI 组件在新建文档时同步初始化,产生额外耗时
3. `switch_to_buffer` 等操作可能包含不必要的同步等待

## 7 How

1. 延迟加载图标栏:在 `menu_icons` 中判断图标栏是否可见,若不可见则将菜单内容暂存到 `icon_bar_pending`,待图标栏变为可见时再执行初始化
2. 延迟加载不可见工具栏:对不可见的工具栏跳过同步 widget 创建,避免新建文档时的无效 UI 开销
3. 移除临时性能计时代码:优化完成后清理 `bench_start`/`bench_end` 调用,保持代码整洁
8 changes: 8 additions & 0 deletions src/Texmacs/Window/tm_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ tm_window_rep::tm_window_rep (widget wid2, tree geom)
serial (tm_window_serial++), menu_current (object ()),
menu_cache (widget ()), text_ptr (NULL) {
zoomf= retina_zoom * get_server ()->get_default_zoom_factor ();
icon_bar_pending= array<string> (5);
}

double
Expand Down Expand Up @@ -449,6 +450,10 @@ tm_window_rep::menu_main (string menu) {

void
tm_window_rep::menu_icons (int which, string menu) {
if (!get_icon_bar_flag (which)) {
icon_bar_pending[which]= menu;
return;
}
eval ("(lazy-initialize-force)");
widget w;
if (get_menu_widget (which, menu, w)) {
Expand All @@ -458,6 +463,7 @@ tm_window_rep::menu_icons (int which, string menu) {
else if (which == 3) set_user_icons (wid, w);
else if (which == 4) set_tab_pages (wid, w);
}
icon_bar_pending[which]= "";
}

void
Expand Down Expand Up @@ -506,6 +512,8 @@ tm_window_rep::set_icon_bar_flag (int which, bool flag) {
else if (which == 2) set_focus_icons_visibility (wid, flag);
else if (which == 3) set_user_icons_visibility (wid, flag);
else if (which == 4) set_tab_pages_visibility (wid, flag);
if (flag && which < N(icon_bar_pending) && icon_bar_pending[which] != "")
menu_icons (which, icon_bar_pending[which]);
}

void
Expand Down
1 change: 1 addition & 0 deletions src/Texmacs/tm_window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class tm_window_rep {
string* text_ptr; // where the interactive string is returned
command call_back; // called when typing finished
string cur_title; // current window title
array<string> icon_bar_pending; // lazy load pending menus

public:
tm_window_rep (widget wid2, tree geom);
Expand Down
Loading