客户端容器 | 青训营笔记

90 阅读28分钟

image.png

浏览器架构

浏览器架构演进

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

在早期的浏览器中,所有的功能都在一个进程中完成,包括用户界面、JavaScript执行、CSS渲染和网络请求等。单进程架构的优势是简单、易于实现,但缺点也很明显,如:不稳定(一个标签页崩溃可能导致整个浏览器崩溃)、不安全(攻击者可以利用漏洞来控制整个浏览器)以及性能瓶颈(多个标签页争抢资源,导致性能下降)。

  • 多进程架构:主进程、网络进程、渲染进程、GPU进程、插件进程

为了解决单进程架构的问题,浏览器厂商开始将浏览器的功能拆分为多个进程。例如,谷歌推出的Chrome浏览器就采用了多进程架构。在这种架构下,浏览器将每个标签页(或每个渲染实例)分配给一个单独的进程,从而实现了进程间的隔离,防止单个网页崩溃影响到其他界面。多进程架构提高了浏览器的稳定性、安全性和性能,但同时也增加了内存消耗。

每一个Tab运行在独立的沙盒里面。

  • 面向服务架构:将原来的UI、数据库、文件、设备、网络等,作为一个独立的基础服务

面向服务架构是多进程架构的升级版本。

随着Web平台的发展,浏览器需要处理越来越多的任务,这使得多进程架构变得复杂且难以维护。面向服务架构的出现旨在将浏览器的各个功能模块化,将它们作为独立的服务来运行和维护。在这种架构下,每个服务都可以独立地使用一个或多个进程,根据需求自动扩展或缩减资源。这样可以进一步提高浏览器的稳定性、安全性和性能,同时优化资源利用率。

image.png

任务管理器

image.png

在多进程浏览器架构中,任务管理器是一个非常重要的组件。任务管理器负责监控、管理和分配浏览器的各个进程,确保整个浏览器系统的稳定性和性能。

任务管理器主要负责以下几方面的功能:

  1. 进程监控:任务管理器可以实时查看浏览器中的各个进程,包括标签页进程、插件进程和扩展进程等。它可以展示各个进程的资源使用情况,如内存占用、CPU使用率和网络活动等。

  2. 进程管理:任务管理器负责启动和关闭浏览器的进程。当用户打开一个新的标签页或启动一个插件时,任务管理器会创建相应的进程。当标签页被关闭或插件停止运行时,任务管理器会结束相应的进程,以释放系统资源。

  3. 资源分配:任务管理器根据各个进程的资源需求,动态地分配系统资源。例如,对于需要大量CPU资源的进程,任务管理器会分配更多的CPU时间片。同时,任务管理器还可以确保关键进程(如用户界面进程)始终获得足够的资源,从而保证整个浏览器的流畅运行。

  4. 进程隔离:为了提高浏览器的安全性,任务管理器会对各个进程进行隔离。这意味着一个进程无法直接访问另一个进程的内存空间。进程隔离可以防止潜在的安全漏洞影响到整个浏览器系统。

  5. 异常处理:任务管理器负责检测和处理进程中的异常情况。当某个进程发生崩溃或无响应时,任务管理器会尝试自动恢复该进程。如果无法恢复,任务管理器会提示用户关闭相应的标签页或插件,以防止整个浏览器崩溃。

浏览器架构分工

image.png

思考

为什么会有单进程架构

早期的浏览器中web技术简单,硬件设备也较为落后;此时采用单进程架构易于实现,维护方便,资源消耗较低,兼容性较好。随着技术进步和需求的增加,单进程架构稳定性、安全性和性能方面的问题也逐渐突出,局限性变大导致单进程架构逐渐落伍。

面向服务架构是否会替代多进程架构

面向服务架构可以看作是多进程架构的升级,这种架构将浏览器的各个功能模块化,作为独立的服务来运行和维护,可以更好地管理和维护浏览器的各个功能模块。然而,多进程架构相对简单且易于实现,在很多情况下依旧适合使用。面向服务架构的优势在于模块化和灵活性,它可以根据需求自动扩展或缩减资源。但是,这种架构可能需要更多的系统资源和开发维护成本。多进程架构在资源消耗和开发成本方面可能更具优势。

