Skip to content

fix(perf): improve file opening performance with lazy loading#460

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:fix-360259-improve-file-opening-performance
May 14, 2026
Merged

fix(perf): improve file opening performance with lazy loading#460
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
add-uos:fix-360259-improve-file-opening-performance

Conversation

@add-uos
Copy link
Copy Markdown
Contributor

@add-uos add-uos commented May 14, 2026

Implement lazy loading mechanism for multiple files to improve performance. Only load first file immediately, defer others.

实现文件打开的懒加载机制,提升性能。只立即加载第一个文件,
其他文件延迟加载。

Log: 优化文件打开性能,实现懒加载机制
PMS: BUG-360259
Influence: 打开多个文件时性能显著提升,应用启动更快,用户体验改善。

Summary by Sourcery

Implement lazy loading when opening multiple files so that only the first supported file is loaded immediately while others are deferred, while keeping unsupported files eagerly loaded to surface errors.

New Features:

  • Introduce pending tab entries to represent additional supported files that are only loaded when the user activates them.

Enhancements:

  • Improve multi-file open performance by reducing initial file loading to a single supported file and deferring the rest.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 14, 2026

Reviewer's Guide

Implements a lazy-loading mechanism when opening multiple files: the first supported file is opened and activated immediately, while remaining supported files are added as pending tabs that load on demand; unsupported files continue to be opened immediately to show error feedback.

File-Level Changes

Change Details Files
Introduce lazy-loading for supported files when opening multiple files, while keeping unsupported files eagerly loaded for error display.
  • Replace blanket loop that eagerly opens all supported files with logic that immediately opens only the first supported file tab and activates it.
  • Iterate over remaining supported files to construct PendingTabInfo objects (filepath, truePath, displayName, isTemFile=false, cursorPosition=-1) and register them via addPendingTab for deferred loading.
  • Clarify behavior for unsupported files by documenting that they cannot be lazy-loaded and must be opened immediately to show error messages, while preserving the existing loop that eagerly opens them.
src/widgets/window.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • Consider whether PendingTabInfo.truePath should preserve the original user-selected path instead of the canonical path (currently set equal to filepath), to avoid losing symlink or casing information that addTab may have previously derived internally.
  • Double-check that the new lazy-loading path initializes all PendingTabInfo fields that other code paths expect (e.g., any flags or metadata addTab used to set), so pending tabs behave identically to fully loaded tabs once activated.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider whether `PendingTabInfo.truePath` should preserve the original user-selected path instead of the canonical path (currently set equal to `filepath`), to avoid losing symlink or casing information that `addTab` may have previously derived internally.
- Double-check that the new lazy-loading path initializes all `PendingTabInfo` fields that other code paths expect (e.g., any flags or metadata `addTab` used to set), so pending tabs behave identically to fully loaded tabs once activated.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Implement lazy loading mechanism for multiple files to improve
performance. Only load first file immediately, defer others.

实现文件打开的懒加载机制,提升性能。只立即加载第一个文件,
其他文件延迟加载。

Log: 优化文件打开性能,实现懒加载机制
PMS: BUG-360259
Influence: 打开多个文件时性能显著提升,应用启动更快,用户体验改善。
@add-uos add-uos force-pushed the fix-360259-improve-file-opening-performance branch from 297464a to 0132f5a Compare May 14, 2026 07:22
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

你好!我是CodeGeeX,你的智能编程助手。我已仔细审查了你提供的Git Diff代码。

本次修改主要包含两部分:一是在.gitignore中新增了构建产物目录;二是在window.cpp中对文件打开逻辑进行了重构,引入了懒加载(Lazy Loading)机制,以优化多文件同时打开时的性能和用户体验。

以下是我对本次代码变更的详细审查意见及改进建议:

1. .gitignore 修改

评价:良好

  • 新增 obj-x86_64-linux-gnu/ 是非常正确的做法,避免了将C/C++编译产生的中间目标文件提交到版本库中。
  • 建议:如果项目存在跨平台编译,建议考虑是否需要添加通配符,如 obj-*/,以覆盖 obj-x86_64-apple-darwin/obj-aarch64-linux-gnu/ 等其他架构的编译目录。

2. window.cpp 逻辑修改

2.1 语法与代码质量

问题 A:foreach 宏已被废弃

  • 代码中仍然使用了 foreach (QString var, otherfiles)。从Qt 5.7开始,foreach 宏已被标记为废弃,在Qt 6中甚至可能被移除。C++11引入了基于范围的for循环,性能更好且更标准。
  • 改进建议:将 foreach 替换为 for (const QString &var : otherfiles)

问题 B:循环内的引用绑定存在潜在的悬垂引用风险

  • for (int i = 1; i < supportfileNames.size(); ++i) 循环中,使用了 const QString &filepath = supportfileNames[i];
  • 如果 supportfileNames 是一个局部变量且在循环结束后销毁,或者后续有修改,引用可能会失效。虽然在这个局部作用域内直接传递给 addPendingTab 大概率是安全的(取决于该函数是否立即拷贝了值),但为了代码的健壮性,建议直接按值传递或显式拷贝,避免不必要的引用风险。
  • 改进建议:改为 QString filepath = supportfileNames[i];,现代C++的移动语义会让这个开销微乎其微。

