如何实现AI搜索前端打字机效果的方案演进?
摘要:在当代前端开发领域,打字机效果作为一种极具创造力与吸引力的交互元素,被广泛运用于各类网站和应用程序中。本文力求以通俗的语言和严谨的思路,深入剖析打字机效果在不同阶段演进的关键技术难点和优劣势。
作者:vivo 互联网前端团队 - He Yanjun
在当代前端开发领域,打字机效果作为一种极具创造力与吸引力的交互元素,被广泛运用于各类网站和应用程序中,为用户带来独特的视觉体验和信息呈现方式,深受广大用户的喜爱。
本文将深入介绍在AI搜索输出响应的过程中,打字机效果是怎样逐步演进的。力求以通俗的语言和严谨的思路深入剖析打字机效果在不同阶段的关键技术难点和优劣势。
1分钟看图掌握核心观点👇
一、前言
在如今基于AI搜索的对话舞台上,如果一段文字像老式打字机一样逐字逐句展现在屏幕上,那将是一种具有独特魅力的吸引力。
话不多说,先来看下最终的实现效果。
二、引言
在AI搜索场景中,由于大模型基于流式输出文本,需要多次响应结果到前端,因此这种场景十分适合使用打字机效果。
打字机效果是指在生成内容的场景中,文字逐字符动态显示,模拟人工打字的过程,主要是出于提升用户体验、优化交互逻辑和增强心理感知等方面的考量:
缓解等待焦虑,降低“无反馈”的负面体验。
内容是逐步响应的,打字机效果可以很好地提供“实时反馈”,用户可以感知到系统正在工作,从而减少了等待过程中的不确定性和焦虑感。
模拟自然交互,增强“类人对话”的沉浸感。
对话交流具有停顿、强调等节奏感,通过实时打字的模拟,跟容易拉近与用户的心理距离,增强对话感和沉浸感。
优化信息接收效率,避免“信息过载”。
如果一次性展示大量密密麻麻的文字,用户需要花时间筛选重点,容易产生抵触,通过打字机效果可以缓和阅读节奏,减少视觉和认知负担。
强化“AI生成”的感知,降低对“标准答案”的预期。
使用户感知到是AI实时计算结果,而非预存的标准答案,有助于用户理性客观地使用工具。
三、早期实现方案——纯文本逐字符打字效果
最开始的产品功能,需要根据用户输入的搜索词,流式输出并逐字符展示到页面上,这可以说是打字机效果的入门级实现了,不依赖任何复杂的技术,其流程图大致如下所示。
3.1 详细说明
前端会定义一个字段用来缓存全量的markdown文本,每次服务端流式响应markdown文本到前端时,前端都会将其追加到这个缓存字段后,然后基于marked依赖库将全量的markdown文本转换为html片段。
要实现逐字符渲染的动画效果,就需要定时更新文本。定时功能一般采用setTimeout或setInterval来实现,而更新文本可以考虑innerHTML和appendChild的方式,这里采用的innerHTML方式插入文本,核心代码如下所示。
let fullText = 'test text';// 全量的html文本
let index = 0;// 当前打印到的下标
let timer = window.setInterval(() => {
++index;
$dom.innerHTML = fullText.substring(0, index);
}, 40);
3.2 innerHTML与appendChild的核心区别对比
为什么选择innerHTML而非appendChild?
由于服务端是流式返回markdown文本,因此每次返回的markdown文本可能不是完整的。
举个例子如下。
先返回下面一段markdown文本
** 这是一个
再返回下面一段markdown文本
标题 **
先返回的文本会当作纯文本展示,再返回的文本会与先返回的文本结合生成html片段如下
<strong>这是一个标题</strong>
如果使用appendChild的话,就不好处理上述场景。
3.3 小结
这种方式的优点就是简单易懂,很容易上手实现,也没有任何依赖。
但是,它的缺点也是显而易见的。比如,我们无法方便的添加一些额外的动画效果来增强视觉体验,如光标闪烁效果;对于一些复杂文本内容,或者需要更加灵活地控制展示细节时也会显得捉襟见肘;并且每次通过innerHTML渲染文本时,都触发了dom的销毁与创建,性能消耗大。
四、需求难度进一步提升
随着产品的迭代,业务要求打字内容不仅是纯文本,还需要穿插展示卡片等复杂样式效果,如下图所示。
卡片的类型包括应用、股票、影视等,需要可扩展、可配置,并且还会包括复杂的交互效果,如点击、跳转等。
很明显,基于早期的实现方案已经远远不能满足日益增强的业务诉求了,必须考虑更加灵活高效的技术方案。
五、现代框架下的实现——基于Vue虚拟dom动态更新
通过上述的分析,打字内容中要穿插展示卡片,显然需要使用单例模式,否则如果每次打字都重新创建元素的话,不仅性能低下,而且数据和状态还无法保持一致。