渲染进程

image.png

多进程架构

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

image.png

image.png

进程与线程

  • 进程和线程都是操作系统进行任务管理的基本单位
  1. 进程:

进程是一个独立的程序执行实例,它包括程序的代码、数据以及运行时所需的系统资源(如文件描述符、内存空间等)。每个进程都有自己的独立地址空间,操作系统会为每个进程分配和管理资源。

进程的特点:

  • 独立性:进程具有独立的地址空间,一个进程无法直接访问另一个进程的资源,除非通过进程间通信(IPC)机制。

  • 隔离性:操作系统会为每个进程分配和管理资源,确保它们之间的隔离。这有助于提高系统的稳定性和安全性。

  • 资源开销:创建和维护进程需要消耗一定的系统资源,如内存、CPU时间等。

应用场景:进程通常用于执行独立的、需要隔离的任务。例如,在多进程浏览器中,每个Tab标签页都运行在一个单独的进程中,以实现进程间的隔离和资源管理。

  1. 线程:

线程是进程内的一个执行单元,它共享进程的地址空间和资源,但拥有自己的执行堆栈和程序计数器。一个进程可以包含多个线程,它们可以并发地执行任务。

线程的特点:

  • 轻量级:线程比进程更轻量级,创建和切换线程的开销较小。

  • 共享资源:线程之间可以共享进程的地址空间和资源,这使得线程间的通信和数据共享变得更加简单高效。

  • 上下文切换:线程之间的上下文切换成本较低,因为它们共享相同的地址空间。

应用场景:线程通常用于实现并发执行和任务分解。例如,在一个图形编辑器中,可以使用多个线程分别处理用户输入、图形渲染和文件保存等任务,从而提高程序的响应速度和执行效率。

JS引擎 VS 渲染引擎

image.png

  1. 解析执行JS

  • JS引擎:JS引擎会将JavaScript源代码解析成抽象语法树(AST),然后通过JIT编译器将AST编译成机器代码,最后执行机器代码。在这个过程中,JS引擎还会进行优化,提高代码的执行效率。常见的JS引擎包括V8(用于Chrome和Node.js)、SpiderMonkey(用于Firefox)和JavaScriptCore(用于Safari)。

  • 渲染引擎:渲染引擎的主要任务是解析HTML和CSS,构建DOM树和渲染树,然后将渲染树转换为屏幕上的像素。在这个过程中,渲染引擎并不直接处理JavaScript代码。然而,当遇到需要执行的JavaScript代码时(例如,通过<script>标签或事件处理程序),渲染引擎会将控制权交给JS引擎。一旦JS引擎执行完毕,渲染引擎会继续执行后续的渲染任务。

  1. XML解析生成渲染树,显示在屏幕

  • JS引擎:JS引擎主要处理JavaScript代码,不负责解析XML或生成渲染树。然而,JavaScript可以通过DOM API操作DOM树,从而间接地影响渲染树的生成和更新。

  • 渲染引擎:渲染引擎负责解析HTML和XML文档,构建DOM树。然后,渲染引擎会解析CSS样式,并将样式信息附加到DOM树上,生成渲染树。接下来,渲染引擎会计算每个节点的布局信息(如位置和大小),并将渲染树转换为屏幕上的像素。这个过程被称为“绘制”或“渲染”。

  1. 桥接方式通信

  • JS引擎和渲染引擎之间需要进行通信,以确保JavaScript代码的执行和网页内容的渲染能够协同工作。这种通信通常通过浏览器内部的API和事件机制实现。

  • JS引擎:JS引擎提供了DOM API,使得JavaScript代码可以访问和操作DOM树。当JavaScript代码需要对DOM树进行操作时(如添加、删除或修改节点),JS引擎会通过浏览器内部的API通知渲染引擎进行相应的

多进程工作流程

image.png

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

