浏览器架构
在日常的研发中,比较常见的客户端就是浏览器,我们来学习一些客户端容器。
架构演进
- 单线程架构:
所有模块运行在同一个进程里,包含网络、插件、JavaScript运行环境等 - 双线程架构:主进程、网络进程、渲染进程、GPU进程、插件进程
- 面向服务架构:将原来的UI、数据库、文件、设备、网络等,作为一个
独立的基础服务
架构对比
任务管理器
按住Shift+Esc快捷打开,可以查看浏览器资源情况。
多进程分工
在浏览器中,通常会有以下几个进程:
这些进程之间通过IPC(进程间通信)来进行通信和协作。例如,当用户在地址栏中输入网址时,浏览器进程会创建一个新的渲染进程来加载和渲染网页内容。当用户关闭标签页时,浏览器进程会销毁对应的渲染进程。
小思考:为什么会有单进程架构?面向服务架构是否会替代多线程架构?
浏览器采用单线程架构的主要原因是
简单易用。单线程架构可以避免多线程编程中的竞态条件和死锁等问题,从而提高开发效率和代码可维护性。但是,单线程架构也可能会导致阻塞和性能问题,因此在前端中通常会使用异步编程来避免这些问题。面向服务架构和多线程架构是两个不同的概念,它们并不是互相替代的关系。面向服务架构是一种分布式系统架构,它将系统拆分成多个服务,每个服务都可以独立部署和扩展。多线程架构是一种并发编程模型,它可以让程序同时执行多个任务,从而提高系统的吞吐量和响应速度。
渲染进程
在了解完浏览器架构后,我们对于浏览器架构有了一定的认识,那么它是怎么渲染的?我们来了解一下。
常见的浏览器内核
渲染进程
宣传进程内部是多进程实现的,主要负责页面渲染、脚本执行、事件处理、网络请求等。
其工作流程为:
- 网络线程负责加载网页资源
- JS引擎解析JS脚本并且执行
- JS解析引擎空闲时,渲染进程立即工作
- 用户交互、定时器操作等产生回调函数放入任务队列中
- 事件线程进行事件循环,将队列里的任务取出交给JS引擎执行
JS引擎和渲染引擎
JS引擎负责
解析和执行JavaScript代码,而渲染引擎负责将HTML、CSS和JavaScript代码转换为可视化的网页。在浏览器中,JS引擎和渲染引擎是通过IPC(进程间通信)来进行通信和协作的。例如,当JS代码需要修改DOM元素时,JS引擎会向渲染引擎发送消息,渲染引擎会根据消息更新渲染树和屏幕显示。
Chrome运行原理
了解Chrome的运行原理可以帮助我们更好地理解浏览器的工作原理和优化网页性能。Chrome是一款现代浏览器,它采用了多种技术来提高网页的加载速度和响应速度。
如何展示网页
浏览器地址输入URL发生了什么?(只关注浏览器)
输入处理
输入处理时展示网页的第一步。输入URL地址后,UI线程判断输入是否为URL地址还是get请求
- 如果是URL,直接向站点请求资源
- 如果是get请求,则将输入发送给站点处理参数
开始导航
当用户按下回车或者点击发送输入,UI线程通知网络线程发起一个网络请求,来获取站点内容,请求过程中,Tab处于loading状态,如下图:
读取响应
网络线程接收道HTTP响应后,先检查响应头的媒体类型(MIME Type)
- 响应主体是一个HTML文件,浏览器将内容交给渲染进程处理
- 其他类型文件,浏览器会交给下载管理器处理
寻找渲染进程
网络线程做完所有检查以后,会告知主进程数据已经准备完毕,主线程确认后会对这个站点寻找一个渲染进程。
- 主进程提供进程之间通信告知渲染进程处理本次导航
- 渲染进程开始接收数据并告知主进程自己开始处理,导航结束,进入文档加载阶段
资源加载
收到主线程的消息之后,开始加载HTML文档,除此之外,还需要加载子资源,比如一些图片、CSS样式文件以及JavaScript脚本。
构建渲染树
- 构建DOM树,将HTML文本转化浏览器能够理解的结构
注意:HTML是一门标记型编程语言。
- 构建CSSOM树,需要将CSS代码转化为浏览器可以理解的CSSOM
- 构建渲染树,
渲染树是DOM树和CSSOM树的结合
页面布局
- 计算渲染树计算每个节点的位置和大小
- 在浏览器页面区域绘制元素边框
- 遍历渲染树,将元素以和模型的形式写入
文档流
页面绘制
- 构建图层:为特定的节点生成专用图层
- 绘制图层:一个图层分成很多绘制指令,然后将这些指令按顺序组成一个绘制列表,交给
合成线程
- 合成线程接收指令生成图块
- 栅格线程将图块进行栅格化
- 展示在屏幕上
前端性能performance
- 时间都花在哪
- 什么情况不卡顿
首屏优化(部分)
- 压缩、分包、删除无用代码
- 静态资源分离
- JS脚本非阻塞加载
- 缓存策略
- SSR
- 预置loading、骨架屏
渲染优化
- GPU加速
- 减少回流、重绘
- 离屏渲染
- 懒加载
JS优化
- 防止内存泄漏
- 循环尽早跳出循环
- 合理使用闭包
- 减少DOM访问
- 防抖、节流
- Web Workers
跨端容器
为什么要跨端?首先是减少开发成本,提高开发效率。其次是提高页面一致性体验。
跨端方案
- webview
- 小程序
- RN、WeeX
- Lynx
- Flutter
webview
Webview 是一个可以在应用程序中嵌入网页的组件。它可以用于在应用程序中显示网页内容,可以内嵌在移动端APP内,实现前端混合开发,大多数混合框架都是基于WebView二次开发。
常用的WebView分类有:安卓、IOS、安卓国内
小程序
小程序渲染层为WebView,小程序为双线程,多WebView架构,数据通信提供Native转发。
RN、WeeX
原生组件渲染,需要依赖于React/Vue框架,使用虚拟DOM通过JSBridge进行通信。
通用原理
- UI组件
- 渲染引擎
- 逻辑控制引擎
- 通信桥梁
- 底层API抹平表现差异