我正在参加「掘金·启航计划」
此文不是水文。。。只是刚好有这个活动参加一下
前言
众所周知,2023年chatgpt横空出世,科幻电影里的人工智能终于在现实社会中展现出雏形,正在逐渐改变世界。
作为一个喜欢探索新鲜事物的程序猿,自然也不会错过这个未来一片光明的新鲜事物,chatgpt发布之后我就注册了账号去试玩了一下,当时确实很震惊,chatgpt3当时的问答效果比市面上已经存在的人工智障完全是降维打击。不过玩了一段时间之后发现chatgpt也不是很神,它相当于把搜索引擎的答案拼接给你回答,而且可能存在为了回答直接现场胡编乱造(所以使用需谨慎)。
在一番玩耍之后我开始了一些技术方面的思考,当然不是大数据模型学习,我能力不够。作为一个前端从业者,从前端角度出发我比较感兴趣他们是他们实时进行回答的交互和动态格式化代码块高亮是怎么实现的。于是呼撸起袖子就是干,打算自己手撸一个和chatgpt效果差不多的问答页面。当然了也有好奇的小伙伴要问了chatgpt已经出了好久了为什么现在才开始仿写,因为一直加班,公司一直在优化人员,工作量真是加量不加价,五一放假才刚好有空。。。。
发现问题
项目搭建
毕竟只是实现一个问答功能,撸起袖子直接开干。
上来就是一手vue3创建项目,毕竟练手项目尝试下新技术增加技能熟练度
npm init vue@latest
然后就直接开撸,通过chatgpt接口实现通过WebSocket进行长连接,然后openApi白嫖的是国内一个老哥建设的不用翻墙版的网站有兴趣可以去玩玩,我当年自己搞得openapi不幸被封了,淦。
mackdown展示
因为chatapi返回的是mackdown格式的字符串所以markdown.converter.js插件进行转化为dom结构进行展示
//npm安装
npm install showdown --save
使用
import showdown from "showdown";
let converter = new showdown.Converter();
let htmlStr='mackdown格式字符串'
converter.makeHtml(htmlStr)
代码高亮
ok很轻松搞定,然后就是代码块高亮百度之后第一个推荐的就是highlight.js 话不多说直接开整
npm install highlight.js --save
mian设置
//导入函数
import hljs from 'highlight.js';
//导入样式
import 'highlight.js/styles/an-old-hope.css'
//直接注册为指令
app.directive('hljs', el => {
let blocks = el.querySelectorAll('pre code');
Array.prototype.forEach.call(blocks, hljs.highlightBlock);
});
使用文件使用
//使用指令直接添加代码块高亮
<div v-hljs>
<pre><code></code></pre>
</div>
实际效果:
效果还可以
问题
实现之后当然进入自测环节,俗话说没有bug的程序员不是好的单身狗,不出意外就是出了意外。。。
我问了三个问题之后肉眼可见的发现问答速度明显变慢,我拖动鼠标移动也是明显放慢n倍甚至我mac的风扇都疯狂转动,直觉告诉我这不正常。
然后开了性能看一下浏览器性能消耗
看完结果我蒙了,这是什么鬼啊,我只是个菜鸟的前端,我的代码虽然不优雅也不至于会搞出来这种效果。
尝试修复
脑子宕机三秒之后开始找原因,自己的bug自己修。。。欲哭无泪,初步怀疑是渲染次数太多了,于是从这个角度开始
常任务切片
因为是卡死了,cpu还吃满了所以怀疑是微任务队列塞满了所以采用切片尝试解决
await new Promise((resolve)=> setTimeout(resolve));
实际测试结果好了一丢丢,但是渲染明显能看到代码块展示闪烁,最主要是问到第四次问题依旧卡顿。失败
使用Worker
因为js为单线程语言所以在处理长任务时候也会选择主动开启辅助线程进行操作。
//指令中处理逻辑
for (let i = 0; i < blocks.length; i++) {
var blob = new Blob([`(${setHljsData.toString()})()`]);
var url = window.URL.createObjectURL(blob);
var worker = new Worker(url);
worker.onmessage = (event) => { blocks[i].innerHTML = event.data; }
worker.postMessage(blocks[i].textContent);
}
而且官方也有例子,
我以为这次终于可以解决问题,没想到没想到,直接页面给我干崩了可能这种处理不适合ws实时接收吧,消耗资源太大了。
曙光
尝试好多种方法失败之后,我看了一下hljs的源码发现high.js功能是比较强大但是相应的太重了,不是轻量级的对于多次渲染来讲,不符合场景,所以我决定更换代码块高亮插件。于是乎我提问了chatgpt咨询轻量级的代码块高亮插件,它给我推荐了Prism.js(有时候chatgpt还是很好用的)。我尝试进行替换发现,真的好用,展示效果类似但是性能消耗天差地别。而且Prism.js还有很多功能可进行按需使用。非常好用就是主题没有high.js多。
替换后性能消耗
总结
程序员还是要勇攀高峰,虽然五一没有怎么休息但是很充实,在这个假期又是锻炼了一下自己解决问题和动手能力,又是让自己成长了一点点希望能早日追上公司前端架构师的脚步。有兴趣的朋友点赞关注可以私信问我要源码,一起学习一起成长。冲冲冲