网络线程的主要任务是从服务器加载网页资源,如HTML、CSS、JavaScript、图片等。加载过程中,网络线程会将HTML和CSS交给渲染线程进行解析,并将JavaScript交给JS引擎进行解析和执行

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

JS引擎将接收到的JavaScript代码解析成抽象语法树(AST),然后通过JIT编译器将AST编译成机器代码,最后执行机器代码。在这个过程中,JS引擎还会进行优化,提高代码的执行效率

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

当JS引擎空闲时(即没有JavaScript代码需要执行),渲染线程开始工作。渲染线程负责解析HTML和CSS,构建DOM树和渲染树,计算布局信息,并将渲染树转换为屏幕上的像素。如果在此过程中遇到JavaScript代码(如<script>标签或事件处理程序),渲染线程会暂停,将控制权交给JS引擎

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

当用户与网页进行交互(如点击、滚动等),或者有定时器触发(如setTimeoutsetInterval)时,相应的回调函数会被放入任务队列中。任务队列是先进先出(FIFO)的数据结构,用于存储待处理的任务

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

事件线程负责管理事件循环。事件循环的主要任务是检查任务队列,将队列中的任务按顺序取出,并交给JS引擎执行。JS引擎执行任务时,可能会对DOM树进行操作,从而触发渲染线程的更新。事件循环会持续进行,直到任务队列为空,或者浏览器关闭。

思考

// 获取当前时间戳
const now = Date.now();
​
// 定时器1:10ms后输出"time10"和定时器1的执行延时
setTimeout(() => {
  console.log('time10', Date.now() - now); // 输出1:?
}, 10);
​
// 定时器2:30ms后输出"time30"和定时器2的执行延时
setTimeout(() => {
  console.log('time30', Date.now() - now); // 输出2:?
}, 30);
​
// 一直执行循环,直到距离当前时间戳至少过去20ms
while (true) {
  if (Date.now() - now >= 20) {
    break;
  }
}
​
// 输出当前已经过去的时间(自now开始计算)
console.log(Date.now() - now); // 输出3:?

这段代码演示了setTimeout的执行顺序以及JavaScript的单线程执行特点

  • 输出1:定时器1的回调函数在10ms后加入事件队列。然而,由于while循环会阻塞主线程,直到至少20ms过去,所以定时器1的回调函数将在while循环结束后立即执行。因此,输出1的值会大于等于20ms,例如:"time10 20"。

  • 输出2:定时器2的回调函数在30ms后加入事件队列。因为while循环在20ms后就结束了,所以定时器2的回调函数会在预期的30ms后执行。因此,输出2的值会接近30ms,例如:"time30 30"。

  • 输出3:这个输出表示while循环结束时已经过去的时间。由于while循环会一直执行,直到至少20ms过去,所以输出3的值会大于等于20ms,例如:"20"。

主要注意的是,由于JavaScript的单线程特性和事件循环机制,setTimeout并不能保证回调函数会在精确的延迟时间后执行。实际的执行时间可能会受到其他任务(如while循环)的影响。

Chrome运行原理

如何展示网页

