23 pontos por princox 2026-03-30 | 3 comentários | Compartilhar no WhatsApp

Descobrir quantas linhas um texto ocupa no navegador é mais complicado do que parece. Normalmente usa-se getBoundingClientRect ou offsetHeight, mas esses métodos forçam o navegador a recalcular o layout. O chamado reflow de layout. Do ponto de vista do navegador, isso é uma tarefa bem pesada.
O Pretext resolve esse problema de outra forma. Com measureText() do Canvas, ele obtém diretamente do mecanismo de fontes a largura dos caracteres e, depois disso, o cálculo das linhas é feito apenas com operações aritméticas puras usando valores de largura em cache. Não acessa o DOM em nenhum momento.

const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')
const { height, lineCount } = layout(prepared, textWidth, 20)

O desempenho também impressiona. Com base no layout de 500 textos, prepare() leva cerca de 19 ms, e depois layout() fica na faixa de 0,09 ms.
Dois modos de uso
Se você só precisa da altura, a combinação prepare() + layout() resolve tudo. Pode ser usada para implementar listas virtualizadas, manter a posição de rolagem ou verificar se um texto gerado por IA ultrapassa os limites de um botão.
Se quiser controlar diretamente o layout linha a linha, dá para usar APIs como layoutWithLines(), walkLineRanges() e layoutNextLine(). Também pode ser integrado com Canvas, SVG, WebGL e renderização no servidor, além de lidar com layouts em que a largura varia por linha, como quando o texto contorna uma imagem.
Há suporte até para emojis, CJK e texto bidirecional como árabe. Um projeto de chenglou, criador do React e do Relay. ⭐ 7.1k
https://github.com/chenglou/pretext​​​​​​​​​​​​​​​​

3 comentários

 
xenoside 2026-03-31

No link do GitHub lá embaixo, parece que vários %E2%80%8B (zero-width space) estão sendo anexados.
js .replace(/\u200b/g, '')

 
xguru 2026-03-30

Acho que a página https://chenglou.me/pretext/editorial-engine/ que está na demo é a que mostra isso melhor.

 
smboy86 2026-03-30

Não é algo que eu conheça e use bem, então peço compreensão desde já.

Pelo que entendi, ele recalcula com base no measureText do canvas...
Não consigo confiar nessa API.
Mais precisamente, não é que eu não confie na API em si,
mas, para renderizar o DOM da mesma forma, é preciso fazer os valores de condição coincidirem perfeitamente para que
a altura e a forma que você vê no navegador sejam idênticas também quando trazidas no formato da API.
Tenho um pesadelo arrepiante de não ter percebido isso e ficar me perguntando por que os valores saíam diferentes e surgiam bugs...