一个用来在前端展示简单的网页代码的项目,项目地址:Codepage。开发过程中主要使用到的知识是:iframe
,script
。
iframe
起初页面的功能设计打算参考别人的博文中:
- 使用真的src地址渲染演示结果,通过与
iframe
通信实现reload
等功能; - Scss通过在线接口进行编译,本地重载
iframe
中的css; - 编辑器中使用
emmet
可以快速的开发html、css;
在实际的开发过程中,查看MDN iframe文档中查看到srcdoc
这在html5中新的属性。这个避免使用src
的一个麻烦,比如插入<script src="">
, 在src中需要使用document.createElement
创建脚本对象,然后设置属性,最后插入文档中的对应位置。
如果直接使用element.innerHTML
插入script
会导致脚本资源不会被加载,详细原因参考:Can scripts be inserted with innerHTML?。换成srcdoc
之后使用模板字符串替换一下就会刷新页面,怎么简单怎么来(Vue SFC Playground中也是这么做的)。
|
|
这段是渲染结果的VUE
的代码,主要功能是允许iframe中的演示结果使用尽可能多的沙盒功能同时也允许iframe内部调用全屏函数。
console
将在 iframe
中 console
输出的内容同步显示到主界面上。
script
script
标签有属性type
,如果这个type
的类型可以是MIME或是module
,如果是其他的则被当成数据对待。
所以我在当前hugo主题中添加palyground
,渲染的时候把需要插入显示的代码放入script中,因为我还不太会用hugo去生成复杂的逻辑,比如gzip压缩等,所以目前的逻辑还是先把代码存储到页面,由JavaScript
生成网页。
|
|
这个方法在很多的WebGL教学中也被使用,将顶点着色器和片源着色器的代码也放在script标签中,当然这个也就是我们学习的时候使用,去翻看一些3D引擎的代码,着色器都是动态生成的代码(这群人玩字符串都要优化到魔怔了)。
LESS和Scss支持
起初打算使用在线接口去实现,但是大家都是各种的CORS身为懒人的我自然懒得去尝试哪个网站的跨域完全开放的,也懒得去搭建一个代理服务。于是想到刚刚上大学的时候看到了LESS直接在HTML中直接使用,开始思考直接在前端引入代码进行编译。这点LESS很容易实现,毕竟他有直接的JavaScript的实现。
问题来到了Scss那边,目前找到最好的解决方案是三年前的项目,直接编译到WASM的Scss的编译器。于是目前LESS和Scss都实现了在前端的编译,由于编译、页面重载是耗时的操作,于是在编辑代码的变动处增加防抖限制。
参数压缩
其实这个在实际的项目中没有太多的作用,因为仔细想了想,项目的目的就是分享百十行内的代码分享,目前使用get请求的参数传递,从目前的测试看下来,不同浏览器(IE在我这除名)的get请求大概可以支持65536(或者32768)个字符,加上代码分享的时候使用base64
编码后加入get请求,大概可以容纳500行代码,足以实现项目的设计目标。
但是中间都走了一段时间的弯路,也要记录下来给个纪念。
Haffman
如果想对哈夫曼编码有直观的认识,这个网站->Haffman Tree Generator;
最开始我在思考base64
编码的结果当中重复的字符串比较多,实际的字符串出现的字母数量不多,比较长点的路径长度才到9,实际测试过程中, 压缩率大概到50%1,加上相比全文可以忽略不计的字典,压缩率还是相当可以,压缩后可以容纳大约1000行代码。
但是这个对于我在博客中使用还是很麻烦的,也很不方便之后其他人集成(虽然没有人会用这个项目就是啦~)。因为不仅仅我内部需要实现一套Haffman编码的逻辑,插入的地方也需要一套编码逻辑。
Gzip
其实最开始我是把目光投向Brotli
,但是Brotli
编码没有找到比较好的浏览器解决方案。后来发现比较新的接口CompressionStream和DecompressionStream,这俩个接口可以实现在web端直接压缩、解码数据,使用起来十分方便,如下是编解码的所有代码。
|
|
Gzip
在代码中的压缩率可以到20%2,这是一个相当恐怖的压缩率,对比一下,Haffman这种没有窗口没有默认字典的压缩方式的确是粗枝大叶。
这里也要吐槽一下,MDN的中文文档更新速度实在是太慢了,得亏是高中的英语能力还是支持的了我看懂英文文档的!!这个Compress接口在中文文档中都无法找到(写这个博客的时候想要贴中文介绍链接,我居然找不到)!还不了解怎么去给MDN打工做翻译啊,感觉翻译这个的中文文档需要翻译很多和这个相关联的页面。
总结
其实项目没有多少代码,估计四百行代码就实现了配置等所有的功能。当时考虑到应用比较小,打算自己写点组件锻炼自己,没有使用组件库。
之所以代码可以这么简短,还是因为有类似Monaco Editor、VueUse、Sass.js这些已经完善的基础功能,我只会傻傻的把他们拼接到一起,做实现自己的一个小想法。
最后是发现来来回回我还是绕到了WASM,这个我在大学时候尝试用来写毕业论文的工具。当时用这个实现了一个数字电路模拟器,用C++写了很多界面渲染的代码,以及电路的状态管理。第一次接触这个技术是2019年的时候,当时觉得学习这个需要熟悉JavaScript
还需要熟悉C++
,对于我这样的懒人大抵是没有机会了。现在再看看,Scss这边的功能也是依赖于这项功能,包括如今火起来的Rust前端框架,也大多依赖与这项功能。同时我自己的另外一个想法,也不得不使用WASM来解决问题。
问题有俩点,前后端对图像的渲染不一致;运行时的后端渲染功能现在必须要用前端实现。
前后端渲染不一致很正常,一般图元信息都是前端来渲染,和后端用的的工具库都不一样,想要调整成一样的多少有点麻烦。这个时候我就在思考能不能让前端的工具库被我们的后端使用呢?这个肯定可以,而且方法特别多,但是接着就到了第二个问题来了。
这个时候需要我们来接手后端的工作,如果使用传统的前端代码去做,那我们还是写俩套,于是不得不去想办法使用WASM让后端的代码可以直接在前端被运行,最少的代码改动。加油,目前已经在加班加点工作了,预计月底可以做到把后端的渲染移植到前端来吧!!到时候再继续写博文记录吧。