image.png

  1. 输入解析:浏览器首先解析输入的内容,判断它是一个有效的URL还是搜索查询。如果输入的内容被识别为搜索查询,浏览器将使用默认的搜索引擎进行搜索。

  2. DNS查询:如果输入的内容是一个有效的URL,浏览器将进行域名系统(DNS)查询以将域名解析为对应的IP地址。浏览器会首先检查本地DNS缓存,如果找不到对应的记录,它会向DNS服务器发送查询请求。

  3. 建立连接:浏览器与目标服务器建立一个TCP连接。这通常包括三次握手过程,以确保双方都准备好进行数据传输。

  4. 发送HTTP请求:TCP连接建立后,浏览器向服务器发送一个HTTP请求。请求通常包括请求方法(如GET或POST)、请求的资源路径、HTTP协议版本、请求头(包含诸如用户代理、接受的编码和语言等信息)以及可能的请求体(如POST请求所包含的表单数据)。

  5. 接收响应:服务器处理HTTP请求,并将响应数据发送回浏览器。响应通常包括HTTP状态码(如200表示成功,404表示未找到等)、响应头(包含诸如内容类型、内容长度等信息)以及响应体(通常是HTML文档)。

  6. 关闭或重用连接:一旦浏览器接收到完整的响应数据,它可以选择关闭TCP连接或将其保持在活动状态以用于后续请求。

  7. 解析HTML:浏览器解析HTML文档,构建DOM树。在解析过程中,浏览器可能遇到<script>标签或其他需要立即执行的脚本,这时浏览器将暂停解析,执行脚本,然后继续解析。

  8. 请求其他资源:HTML文档通常包含其他资源的引用,如CSS、JavaScript和图片等。浏览器将发送额外的HTTP请求来获取这些资源。这些请求可能与初始请求的服务器相同,也可能涉及其他服务器。

  9. 构建渲染树:浏览器解析CSS样式,并将其应用于DOM树,生成渲染树。渲染树包含了所有可见元素及其样式信息。

  10. 布局:浏览器计算渲染树中每个元素的位置和大小,生成布局信息。

  11. 绘制:浏览器根据渲染树和布局信息将元素绘制到屏幕上。这个过程称为绘制或渲染。浏览器会将各个层的元素绘制到位图中,然后将这些位图合成到屏幕上显示的最终图像。

  12. 交互:在完成页面绘制后,浏览器开始接收和处理用户的交互,如点击、滚动、输入等。这些交互可能会触发JavaScript事件处理程序,从而修改DOM或应用新的样式。这些修改可能会导致浏览器重新布局和绘制页面的部分或全部内容。

  13. 关闭或卸载:当用户导航到其他页面或关闭浏览器选项卡时,浏览器将触发相应的页面卸载事件,如beforeunloadunload。这给开发者一个机会来执行清理操作,如保存用户数据或取消挂起的网络请求。一旦完成这些操作,浏览器将卸载页面并释放相关资源。

输入处理

  1. 用户Url框输入内容的后,UI线程会判断输入的是一个URL地址呢,还是一个query查询条件

  2. 如果是URL,直接请求站点资源

  3. 如果是query,将输入发送给搜索引擎

image.png

开始导航

  1. 当用户按下回车,UI线程通知网络线程发起一个网络请求,来获取站点内容

  2. 请求过程中,tab处于loading(转圈等待)状态

image.png

读取响应

  1. 网络线程接收到HTTP响应后,先检查响应头的媒体类型(MIME Type)

  2. 如果响应主体是一个HTML文件,浏览器将内容交给渲染进程处理

  3. 如果拿到的是其他类型文件,比如Zip、exe等,则交给下载管理器处理

image.png

寻找渲染流程

  1. 网络线程做完所有检查后,会告知主进程数据已准备完毕,主进程确认后为这个站点寻找一个渲染进程

  2. 主进程通过IPC消息告知渲染进程去处理本次导航

  3. 渲染进程开始接收数据并告知主进程自己已开始处理,导航结束,进入文档加载阶段

image.png

渲染进程

资源加载

  1. 收到主进程的消息后,开始加载HTML文档

  2. 除此之外,还需要加载子资源,比如一些图片,CSS样式文件以及JavaScript脚本

image.png

构建渲染树

  1. 构建DOM树,将HTML文本转化成浏览器能够理解的结构

  2. 构建CSSOM树,浏览器同样不认识CSS,需要将CSS代码转化为可理解的CSSOM

  3. 构建渲染树,渲染树是DOM树和CSSOM树的结合

image.png

页面布局

  1. 根据渲染树计算每个节点的位置和大小

  2. 在浏览器页面区域绘制元素边框

  3. 遍历渲染树,将元素以盒模型的形式写入文档流

image.png

页面绘制

  1. 构建图层:为特定的节点生成专用图层

  2. 绘制图层:一个图层分成很多绘制指令,然后将这些指令按顺序组成一个绘制列表,交给合成线程(减少绘制次数)

  3. 合成线程接收指令生成图块

  4. 栅格线程将图块进行栅格化

  5. 展示在屏幕上

image.png

前端性能performance

