客户端容器 | 青训营笔记

41 阅读7分钟

浏览器架构

浏览器架构演进:

单进程架构:所有模块运行在同一个进程里,包含网络、插件、JavaScript运行环境等。

多进程架构(现代浏览器架构):主进程、网络进程、渲染进程、GPU进程、插件进程。进程之间是相互隔离的,防止单个进程或页面崩溃之后影响整个浏览器。而且每一个tab?都是运行但独立的沙盒里,安全性高。

面向服务架构:将原来的UI、数据库、文件、设备、网络等,作为一个独立的基础服务。是多进程架构的升级版,进程之间访问需要事先定义好接口,通过IP通信来进行交互。

三种架构对比: Pasted Graphic 83.png

渲染进程

多线程架构

内部是多线程实现,主要负责页面渲染,脚本执行,事件处理,网络请求等。

JS引擎 VS 渲染引擎 Pasted Graphic 88.png JS引擎和渲染引擎是相互独立的,当需要通过JS操作DOM时,是通过Bridge的形式去进行操作的,Bridge会对JS代码造成一定的延时

多进程工作流程

1.网络线程负责加载网页资源

2.JS引擎解析JS脚本并且执行

3.JS解析引擎空闲时,渲染线程立即工作

4.用户交互、定时器操作等产生回调函数放入任务队列中

5.事件线程进行事件循环,将队列里的任务取出交给JS引擎执行

Chrome运行原理

输入处理:用户URL框输入内容后,UI线程会判断输入的是一个URL地址还是一个query查询条件,如果是URL,则直接请求站点资源;如果是query,则将输入发送给搜索引擎

开始导航:当用户按下回车,UI线程通知网络线程发起一个网络请求,来获取站点内容,请求过程中,tab处于loading状态

读取响应:网路线程接收到HTTP响应后,先检查响应头的媒体类型(MIME Type),如果响应主体是一个HTML文件,浏览器将内容交给渲染进程处理;如果拿到的是其他类型文件,比如Zip、exe等,则交给下载管理器处理

寻找渲染进程:网络线程做完所有检查后,会告知主进程数据已经准备完毕,主进程确认后为这个站点寻找一个渲染进程。主进程通过IPC消息告知渲染进程去处理本次导航。渲染进程开始接收数据并告知主进程自己已开始处理,处理结束之后,导航结束,进入文档加载阶段

资源加载:收到主进程的消息后,开始加载HTML文档,除此之外,还需要加载子资源,比如一些图片,CSS样式文件以及JavaScript脚本

构建渲染树:构建DOM树,将HTML文本转化成浏览器能够理解的结构,同时DOM给JavaScript提供了能够操作的接口;构建CSSOM树,浏览器同样不认识CSS,需要将CSS代码转化为可理解的CSSOM,CSSOM同样给JavaScript能操作它的能力;构建渲染树,渲染树是DOM树和CSSOM树的结合。渲染树会得到每个节点的样式和数据结构

页面布局:根据渲染树计算每个节点的位置和大小,在浏览器页面区域绘制元素边框,遍历渲染树,将元素以盒模型的形式写入文档流

页面绘制:构建图层:为特定的节点生成专用图层;绘制图层:一个图层分成多个绘制指令,然后将这些指令按顺序组成一个绘制列表,交给合成线程;合成线程接收指令生成图块;栅格线程将图块栅格化,即将图块转成位图,变成一个一个像素点,通常会使用GPU加速这个栅格化的过程;调用显卡,将其展示在屏幕上

前端性能performance

首屏优化

1.压缩、做单页应用将JS代码分包,利用浏览器的并发可以加快速度、删除无用代码

2.静态资源分离,静态资源不要和服务放在一起,如果是同源的,一般请求同源资源时,默认会带上域下面的Cookie

3.JS脚本非阻塞加载:JS脚本要么是非阻塞的,要么放在包的底部,因为渲染进程渲染解析HTML文件是自上而下的,若将JS放在上面,会先解析JS,由于渲染引擎和JS引擎是互斥的,会导致卡顿

4.缓存策略:合理使用缓存策略

5.SSR

6.预置loading、骨架屏

渲染优化

1.GPU加速:GPU加速一般会新建图层,是一个耗时的操作。所以在开发过程中某一个元素可能用到GPU加速的话,可以在session上设置属性,告诉浏览器这个元素可能会被用到,将其放到新建的图层中

2.减少回流、重绘:display:none会影响DOM结构,造成回流,可以使用visibility去切换;尽量不要使用table布局

3.离屏渲染

4.懒加载

JS优化

1.防止内存泄漏:定时器忘记清除会导致内存泄漏

2.循环尽早break

3.合理使用闭包

4.减少DOM访问

5.防抖、节流:防抖是多次提交时只会提交最后一次提交的结果,节流是在固定时间内多次调用都只会执行一次

6.Web Workers:可以用在图片、视频、音频的处理上

跨端容器

跨端的优点:开发成本低,开发效率高,一致性的体验,前端开发生态

跨端方案:WebView、小程序、RN/WeeX、Lynx(字节内部使用)、Flutter

WebView

WebView即网页视图,用于加载网页URL,并展示其内容的控件,和浏览器的渲染进程功能类似。可以内嵌在移动端App内,实现前端混合开发,市面上大多数混合框架都是基于WebView的二次开发,比如uniapp、Cordova、Ionic

使用WebView优势:一次开发,处处使用,学习成本低;随时发布,即时更新,不用下载安装包;移动设备性能不断提升,性能有保障;通过JSBridge和原生系统交互,实现复杂功能

WebView和Native通信

JS环境中提供通信的JSBridge
Native端提供SDK响应JSBridge发出的调用
前端和客户端分别实现对应功能模块

JSBridge的好处:让业务方法自己去处理自己的逻辑

小程序 微信最先推出,后来各家跟上 渲染层还是WebView,基于浏览器的内核,完全重构了一个内置的解析器,配合自己定义好的一些开发语言的标准,采用双线程,多WebView方案,把数据层和渲染层分开,当需要进行交互时,必须通过Native进行。渲染层和逻辑层的通信都必须通过Native进行转发和拦截

React Native/WeeX 使用原生组件渲染,依赖React/Vue框架。virtual dom是JS的对象,是对整个DOM的描述,通过JSBridge,让Native可以直接通信。

Lynx 基于Vue框架,通过JS Core/V8引擎通过JSBinding(高效的JSBridge)和Renderer进行绑定,通过Native UI/Skia进行UI展示

把DOM节点的构建放在Native层,JS只负责业务逻辑,因此不会阻塞UI线程。

Flutter dart vm是dart语言的虚拟环境

通用原理

提供一套基础的UI组件、渲染引擎和逻辑控制引擎,业务和底层会有一个通信的bridge,底层的API在各端上自己实现,再抹平各端的表现差异

跨端方案对比

小程序体验比WebView流畅是因为小程序做了离线缓存,且基于WebView做了定制,将一些较危险的操作封死了。