当前位置: 首页 > 科技观察

手写简单浏览器思路总结

时间:2023-03-16 00:21:24 科技观察

本文转载自微信公众号《神光的编程秘籍》,作者神说必有光。转载本文请联系神光编程秘籍公众号。其实这个想法我早就有了,只是一直没有开始写。正好赶上掘金的每日更新,想再实现一下,再把实现过程记录下来。思路来源前段时间在研究babel,写了一本小册子。有一个基于babel解析器实现js解释器的案例。进一步,添加渲染部分,编写一个简单的浏览器。最近在看postcss的源码,也整理了一下css解析器的实现,可以自己实现css到ast的解析。之前写过html解析器,类似的东西写过很多次,比如vue模板解析器,wxml解析器等,html到ast的转换也能实现。最近还写了一篇eventloop和js引擎、渲染引擎的关系,还有一篇跨端引擎原理的文章,描述了如何使用eventloop将js的解释执行和渲染结合起来的css,并共享一个线程来完成Rendering和逻辑,以及如何基于容器思想实现一个跨端引擎。把这些东西放在一起其实就是一个简单的浏览器实现思路,所以想利用这个updateactivity来实现。一是对这段时间的产出进行综合,二是也可以加深对前端代码运行环境的理解。也希望能给大家一些启发。实现思路概览本文将讲实现思路,具体实现从下一篇开始。html解析器我们会实现一个html解析器,将html字符串解析成dom树,使用遍历的方式来实现,和vue模板编译器的解析器是一致的。css解析器我们将实现一个css解析器,将css字符串解析为css树。实现思路和postcss解析器类似。布局引擎有了htmlparser和cssparser之后,将两者合并成一个rendertree,然后实现布局引擎将样式计算为具体的坐标。一旦渲染引擎有了特定的坐标,它就可以渲染了。这里我们基于画布进行渲染。至此,界面上html和css的显示就完成了。js解释器js字符串的解释和执行首先需要一个js解析器,自己没有实现,直接用acron,然后自己做解释执行。它将实现范围和功能执行,注入几个绑定事件,并实现dom操作api的实现。事件循环渲染和逻辑执行都实现了,但是如果两者都运行在同一个线程中,则需要通过事件循环进行调度。js的执行方式是一个宏任务,所有微任务。每次循环结束,检查是否需要渲染,渲染以每帧16ms的速率刷新。我们将使用常量setTimeout来实现事件循环不断获取事件的逻辑,因为无限循环会阻塞主线程(在C++中,可以使用无限循环来实现事件循环,因为其他线程将事件对象放入队列中).这样就可以根据帧率刷新渲染,实现js逻辑的执行。网络资源下载实现了html、css、js的渲染和执行,也实现了事件循环调度。这些资源是从网上下载的,所以需要实现一个下载模块。该模块必须能够从一个url下载html,然后解析出其中的链接进行下载。静态服务器html、css、js等资源从web服务器下载。通过http协议,这个服务器也需要实现。它可以是一个简单的静态服务器,也可以是一个具有某种逻辑的动态服务器。浏览器的界面既然是浏览器,肯定有输入url的地方,也有显示内容的地方,所以我们做一个界面,上面是地址栏输入url,下面是内容区它用于显示和渲染内容。整体架构图如下:总结本文是【手写一个简单的浏览器】系列文章的第一篇,主要讲述思路来源、整体实现思路以及各部分的总体思路。首先html解析器,css解析器,js解析器,除了js会由acorn实现,然后会实现布局引擎和渲染引擎,实现jsast的解释和执行,事件循环将两者整合实现渲染和逻辑调度。加上网络资源的下载和浏览器的界面后,就是一个简单的浏览器,思路可行。后续每个部分都会用一篇文章解释清楚,源码放在github上,敬请期待。