• 请不要在回答技术问题时复制粘贴 AI 生成的内容
0x01Dev
V2EX  ›  程序员

大佬们,求助一个前端问题, AI 流式输出做了一个打字机效果,然后正在输出的时候选中部分文字,选中区域总会闪来闪去,有啥优化方法么

  •  
  •   0x01Dev · Jul 21, 2025 · 2157 views
    This topic created in 313 days ago, the information mentioned may be changed or developed.

    好像是 dom 频繁刷新的问题,我看 deepseek 也会这样,但是豆包好些不会,有啥优化的方法么

    7 replies    2025-07-21 17:43:53 +08:00
    chairuosen
        1
    chairuosen  
       Jul 21, 2025
    闪是选中字的 dom 被改了。试试每个字套一个 span 试试,这样新字出现不会改旧的 dom (我没试过)
    dcsuibian
        2
    dcsuibian  
       Jul 21, 2025
    #1 说的对,刚刚拿 vue 试过了。
    <p>{{content}}</p> // 频繁闪
    <span v-for="(content, index) in contents" :key="index">{{ content }}</span> //不会闪
    但是问题也来了,如果你每次拿到字符串就渲染一个<span>,那跟 markdown 渲染出来的效果就不一致了。
    ooo4
        3
    ooo4  
       Jul 21, 2025
    https://www.npmjs.com/package/vue-mdr
    如果是 vue 可以试试这个
    tinx
        4
    tinx  
       Jul 21, 2025
    换个思路,正在输出的时候禁止选中
    chairuosen
        5
    chairuosen  
       Jul 21, 2025
    @dcsuibian 可能 render 函数可解。每次拿到 md2html 的 html 后,用 xmlparser 转成结构化数据然后再转成 jsx ,这个过程纯文字部分也都套 span 解决
    ooo4
        6
    ooo4  
       Jul 21, 2025
    @ooo4 就是 react-markdown 的思路,大概就这个流程 markdown string-> markdwon ast -> html ast -> vue node ,然后再 vuenode 里面的文本再进行拆分,用 span 标签包裹,由于使用了 vue 进行渲染,那么 vue 的 diff 机制只会渲染新增的元素,相同的 vnode 就会跳过 dom 更新,这样就能保留状态
    ljl024
        7
    ljl024  
       Jul 21, 2025
    markdown 的渲染都是分行的,基本上大模型也不会输出特别大的单个文本块。
    如果是把 markdown 算成 html 再渲染,可以用换行符做一下拆分。除了最后一行,应该不会发生变更。
    然后再参考 #4 的,把输出中的最后一行改成不允许选中。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2269 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 00:48 · PVG 08:48 · LAX 17:48 · JFK 20:48
    ♥ Do have faith in what you're doing.