浏览器
浏览器大体上由以下几个组件组成,各个浏览器可能有一点不同
浏览器组成
- 界面控件 – 包括地址栏,前进后退,书签菜单等窗口上除了网页显示区域以外的部分
- 浏览器引擎 – 查询与操作渲染引擎的接口
- 渲染引擎 – 负责显示请求的内容。比如请求到HTML, 它会负责解析HTML、CSS并将结果显示到窗口中
- 网络 – 用于网络请求, 如HTTP请求。它包括平台无关的接口和各平台独立的实现
- UI后端 – 绘制基础元件,如组合框与窗口。它提供平台无关的接口,内部使用操作系统的相应实现
- JS解释器 - 用于解析执行JavaScript代码
- 数据存储持久层 - 浏览器需要把所有数据存到硬盘上,如cookies。新的HTML5规范规定了一个完整(虽然轻量级)的浏览器中的数据库 web database
- 定时器触发线程:用来记数 --> node中 定时器也是通过时间循环来处理的 而不是单独的线程计数
- 事件触发线程&HTTP请求线程:微任务?
线程与进程
每个窗口就是一个进程 会 new 一个引擎实例,进程之间不共享资源和地址空间
每个 Tab 就是一个线程,线程之间共享空间地址和资源,所以会有一些安全问题
浏览器常驻线程 戳
- GUI渲染线程:渲染界面(HTML),重回(repaint)、回流(reflow)的时候也会执行,在 js 脚本线程运行的时候,GUI 线程会挂起
- js 脚本线程:用户交互逻辑、DOM CSS样式树操作
- 为什么不用多线程:多个 js 线程操作一个 DOM,可能造成性能浪费/数据不一致,当然可以通过锁来控制,但是太复杂了 JS 最初选择了单线程
- GUI 和 JS 线程为什么互斥:如果 js 在操作样式,GUI 也在渲染样式,可能会造成数据不一致问题
- 互斥有什么问题:js 线程运行时间太长,GUI 被挂起到其他队列,会造成页面卡顿
- 定时器触发线程
- 事件触发线程
- 异步http请求线程
传说中的DOM操作
从去年正式接触到前端开发开始,就听很多人说直接操作dom成本高 性能差,尤其是在学习了React这类的MVx框架之后,前端也开启了data驱动view的模式,大学学习的jQuery还没怎么用就被毙掉了,那到底为什么DOM操作会严重降低前端性能呢?
DOM 文档对象模型,是Document Object Model的缩写,CSSOM css对象模型,是CSS Object Model的缩写
在刚接触前端的时候,一直以为DOM就是div、span、Hx这些标签。DOM毕竟是model,html作为一种标记语言 在DOM模型中担任对象的角色,而DOM则为html标签提供‘编程API’,DOM不会去操作标签属性 内容等内部的东西。但实际开发中,光设计 不动态修改界面是不合理的,所以就出现了JS等脚本语言进行html级别的操作
其实DOM操作不是JS的特权,貌似Python这些脚本语言也是可以的。而且在前端页面加载的时候,除了DOM 还有一个叫CSSOM的东西,负责解析CSS并形成树,和DOM是两套模型结构
说说浏览器渲染
DOM操作成本,无非就是传输成本+渲染成本两部分。首先服务器和客户端(这里只说浏览器,其他的不太了解 不敢乱说 怕被打),挥个手啊 抱一抱啊巴拉巴拉的PY交易一波,就把文件从服务器搬到了浏览器,我们下面介绍的浏览器渲染 也只从这个时间点开始 只讲DOM渲染,JSP这种服务端渲染就不讲了。浏览器渲染主要步骤如下:
- HTML解析,生成DOM模型树(如果这里有外链或者内联 会发出一些请求或者加载)
- CSS解析,构建CSS样式树(同上)
- 合并CSSOM和DOM
- render布局
- render绘制
- 小尾巴
HTML解析
<