image.png

时间都花在哪?

  • 页面加载

  • 渲染解析

  • js渲染

  • 页面绘制

  • ...

什么情况下卡顿

卡顿一般是由于浏览器在渲染页面时遇到了阻塞或耗时操作导致的。以下是一些可能导致卡顿的情况:

  • JavaScript执行时间过长:JavaScript的执行会阻塞页面的渲染。如果脚本执行时间过长,会导致页面无响应或卡顿现象。

  • 大量的DOM操作:DOM操作会影响页面的渲染,特别是在大量DOM操作时。如果需要频繁地更新DOM元素,可以考虑使用虚拟DOM等技术来减少DOM操作次数。

  • 大量的网络请求:浏览器在渲染页面时需要下载和解析HTML、CSS、JavaScript和图像等资源。如果有大量的资源需要下载,会导致页面加载时间过长。

  • 大量的样式和布局计算:如果页面包含大量的样式和布局计算,会影响页面的渲染性能。

  • 阻塞渲染的JavaScript:如果脚本阻塞了页面的渲染,就会导致卡顿或页面无响应。

首屏优化

  1. 压缩、分包、删除无用代码

通过压缩代码、分包加载和删除无用代码等技术,可以减小页面的体积,加快页面的加载速度。

  1. 静态资源分离

将页面中的静态资源(如CSS、JavaScript和图像等)与HTML文档分离,可以使得浏览器可以并行加载这些资源,从而提高页面的加载速度。

  1. JS脚本非阻塞加载

将JS脚本异步加载,可以减少页面的渲染阻塞,从而提高页面的加载速度。可以使用defer和async等属性来实现JS的非阻塞加载。

  1. 缓存策略

合理地设置缓存策略,可以减少对服务器的请求,加快页面的加载速度。可以使用HTTP响应头中的Cache-Control和Expires等属性来设置缓存策略。

  1. SSR

服务器端渲染(Server Side Rendering)可以在服务器端生成HTML文档,减少客户端渲染的工作量,从而提高页面的加载速度。SSR适用于复杂的单页面应用或对SEO有要求的应用。

  1. 预置loading、骨架屏

在页面加载过程中,可以预置一个loading动画或骨架屏,以提高用户体验。这些技术可以在页面加载完成之前,先显示一些占位元素,给用户一个等待的感觉,从而减少用户等待的焦虑和不安。

渲染优化

  1. GPU加速

将复杂的图形处理任务交给GPU来处理,可以加快页面的渲染速度。可以使用CSS3的transform和opacity等属性来开启GPU加速。

  1. 减少回流、重绘

回流和重绘是影响页面性能的主要因素之一。可以通过避免使用影响布局的属性、批量修改DOM元素等技术来减少回流和重绘操作。

  1. 离屏渲染

离屏渲染是将页面中的部分内容在单独的图层中进行渲染,从而减少对主渲染线程的阻塞。可以使用CSS3的transform和position等属性来开启离屏渲染。

  1. 懒加载

将页面中的非必要资源(如图片和视频等)延迟加载,可以加快页面的加载速度。可以使用Intersection Observer和Lazyload等技术来实现懒加载。

JS优化

  1. 防止内存泄漏

有可能出现内存泄漏的场景

全局变量:全局变量会一直存在于内存中,直到程序结束才会被释放。如果程序中定义了大量的全局变量,就会导致内存占用过多,从而导致内存泄漏。

闭包:闭包会在函数中保存局部变量和参数,如果函数执行后,闭包中的变量没有被释放,就会导致内存泄漏。为了避免内存泄漏,应该合理使用闭包,并注意释放不需要的变量。

循环引用:循环引用是指两个或多个对象之间相互引用,形成了一个死循环,导致内存无法释放。为了避免循环引用,应该及时释放不需要的引用,并使用垃圾回收机制来自动释放内存。

定时器和事件监听器:定时器和事件监听器会持续占用内存,直到被清除或被解除绑定。如果程序中存在大量的定时器和事件监听器,就会导致内存占用过多,从而导致内存泄漏。