问题 C:未使用的 QFileInfo 变量(可能)

  • 代码中声明了 QFileInfo fileInfo(filepath); 并使用了 fileInfo.fileName()。请确保 QFileInfo 的头文件已被包含。此外,如果 filepath 是绝对路径,这没有问题;如果是相对路径,需注意 QFileInfo 的解析基准路径问题。

2.2 代码逻辑

问题 A:不支持的文件未使用懒加载的逻辑一致性

  • 注释中写道:“不支持的文件无法懒加载,需要立即加载以显示错误提示”。这在逻辑上是说得通的,因为需要立即反馈给用户。
  • 但如果一次性打开几百个不支持的文件,依然会导致界面卡顿。建议后续考虑是否可以对不支持的文件也实现一种“轻量级占位”机制,只在标签页上显示文件名,用户点击时才弹出错误提示。

问题 B:PendingTabInfo 结构的初始化

  • 代码中手动对 PendingTabInfo 的各个字段进行了赋值:
    pendingInfo.filepath = filepath;
    pendingInfo.truePath = filepath;
    pendingInfo.displayName = fileInfo.fileName();
    pendingInfo.isTemFile = false;
    pendingInfo.cursorPosition = -1;
  • 改进建议:建议在 PendingTabInfo 的类/结构体定义中为这些字段提供默认初始值(C++11 default member initializers),例如 bool isTemFile = false; int cursorPosition = -1;。这样在使用处可以简化代码,只设置必要的字段,防止遗漏初始化。

2.3 代码性能

评价:优秀

  • 引入懒加载机制是本次修改的最大亮点。当用户通过对话框多选打开几十个文件时,只立即加载并渲染第一个文件,其余文件仅创建标签页UI占位,这能极大地减少I/O阻塞和UI渲染时间,提升响应速度。
  • QFileInfo 的构造和 fileName() 提取在当前线程执行,因为只是字符串操作,开销极小,性能上没有问题。

2.4 代码安全

问题 A:路径规范化与路径遍历

  • supportfileNames 中的路径直接被传递给了 addPendingTab。如果这些路径来源于用户输入(如拖放、命令行参数等),可能包含 ../ 等路径遍历字符。
  • 改进建议:确保在进入此逻辑前,所有路径都已经通过 QFileInfo::canonicalFilePath()QDir::cleanPath() 进行了规范化处理。如果 supportfileNames 已经是规范化的路径(从上下文推测可能已经处理过),则无需担心。

问题 B:符号链接处理

  • 如果用户打开的是一个符号链接,QFileInfo::fileName() 会返回链接文件本身的名称,这通常是符合预期的。但如果业务逻辑中需要追踪真实文件,应使用 canonicalFilePath(),需根据业务需求确认 truePathfilepath 是否需要指向真实文件。

🚀 综合改进后的代码建议

    // 使用懒加载机制:只立即加载并激活第一个支持的文件
    // 其他支持的文件作为待加载标签页,用户点击时才加载内容
    if (!supportfileNames.isEmpty()) {
        // 第一个文件立即加载并激活
        addTab(supportfileNames.first(), true);

        // 剩余支持的文件使用懒加载
        for (int i = 1; i < supportfileNames.size(); ++i) {
            QString filepath = supportfileNames[i]; // 使用局部变量,避免潜在的悬垂引用,依赖移动语义提高性能
            QFileInfo fileInfo(filepath);
            
            PendingTabInfo pendingInfo;
            pendingInfo.filepath = filepath;
            pendingInfo.truePath = filepath;
            pendingInfo.displayName = fileInfo.fileName();
            // 建议在 PendingTabInfo 定义处使用默认初始化:isTemFile = false, cursorPosition = -1
            pendingInfo.isTemFile = false; 
            pendingInfo.cursorPosition = -1;
            
            addPendingTab(pendingInfo);
        }
    }

    // 后添加不支持文件(在最后编辑页面显示)
    // 不支持的文件无法懒加载,需要立即加载以显示错误提示
    // 注意:使用 C++11 基于范围的 for 循环替代已废弃的 foreach 宏,并使用 const 引用避免拷贝
    for (const QString &var : otherfiles) {
        addTab(var, true);
    }

附带建议(针对 PendingTabInfo 结构体的优化):

struct PendingTabInfo {
    QString filepath;
    QString truePath;
    QString displayName;
    bool isTemFile = false;      // 提供默认值
    int cursorPosition = -1;     // 提供默认值
};

希望这些审查意见对你有所帮助!如果有任何疑问,欢迎随时提问。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@add-uos
Copy link
Copy Markdown
Contributor Author

add-uos commented May 14, 2026

/merge

@deepin-bot deepin-bot Bot merged commit 30d885a into linuxdeepin:master May 14, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants