gpt4 book ai didi

electron - 根据 CSS 规则测量文本高度 – _无需浏览器渲染_ – 与虚拟化列表一起使用,提前指定高度

转载 作者:行者123 更新时间:2023-12-03 06:25:30 24 4
gpt4 key购买 nike

我一直在 Electron (Chrome) 和 React 中实现一个聊天客户端。我们的首要任务是速度。那么,我们有必要使用虚拟化列表组件(也称为“缓冲渲染”或“窗口渲染”)。我们探索了react-virtualized、react-window 和react-infinite 等。

所有这些组件的一个共同问题是,如果支持可变高度的列表元素,则需要提前知道高度。现在,有些聊天很长,有些聊天很短,这对我们来说是一个挑战。 (借助 EXIF 数据和 ffprobe,图像和视频变得很容易)。

因此,我们面临着测量高度的挑战,同时还要努力提高性能。一种明显的技术是将元素放在视口(viewport)外的浏览器容器中,执行测量,然后渲染列表。但这在性能要求方面伤害了我们。像react-virtualized/CellMeasurer(原作者不再维护)和react-window这样的软件使我们可以使用这种技术,内置在库中,但性能有点慢而且不可靠。可能性能更高的类似想法是使用后台 Electron 浏览器窗口来进行渲染和测量,但我的直觉是这不会快得多。

我认为必须有某种解决方法可以根据自动换行、最大宽度和字体规则提前计算出字符串高度。

我目前的想法是使用像 string-pixel-width 这样的库以便在我们通过 API 获取文本数据后立即计算行高。基本上,该库使用 this piece of code生成字符宽度映射 [*]。然后,一旦我们知道每个文本的宽度,我们就会在每一行达到计算的最大行宽度时将其分开,最后通过行数推断列表元素的高度。由于断词,这将需要一些算法摆弄,但有一些库可以帮助解决这个问题 – css-line-break看起来很有希望。

[*] 我们必须稍微修改它以考虑所有 Unicode 字符范围,但这很简单。

我还没有完全探索过一些选项,包括 python weasyprint 项目和 facebook-yoga 项目。我对你的想法持开放态度!

最佳答案

使用 Canvas 功能测量文本可以高效地解决此问题。

Electrons canvas text is calculated the same as the regular text, there are some diffrences in rendering though especially in reguard of anti-aliasing but that does not affect the calculation.

您可以使用以下命令从任何文本中获取 TextMetrics

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

// Set your font parameters
// Docs: https://developer.mozilla.org/en-US/docs/Web/CSS/font
ctx.font = "30px Arial";

// returns a TextMetrics object
// Docs: https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics
const text = ctx.measureText('Hello world')

这不包括换行符和自动换行,对于此功能我建议您使用 text package from pixijs ,它已经使用了这个方法。此外,您可以 fork 源代码(MIT 许可证)并通过在 Electron 中启用实验性 chromium TextMetrics 功能并使用它来修改它以获得额外的性能。

这可以在创建窗口时完成

new BrowserWindow({
// ... rest of your window config ...

webPreferences: {
experimentalFeatures: true
}
})

现在到我在评论中提到的部分,因为我不知道你的代码库、你的计算以及一切都应该在渲染过程中发生。如果不是这种情况,您绝对应该将代码从主进程移至渲染进程,如果您执行文件访问操作或任何特定于节点的操作,您仍然应该执行此操作,但在所谓的预加载脚本中

它是 webPreferences 中的附加参数

webPreferences: {
preload: path.join(__dirname, 'preload.js')
experimentalFeatures: true
}

在此脚本中,您可以完全访问节点,包括 native 节点模块,而无需使用 IPC 调用。我不鼓励对任何类型的多次调用函数进行 IPC 调用的原因是它本质上很慢,您需要序列化/反序列化才能使它们工作。 Electron 的默认行为更糟糕,因为它使用 JSON,除非您使用 ArrayBuffers。

关于electron - 根据 CSS 规则测量文本高度 – _无需浏览器渲染_ – 与虚拟化列表一起使用,提前指定高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59440762/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com