如何优化 GoldenDict 查词速度

各位检索一个词的平均耗时是多少呢?
我这里软件和词典都在 SSD 里,单独激活 LDOCE5++,随便搜一个词例如 dictionary,需要消耗大约半秒,如果把其他常用的一些词典勾上就需要超过一秒。

我对这个速度不是特别满意,这不是我预期里有索引的速度。这应该是哪里我配置出了问题,没搜到相关的帖子就来问一问

操作系统是 Windows 10 22H2
GD 是坛友的 fork 版本

Goldendict 23.04.02-QingmingFestival.230402.ce9436f9
windows winnt 10.0.19045 Qt 6.4.3 x86_64-little_endian-llp64
Visual C++ Compiler: 192930148
Flags: MAKE_ZIM_SUPPORT MAKE_EXTRA_TIFF_HANDLER MAKE_CHINESE_CONVERSION_SUPPORT
1 个赞

GoldenDict的索引没问题的,我测试过查词平均耗时小于5毫秒(也可能是3毫秒,记不清了,SSD 三星 980 Pro。可能拖慢速度的地方就是正则预处理文本和浏览器加载这两个步骤,要测试过才知道。

1 个赞

我怀疑是浏览器问题,用官方版本的试一下。官方版本也有问题就是正则的原因,没问题就是浏览器的原因。

1 个赞

我感觉上是因为浏览器加载

当我查一个词的时候,它会经过下面几个阶段:

  1. 无反应
  2. 白屏
  3. 从上到下显示元素

GoldenDict_HR9TyXvafY

这么做能提升加载速度的依据是什么?谁来讲讲。

难道是因为原 MDX 存在不规范标签,提取时自动“修复”了,所以重新打包后加载变快了?

1 个赞

动画里白屏的时候,文本已经处理完成,到了浏览器加载的阶段。

2 个赞

不明白你说的提取和展开指的是什么?如果你指的是解析原 html 生成换行+缩进的新 html,那可能要做对比实验:
1、测原单行 MDX 加载耗时
2、测不提取转多行 MDX 加载耗时
3、测提取转多行 MDX 加载耗时
4、测提取转单行 MDX 加载耗时

为什么把空格改成换行就能提升本地网页加载速度?这不科学吧?

试了下 goldendict-1.5.0-RC2-614-g1cd1c300 无此问题,应该是 fork 版限定的问题了
那应该优先怀疑 QtWebEngine 和 QtWebKit 行为的区别

我日用的浏览器 (Vivaldi) 之前有很长时间有这种白屏卡顿的现象,也可能是 Chromium 的什么问题
另外我不用深色模式查词也要卡半秒钟,应该不是深色模式的问题

不是很理解单行 HTML 和多行 HTML 的区别,这具体来说会有什么变化呢,如何影响渲染

输入完以后按 enter 的过程是:

让浏览器加载 gdword://localhost?word={GDWORD}

GD 处理请求 → 判断 请求 是 gdword:// → 合成结果。

所以 Inspector → Network 应该基本反映了查询新词过程中大部分时间。

加载过程中碰到比如说 bres:// 也会生成新的请求 → 读取词典中的资源 → 转换成能显示或者音频的格式。

在我的机器上 500ms~1000ms 基本是平均水平。

至于怎么优化,要看代码分析咯。

2 个赞

你可以点 Performance 里面的这个按钮,然后加载好了按停止,在 Summary 栏目下可能会有一些发现。

3 个赞

我觉得 gd 生成的网页不算复杂,又没有动画,加载资源以外的时间应该不多,就算多我们也做不了啥 (一般人又不能随便改进 chromium 本体 :sweat_smile: )。

感谢你详细的解释。看来 500ms 到 1000ms 是正常的。
那么无反应的时候就是在和后端交互,一小会白屏是浏览器在初始化和通过网络获取资源,最后渲染完。

的确读字体可能要花费不少时间,我个人也认为词典没必要携带字体,指定一下哪里用 sans 哪里用 serif 就行了。
不过图里看起来是没读到?报错了

我觉得这个速度是有问题的是因为,其他的词典软件,包括官方的 GD,加载都是无感的。
我对导致这个问题的原因有以下的猜测:

  1. 也许它们是没有前后端通信的
  2. 也许有哪里有同步行为阻塞了浏览器的渲染
  3. 也许 WebKit 和 WebEngine 的渲染行为有什么区别

图为 Golden Dict 的 Performance 测试,它用 655.99 毫秒 (517.34 毫秒网络传输 + 138.65 毫秒资源加载)加载 gdword://localhost,又过了快 1 秒钟才开始 First Content Print

图为欧路的 Performance 测试,它用 40.34 ms (1.75 ms network transfer + 38.59 ms resource loading) 读了一个 http://eusoft_cef/html 进来,然后根据 html 再去找其他外部资源(70ms)又过了几十毫秒后,界面就显示了出来

1 个赞

不懂 web 开发,不过看起来 gd-custom.js gd-built-in.js webchannel.js iframe-resizer.js 这几个应该可以无脑标一个 defer/async

如果把 <head> 里用 jquery 的地方都改成现代的 api,整个 jquery 也可以 defer/async?

具体的代码在这里,你可以看一下:

合成 <head>https://github.com/xiaoyifang/goldendict/blob/8475353a905a9a3123a9089396e5828da1dc0546/article_maker.cc#L37-L198

.js https://github.com/xiaoyifang/goldendict/tree/staged/scripts

2 个赞

可以加个defer ,来个PR :smile:

1 个赞

试了下,加了defer,脚本报错