DOM节点:DOM节点也会占用内存空间,如果程序中存在大量的DOM节点,就会导致内存占用过多,从而导致内存泄漏。为了避免内存泄漏,应该及时清除不需要的DOM节点。

内存泄漏会导致不必要的内存占用和程序崩溃。可以使用let和const关键字声明变量,避免变量污染和内存泄漏。

  1. 循环尽早break

在循环中,如果已经找到了需要的结果,可以使用break语句尽早结束循环,避免无用的迭代和计算。

  1. 合理使用闭包

闭包可以在函数中保存局部变量和参数,避免全局变量的污染和泄漏。但是,如果使用不当,也会导致内存泄漏和性能下降。

  1. 减少Dom访问

DOM操作是JavaScript性能的一个瓶颈。可以使用缓存和批量操作等技术来减少DOM访问次数,从而提高JavaScript的性能。

  1. 防抖、节流

防抖(debounce): 防抖是指在一定时间内,如果连续触发事件,那么只执行一次目标函数。常用于输入框实时搜索、窗口大小调整等场景。防抖的实现原理是:设置一个定时器,在指定的延迟时间内,如果再次触发事件,则重新计时。只有在延迟时间内没有再次触发事件时,才会执行目标函数。

节流(throttle): 节流是指在一定时间内,无论触发多少次事件,目标函数都只执行一次。常用于滚动事件、鼠标移动等场景。节流的实现原理是:设置一个间隔时间,在这个时间内,无论事件触发多少次,都只执行一次目标函数。一旦超过这个间隔时间,就会再次执行目标函数。

防抖和节流是用来控制函数调用频率的技术。可以使用setTimeout和requestAnimationFrame等API来实现防抖和节流(或者用第三方库也行)。

  1. Web Workers

Web Workers是一种在后台线程中执行JavaScript代码的技术。可以将耗时的计算任务和数据处理等操作放到Web Workers中执行,避免阻塞主线程,提高页面的响应速度。

跨端容器

image.png

WebView

  • Webview,即网页视图,用于加载网页Url,并展示其内容的控件。

  • 可以内嵌在移动端App内,实现前端混合开发,大多数混合框架都是基于Webview的二次开发;比如lonic、Cordova。

常用WebView分类

image.png

WebView主要优点

  • 跨平台兼容性:使用WebView,开发者可以利用Web技术为多个平台(如iOS和Android)创建应用。这可以节省开发时间和成本,一次开发处处使用,学习成本低,同时确保应用在各个平台上提供一致的用户体验。

  • 代码重用:WebView允许开发者在移动应用中重用现有的Web代码。这意味着,对于已有Web应用的公司来说,可以更容易地将其产品扩展到移动平台。

  • 简化更新过程:随时发布,即时更新,不用下载安装包。WebView使得应用内容的更新变得更加简单。因为WebView直接加载Web内容,开发者可以在服务器端更新应用内容,而无需重新提交整个应用到应用商店进行审核。

  • 通过JSBridge和原生系统交互,能够实现一些更加复杂的功能

WebView使用原生能力

  • Javascript调用Native

API注入:Native获取]avascript3环境上下文,对其挂载的对象或者方法进行拦截

使用Webview URL Scheme跳转拦截

IOS上window.webkit.messageHandler直接通信

  • Native调用Javascript

直接通过webview暴露的API执行JS代码

IOS webview.stringByEvaluatingJavaScriptFromString

Android webview.evaluateJavascript

WebView< - >Nactive 通信

  • JS环境中提供通信的 JSBridge

  • Native端提供 SDK 响应 JSBridge 发出的调用

  • 前端和客户端分别实现对应功能模块

image.png

实现一个简易的JSBridge

  • JSBridge是一种在WebView中实现原生与JavaScript之间通信的技术

image.png

image.png

小程序

image.png

微信、支付宝、百度小程序、小米直达号

渲染层-webview

双线程,多webview架构

数据通信,Native转发

React Native/WeeX

image.png

  • React Native: React Native是Facebook开发的一个开源框架,它允许开发者使用React和JavaScript编写原生移动应用。

