代码之家  ›  专栏  ›  技术社区  ›  Zack Burt

根据CSS规则测量文本高度\u无需浏览器渲染\u用于虚拟化列表,提前指定高度

  •  0
  • Zack Burt  · 技术社区  · 6 年前

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

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

    我认为,必须有一些解决办法来计算字符串高度提前,根据字包装,最大宽度和字体规则。

    string-pixel-width this piece of code 生成字符宽度[*]的映射。然后,一旦我们知道每一个文本有多宽,当它超过计算出的最大行宽时,我们将每一行分开,最后通过行计数推断列表元素的高度。这将需要一点算法摆弄由于打破字,但有图书馆来帮助这一点 css-line-break 看起来很有希望。

    [*]我们将不得不对其进行一些修改,以考虑所有Unicode字符范围,但这是微不足道的。

    0 回复  |  直到 6 年前
        1
  •  4
  •   Hans Koch    6 年前

    使用canvas功能来度量文本可以有效地解决这个问题。

    电子画布文本的计算方法与普通文本相同,但在渲染过程中存在一些差异,特别是在抗混叠方面 不影响计算 .

    您可以使用

    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 ,它已使用此方法。此外,您还可以分叉源代码(MIT许可证),通过启用electron中的实验性度量特性并利用它来修改它以获得额外的性能。

    new BrowserWindow({
      // ... rest of your window config ...
    
      webPreferences: {
        experimentalFeatures: true
      }
    })
    

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

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

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

    推荐文章