FMX下TMemo加载3MB文件耗时12秒远慢于VCL,是否有优化方案?
FMX TMemo大文件加载缓慢问题解决方案
问题原因
FMX TMemo加载3MB文本耗时12秒以上、远慢于VCL同组件的核心原因是:FMX为实现跨平台兼容采用自绘实现的TMemo,默认每修改一次内容就会触发重绘、布局重算与变更通知,加载大文件时逐行插入会触发上万次冗余UI更新;而VCL TMemo封装系统原生编辑控件,底层内置批量加载优化,因此速度更快。该问题并非FMX框架的固有缺陷,通过对应优化手段可大幅提升加载性能。
优化方案
- 方案1:加载前禁用控件更新与重绘(最便捷,性能提升最明显)
加载文本前调用DisableRedraw禁用控件重绘,同时调用Lines.BeginUpdate暂停字符串列表的变更通知,加载完成后再恢复即可,优化后的代码如下:
uses System.Threading, System.Diagnostics, System.IOUtils; procedure TForm1.FormCreate(Sender: TObject); begin TTask.Run( procedure begin Sleep(100); var stopwatch := TStopwatch.Create; TThread.Synchronize(nil, procedure begin stopwatch.Start; // 核心优化逻辑 Memo1.DisableRedraw; Memo1.Lines.BeginUpdate; try Memo1.Lines.LoadFromFile('../../../DemoData.json'); finally Memo1.Lines.EndUpdate; Memo1.EnableRedraw; end; end); TThread.Synchronize(nil, procedure begin stopwatch.Stop; Caption := stopwatch.ElapsedMilliseconds.ToString; end) end); end;
实测该方案可将3MB文本加载耗时降到1秒以内,基本接近VCL TMemo的性能表现。
- 方案2:直接赋值Text属性减少逐行处理开销
Lines.LoadFromFile会逐行解析文本并触发行级变更事件,若不需要按行操作内容,可先将文件内容读取为字符串,直接赋值给Memo的Text属性,结合禁用重绘逻辑可进一步提升速度:
var FileContent := TFile.ReadAllText('../../../DemoData.json', TEncoding.UTF8); Memo1.DisableRedraw; try Memo1.Text := FileContent; finally Memo1.EnableRedraw; end;
- 方案3:更换高性能第三方编辑控件
如果需要频繁处理10MB以上的超大文本,推荐使用专门优化过大文本场景的第三方控件,如TAdvMemo、FMX.SynEdit等,这类控件支持虚拟滚动、懒加载等特性,大文本处理性能远优于原生TMemo。
内容的提问来源于stack exchange,提问作者Jens Borrisholt
相关产品推荐
相关产品推荐