React Native的优势包括:

代码复用:React Native允许开发者在多个平台上复用大部分代码,从而减少开发时间和成本。

热重载:React Native支持热重载功能,允许开发者在不重新编译整个应用的情况下查看代码更改的效果,提高开发效率。

原生性能:虽然React Native使用JavaScript编写,但它将JavaScript代码转换为原生组件,从而提供了接近原生应用的性能。

丰富的生态系统:React Native拥有庞大的社区支持,开发者可以利用许多第三方库和组件来加速开发过程。

  • Weex: Weex是由阿里巴巴开发的一个开源框架,它允许开发者使用Vue.js和JavaScript编写原生移动应用。

Weex的优势包括:

代码复用:类似于React Native,Weex也支持在不同平台上复用代码,从而降低开发成本。

原生渲染:Weex将Vue.js组件转换为原生组件进行渲染,从而实现了较高的性能。

插件系统:Weex提供了一个丰富的插件系统,开发者可以使用这些插件来轻松实现原生功能,如地图、支付等。

模块化:Weex允许开发者将应用拆分为多个模块,这有助于实现高度模块化的开发过程,提高代码可维护性。

原生组件渲染

React/Vue框架

virtual dom

JSBridge

Lynx

image.png

基于Vue框架

绑定于JS Core / V8

JSBinding

Native UI /Skia

Flutter

image.png

Flutter是Google开发的一个开源UI工具包,旨在为开发者提供一种构建优美、高性能的跨平台应用的解决方案。Flutter具有一些独特的特点,包括基于Widget的设计、Dart VM以及使用Skia图形库

wideget

dart vm

skia图形库

通用原理

image.png

  • UI组件

  • 渲染引擎

  • 逻辑控制引擎

  • 通信桥梁

  • 底层API抹平表面差异

方案对比

image.png

思考

  • 同样是基于WebView渲染,为什么小程序体验比webview流畅?

小程序相对于WebView,因为平台适配问题,可以对场景进行专门的优化,使得它的体验更佳。

  • 优化的渲染引擎: 小程序的渲染引擎经过针对性优化,以适应移动设备的性能特点。这使得小程序在处理动画、滚动等界面交互时更加流畅。此外,小程序还采用了一些高效的Web渲染技术,如硬件加速、层合成等,从而提高了渲染性能。

  • 分离的逻辑层和渲染层: 小程序将逻辑层(JavaScript代码)和渲染层(UI界面)分开处理。逻辑层运行在Web容器中,而渲染层则运行在一个独立的原生视图中。通过这种分离,小程序可以在不影响UI渲染的情况下执行JavaScript代码,从而提高了应用的流畅度。

  • 限制和优化的API: 小程序提供了一组限制和优化的API,这些API专门针对移动设备的性能和用户体验进行了调整。通过使用这些API,开发者可以更高效地编写适用于移动设备的应用,从而提高应用的流畅度。

  • 资源限制: 小程序对资源的大小和数量有严格的限制,这迫使开发者在设计应用时充分考虑性能优化。较小的资源包意味着更快的加载速度,从而提高了应用的启动速度和运行性能。

  • 预加载和缓存机制: 小程序具有预加载和缓存机制,这使得应用在首次启动时可以快速加载和渲染,从而提高了用户体验。此外,缓存机制还可以减少网络请求和数据传输,降低应用的延迟。

  • 未来的跨端方案会是什么

在可见的未来,因为各个公司的存在,跨端方案应该会一直保持着通用+专用的情况。WebView这种通用方案适配更加广泛,标准统一,开发条件低,适合在各种方式下都能使用;但是专用跨端方案,像小程序,因为平台的专有优势可以进行优化,将会在使用场景下表现出更优于通用方案的表现。

总结

客户端容器是前端最重要的展现方式,就像作家手中的稿纸、演员面对的相机,所有的思考和制作表达都要通过它才能传达出来。客户端容器作为前端人吃饭的筷子,我们一定要对它深入了解,明白它的原理,只有真正掌握了它,才能更好的将自己的知识和能力展现出来。