浏览器架构
浏览器架构演进
-
单进程架构:一切模块运转在同一个进程里,包含网络、插件、JavaScript运转环境等
- 在前期的浏览器中,一切的功用都在一个进程中完结,包含用户界面、JavaScript履行、CSS烘托和网络恳求等。单进程架构的优势是简略、易于完结,但缺陷也很显着,如:不安稳(一个标签页溃散或许导致整个浏览器溃散)、不安全(攻击者能够运用缝隙来操控整个浏览器)以及功用瓶颈(多个标签页争抢资源,导致功用下降)。
-
多进程架构:主进程、网络进程、烘托进程、GPU进程、插件进程
- 为了处理单进程架构的问题,浏览器厂商开端将浏览器的功用拆分为多个进程。例如,谷歌推出的Chrome浏览器就选用了多进程架构。在这种架构下,浏览器将每个标签页(或每个烘托实例)分配给一个单独的进程,然后完结了进程间的阻隔,防止单个网页溃散影响到其他界面。多进程架构进步了浏览器的安稳性、安全性和功用,但一起也增加了内存耗费
- 每一个Tab运转在独立的沙盒里边
-
面向服务架构:将本来的UI、数据库、文件、设备、网络等,作为一个独立的根底服务
- 面向服务架构 => 多进程架构晋级版别
- 跟着Web渠道的开展,浏览器需求处理越来越多的使命,这使得多进程架构变得杂乱且难以保护。面向服务架构的呈现旨在将浏览器的各个功用模块化,将它们作为独立的服务来运转和保护。在这种架构下,每个服务都能够独登时运用一个或多个进程,依据需求主动扩展或减缩资源。这样能够进一步进步浏览器的安稳性、安全性和功用,一起优化资源运用率
浏览器架构比照
浏览器架构 – 使命办理器
在多进程浏览器架构中,使命办理器是一个非常重要的组件。使命办理器担任监控、办理和分配浏览器的各个进程,保证整个浏览器体系的安稳性和功用。
使命办理器首要担任以下几方面的功用:
- 进程监控:使命办理器能够实时检查浏览器中的各个进程,包含标签页进程、插件进程和扩展进程等。它能够展现各个进程的资源运用情况,如内存占用、CPU运用率和网络活动等。
- 进程办理:使命办理器担任发动和封闭浏览器的进程。当用户翻开一个新的标签页或发动一个插件时,使命办理器会创立相应的进程。当标签页被封闭或插件中止运转时,使命办理器会完毕相应的进程,以开释体系资源。
- 资源分配:使命办理器依据各个进程的资源需求,动态地分配体系资源。例如,关于需求许多CPU资源的进程,使命办理器会分配更多的CPU时刻片。一起,使命办理器还能够保证要害进程(如用户界面进程)一向获得足够的资源,然后保证整个浏览器的流通运转。
- 进程阻隔:为了进步浏览器的安全性,使命办理器会对各个进程进行阻隔。这意味着一个进程无法直接拜访另一个进程的内存空间。进程阻隔能够防止潜在的安全缝隙影响到整个浏览器体系。
- 反常处理:使命办理器担任检测和处理进程中的反常情况。当某个进程发生溃散或无呼应时,使命办理器会测验主动康复该进程。假如无法康复,使命办理器会提示用户封闭相应的标签页或插件,以防止整个浏览器溃散。
经过使命办理器,浏览器能够有效地监控和办理其各个进程,保证整个体系的安稳性、功用和安全性。不同浏览器的使命办理器完结或许会有所差异,但它们的核心功用和方针都是相似的。在谷歌Chrome浏览器中,用户能够经过按下
Shift + Esc
快捷键或许在菜单中挑选“更多东西” > “使命办理器”来翻开使命办理器。
浏览器架构 – 多进程分工
进程称号 | 进程描述 |
---|---|
浏览器(主进程) | 首要担任页面展现逻辑,用户交互,子进程办理;包含地址栏、书签、前进、后退、收藏夹等 |
GPU进程 | 担任UI制作,包含整个浏览器悉数UI |
网络进程 | 网络服务进程,担任网络资源加载 |
标签页(烘托进程) | 操控tab内的一切内容,将HTML、CSS和JavaScript转换为用户可交互的网页 |
插件进程 | 操控网站运转的插件,比方flash、ModHeader等 |
其他进程 | 如上图所示:适用程序Storage/Network/Audio Service等 |
问题考虑
-
为什么会有单进程架构?
-
单进程架构在前期的浏览器中呈现,当时的Web技能相对较为简略,浏览器需求处理的使命和杂乱性远不及现在。在这个布景下,单进程架构具有一些优势:
- 简略性:单进程架构更易于完结和保护,因为它不需求处理多进程间的通讯和资源分配问题。关于前期的浏览器开发者来说,单进程架构供给了一种快速完结浏览器功用的办法。
- 资源耗费:相较于多进程架构,单进程架构在内存和CPU资源耗费方面较低。因为多进程架构中,每个进程都需求占用必定的体系资源,而单进程架构只需求保护一个进程。在核算机硬件资源有限的前期,这一点是非常重要的。
- 兼容性:前期的Web技能和规范相对较为简略,单进程架构在兼容性方面体现优异。因为不需求处理多进程间的兼容性问题,单进程浏览器更简略支撑不同的操作体系和硬件渠道。
可是,跟着Web技能的开展,浏览器需求处理越来越杂乱的使命,如多媒体播映、实时通讯和许多的JavaScript代码等。这使得单进程架构的局限性变得越来越显着,包含安稳性、安全性和功用等方面的问题。因而,浏览器厂商开端选用多进程架构和面向服务架构,以习惯这些新的挑战。
单进程架构在前期的浏览器中呈现,是因为它在简略性、资源耗费和兼容性方面具有优势。可是,跟着Web技能的开展,这种架构的局限性逐步露出,导致现代浏览器转向多进程架构和面向服务架构
-
-
面向服务架构是否会替代多进程架构?
-
面向服务架构在某种程度上能够看作是多进程架构的一种演进和优化。这种架构将浏览器的各个功用模块化,作为独立的服务来运转和保护。这样能够进一步进步浏览器的安稳性、安全性和功用,一起优化资源运用率。
尽管面向服务架构具有必定的优势,可是它纷歧定会彻底替代多进程架构。这是因为两种架构各自有不同的运用场景和优缺陷:
- 面向服务架构更适用于杂乱的浏览器体系,它能够更好地办理和保护浏览器的各个功用模块。可是,在一些轻量级或特定用处的浏览器中,多进程架构或许依然是一个合适的挑选,因为它相对简略且易于完结。
- 面向服务架构的优势在于模块化和灵活性,它能够依据需求主动扩展或减缩资源。可是,这种架构或许需求更多的体系资源和开发保护本钱。多进程架构在资源耗费和开发本钱方面或许更具优势。
- 不同浏览器厂商或许会依据自己的产品定位和技能栈挑选不同的架构。例如,谷歌Chrome浏览器选用了多进程架构,并在此根底上引进了一些面向服务架构的规划理念。而其他浏览器厂商或许会挑选彻底依据面向服务架构的完结。
总归,面向服务架构在某些方面具有优势,但它纷歧定会彻底替代多进程架构。两种架构各自适用于不同的运用场景,浏览器厂商或许会依据实践需求和技能栈挑选合适的架构。跟着Web技能的不断开展,未来浏览器架构或许会持续演进,以习惯更多的需求和挑战。
-
烘托进程
常见浏览器内核
内核 | 浏览器 | JS引擎 | 补充阐明 |
---|---|---|---|
Trident | IE4-11 | JScript,Chakra | 出生于1994年,IE8曾经运用JScript引擎,IE9开端运用Chakra引擎 |
Gecko | Firefox | SpiderMonkey | Gecko内核首要用在Firefox浏览器上,一起是一个跨渠道的内核,支撑在Windows、BSD、Linux、Mac OS X中运用 |
Webkit | Safari、Chrome、Android(安卓)浏览器 | JavaScriptCore | 由Apple公司技能团队开发,并在2005年开源 |
Blink | Chrome,Opera | V8 | Google:依据Webkit开发的内核,在Vebkit的根底上参加多进程,沙箱等技能,于2013年开源。(NodeJS运用的便是这个引擎) |
Edge | Edge | Chakra | 2015年由微软发布,用于Edge浏览器上,因为功用较差,运转不安稳等原因,2018年微软将Edge浏览器内核迁移到Chromium |
Trident+Webkit(Blink) | 国产浏览器QQ、360、搜狗、UC等 | 都有 | 前期银行体系都是在IE上进行开发,想要支撑银行体系就切换到Trident内核,想要体会就切到Webkit内核 |
烘托进程 – 多线程架构
在这里咱们触及到了(多)线程,前面触及到了(多)进程。这里补充额定知识来阐明两者:
进程和线程都是操作体系进行使命办理的基本单位,它们之间有必定的关联性,但也有显着的差异
- 进程:
进程是一个独立的程序履行实例,它包含程序的代码、数据以及运转时所需的体系资源(如文件描述符、内存空间等)。每个进程都有自己的独登时址空间,操作体系会为每个进程分配和办理资源。
进程的特色:
- 独立性:进程具有独立的地址空间,一个进程无法直接拜访另一个进程的资源,除非经过进程间通讯(IPC)机制。
- 阻隔性:操作体系会为每个进程分配和办理资源,保证它们之间的阻隔。这有助于进步体系的安稳性和安全性。
- 资源开销:创立和保护进程需求耗费必定的体系资源,如内存、CPU时刻等。
运用场景:进程一般用于履行独立的、需求阻隔的使命。例如,在多进程浏览器中,每个Tab标签页都运转在一个单独的进程中,以完结进程间的阻隔和资源办理。
- 线程:
线程是进程内的一个履行单元,它同享进程的地址空间和资源,但拥有自己的履行仓库和程序计数器。一个进程能够包含多个线程,它们能够并发地履行使命。
线程的特色:
- 轻量级:线程比进程更轻量级,创立和切换线程的开销较小。
- 同享资源:线程之间能够同享进程的地址空间和资源,这使得线程间的通讯和数据同享变得愈加简略高效。
- 上下文切换:线程之间的上下文切换本钱较低,因为它们同享相同的地址空间。
运用场景:线程一般用于完结并发履行和使命分化。例如,在一个图形编辑器中,能够运用多个线程分别处理用户输入、图形烘托和文件保存等使命,然后进步程序的呼应速度和履行功率。
总结:进程是一个独立的程序履行实例,具有独立的地址空间和资源;线程是进程内的一个履行单元,同享进程的地址空间和资源。进程一般用于履行独立的、需求阻隔的使命,而线程则用于完结并发履行和使命分化
- 内部是多线程完结,首要担任页面烘托,脚本履行,事情处理,网络恳求等
JS引擎 VS 烘托引擎
JS引擎和烘托引擎是浏览器中两个非常重要的组件。它们分别担任处理JavaScript代码和烘托网页内容
-
解析履行JS
- JS引擎:JS引擎担任解析和履行JavaScript代码。它会将JavaScript源代码解析成笼统语法树(AST),然后经过JIT编译器将AST编译成机器代码,最后履行机器代码。在这个进程中,JS引擎还会进行优化,进步代码的履行功率。常见的JS引擎包含V8(用于Chrome和Node.js)、SpiderMonkey(用于Firefox)和JavaScriptCore(用于Safari)。
- 烘托引擎:烘托引擎的首要使命是解析HTML和CSS,构建DOM树和烘托树,然后将烘托树转换为屏幕上的像素。在这个进程中,烘托引擎并不直接处理JavaScript代码。可是,当遇到需求履行的JavaScript代码时(例如,经过
<script>
标签或事情处理程序),烘托引擎会将操控权交给JS引擎。一旦JS引擎履行完毕,烘托引擎会持续履行后续的烘托使命。
-
XML解析生成烘托树,显现在屏幕
- JS引擎:JS引擎首要处理JavaScript代码,不担任解析XML或生成烘托树。可是,JavaScript能够经过DOM API操作DOM树,然后间接地影响烘托树的生成和更新。
- 烘托引擎:烘托引擎担任解析HTML和XML文档,构建DOM树。然后,烘托引擎会解析CSS款式,并将款式信息附加到DOM树上,生成烘托树。接下来,烘托引擎会核算每个节点的布局信息(如位置和巨细),并将烘托树转换为屏幕上的像素。这个进程被称为“制作”或“烘托”。
-
桥接方式通讯
- JS引擎和烘托引擎之间需求进行通讯,以保证JavaScript代码的履行和网页内容的烘托能够协同作业。这种通讯一般经过浏览器内部的API和事情机制完结。
- JS引擎:JS引擎供给了DOM API,使得JavaScript代码能够拜访和操作DOM树。当JavaScript代码需求对DOM树进行操作时(如增加、删去或修改节点),JS引擎会经过浏览器内部的API告诉烘托引擎进行相应的
烘托进程 – 多线程作业流程
-
网络线程担任加载网页资源
- 网络线程的首要使命是从服务器加载网页资源,如HTML、CSS、JavaScript、图片等。加载进程中,网络线程会将HTML和CSS交给烘托线程进行解析,并将JavaScript交给JS引擎进行解析和履行
-
JS引擎解析JS脚本而且履行
- JS引擎将接纳到的JavaScript代码解析成笼统语法树(AST),然后经过JIT编译器将AST编译成机器代码,最后履行机器代码。在这个进程中,JS引擎还会进行优化,进步代码的履行功率
-
JS解析引擎空闲时,烘托线程当即作业
- 当JS引擎空闲时(即没有JavaScript代码需求履行),烘托线程开端作业。烘托线程担任解析HTML和CSS,构建DOM树和烘托树,核算布局信息,并将烘托树转换为屏幕上的像素。假如在此进程中遇到JavaScript代码(如
<script>
标签或事情处理程序),烘托线程会暂停,将操控权交给JS引擎
- 当JS引擎空闲时(即没有JavaScript代码需求履行),烘托线程开端作业。烘托线程担任解析HTML和CSS,构建DOM树和烘托树,核算布局信息,并将烘托树转换为屏幕上的像素。假如在此进程中遇到JavaScript代码(如
-
用户交互、定时器操作等发生回调函数放入使命行列中
- 当用户与网页进行交互(如点击、翻滚等),或许有定时器触发(如
setTimeout
或setInterval
)时,相应的回调函数会被放入使命行列中。使命行列是一个先进先出(FIFO)的数据结构,用于存储待处理的使命
- 当用户与网页进行交互(如点击、翻滚等),或许有定时器触发(如
-
事情线程进行事情循环,将行列里的使命取出交给JS引擎履行
- 事情线程担任办理事情循环。事情循环的首要使命是检查使命行列,将行列中的使命按次序取出,并交给JS引擎履行。JS引擎履行使命时,或许会对DOM树进行操作,然后触发烘托线程的更新。事情循环会持续进行,直到使命行列为空,或许浏览器封闭。
陈腔滥调文笔试题
这段代码首要用于演示
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
循环)的影响。
// 获取当时时刻戳
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:?
Chrome运转原理
Chrome运转原理 – 如何展现网页
- 浏览器地址输入URL后发生了什么(完好流程)
- 输入解析:浏览器首要解析输入的内容,判别它是一个有效的URL仍是查找查询。假如输入的内容被识别为查找查询,浏览器将运用默认的查找引擎进行查找。
- DNS查询:假如输入的内容是一个有效的URL,浏览器将进行域名体系(DNS)查询以将域名解析为对应的IP地址。浏览器会首要检查本地DNS缓存,假如找不到对应的记载,它会向DNS服务器发送查询恳求。
- 树立衔接:浏览器与方针服务器树立一个TCP衔接。这一般包含三次握手进程,以保证双方都准备好进行数据传输。
- 发送HTTP恳求:TCP衔接树立后,浏览器向服务器发送一个HTTP恳求。恳求一般包含恳求办法(如GET或POST)、恳求的资源路径、HTTP协议版别、恳求头(包含比方用户代理、承受的编码和言语等信息)以及或许的恳求体(如POST恳求所包含的表单数据)。
- 接纳呼应:服务器处理HTTP恳求,并将呼应数据发送回浏览器。呼应一般包含HTTP状况码(如200表明成功,404表明未找到等)、呼应头(包含比方内容类型、内容长度等信息)以及呼应体(一般是HTML文档)。
- 封闭或重用衔接:一旦浏览器接纳到完好的呼应数据,它能够挑选封闭TCP衔接或将其坚持在活动状况以用于后续恳求。
- 解析HTML:浏览器解析HTML文档,构建DOM树。在解析进程中,浏览器或许遇到
<script>
标签或其他需求当即履行的脚本,这时浏览器将暂停解析,履行脚本,然后持续解析。- 恳求其他资源:HTML文档一般包含其他资源的引证,如CSS、JavaScript和图片等。浏览器将发送额定的HTTP恳求来获取这些资源。这些恳求或许与初始恳求的服务器相同,也或许触及其他服务器。
- 构建烘托树:浏览器解析CSS款式,并将其运用于DOM树,生成烘托树。烘托树包含了一切可见元素及其款式信息。
- 布局:浏览器核算烘托树中每个元素的位置和巨细,生成布局信息。
- 制作:浏览器依据烘托树和布局信息将元素制作到屏幕上。这个进程称为制作或烘托。浏览器会将各个层的元素制作到位图中,然后将这些位图组成到屏幕上显现的最终图画。
- 交互:在完结页面制作后,浏览器开端接纳和处理用户的交互,如点击、翻滚、输入等。这些交互或许会触发JavaScript事情处理程序,然后修改DOM或运用新的款式。这些修改或许会导致浏览器从头布局和制作页面的部分或悉数内容。
- 封闭或卸载:当用户导航到其他页面或封闭浏览器选项卡时,浏览器将触发相应的页面卸载事情,如
beforeunload
和unload
。这给开发者一个机会来履行整理操作,如保存用户数据或取消挂起的网络恳求。一旦完结这些操作,浏览器将卸载页面并开释相关资源。总结:当您在浏览器地址栏输入URL后,浏览器会阅历一系列的操作,从DNS查询和TCP衔接树立,到HTTP恳求、呼应处理、HTML解析、资源加载、烘托树构建、布局、制作以及用户交互等。这些操作共同构成了从输入URL到显现完好网页的整个进程
视频中的流程(归于浏览器主进程中的导航流程,目的是为了保证用户能够成功加载并显现所恳求的网页):
- 输入处理:浏览器主进程会依据用户输入的URL进行解析和处理,包含检查URL的有效性、判别是否需求运用查找引擎、判别是否需求运用HTTPS等等。在处理完输入之后,浏览器主进程将建议开端导航的恳求。
- 开端导航:浏览器主进程会向网络进程发送开端导航的恳求,以便进行后续的页面加载操作。在发送恳求之前,浏览器主进程会先判别当时页面是否支撑复用,假如支撑,则会重用烘托进程,不然会创立一个新的烘托进程来加载页面。
- 读取呼应:一旦网络进程开端加载页面,它会读取服务器呼应的数据,并将其回来给浏览器主进程。在读取呼应的进程中,网络进程会进行数据解码和安全检查等操作。
- 寻觅烘托进程:一旦浏览器主进程收到网络进程回来的呼应数据,它会依据呼应数据中的烘托进程ID来寻觅对应的烘托进程。假如现已存在对应的烘托进程,则将呼应数据发送给该进程进行处理;不然,浏览器主进程会创立一个新的烘托进程来处理该页面。
输入处理
- 用户Url框输入内容的后,UI线程会判别输入的是一个URL地址呢,仍是一个query查询条件
- 假如是URL,直接恳求站点资源
- 假如是query,将输入发送给查找引擎
开端导航
- 当用户按下回车,UI线程告诉网络线程建议一个网络恳求,来获取站点内容
- 恳求进程中,tab处于loading(转圈等候)状况
读取呼应
- 网络线程接纳到HTTP呼应后,先检查呼应头的媒体类型(MIME Type)
- 假如呼应主体是一个HTML文件,浏览器将内容交给烘托进程处理
- 假如拿到的是其他类型文件,比方Zip、exe等,则交给下载办理器处理
寻觅烘托进程
- 网络线程做完一切检查后,会奉告主进程数据已准备完毕,主进程承认后为这个站点寻觅一个烘托进程
- 主进程经过IPC音讯奉告烘托进程去处理本次导航
- 烘托进程开端接纳数据并奉告主进程自己已开端处理,导航完毕,进入文档加载阶段
烘托进程 – 资源加载
- 收到主进程的音讯后,开端加载HTML文档
- 除此之外,还需求加载子资源,比方一些图片,CSS款式文件以及JavaScript脚本
烘托进程 – 构建烘托树
- 构建DOM树,将HTML文本转化成浏览器能够了解的结构
- 构建CSSOM树,浏览器同样不认识CSS,需求将CSS代码转化为可了解的CSSOM
- 构建烘托树,烘托树是DOM树和CSSOM树的结合
烘托进程 – 页面布局
- 依据烘托树核算每个节点的位置和巨细
- 在浏览器页面区域制作元素边框
- 遍历烘托树,将元素以盒模型的形式写入文档流
烘托进程 – 页面制作
- 构建图层:为特定的节点生成专用图层
- 制作图层:一个图层分成许多制作指令,然后将这些指令按次序组成一个制作列表,交给组成线程(削减制作次数)
- 组成线程接纳指令生成图块
- 栅格线程将图块进行栅格化
- 展现在屏幕上
前端功用performance
performance
方针中常用的特色和办法:
navigationStart
:浏览器开端导航到当时页面的时刻戳。
fetchStart
:浏览器开端检索文档的时刻戳。
responseStart
:浏览器收到第一个字节的时刻戳。
domLoading
:浏览器开端解析文档的时刻戳。
domInteractive
:浏览器完结解析文档的时刻戳。
domContentLoadedEventStart
:文档DOMContentLoaded事情开端的时刻戳。
domComplete
:文档解析完结的时刻戳。
loadEventStart
:文档加载事情开端的时刻戳。
loadEventEnd
:文档加载事情完毕的时刻戳。
- 最常用的是
navigationStart
和loadEventEnd
。navigationStart
表明浏览器开端导航到当时页面的时刻戳,loadEventEnd
表明文档加载事情完毕的时刻戳。这两个时刻戳之差便是页面的加载时刻
-
时刻都花在哪?
-
什么情况下卡顿
卡顿一般是因为浏览器在烘托页面时遇到了堵塞或耗时操作导致的。以下是一些或许导致卡顿的情况:
- JavaScript履行时刻过长:JavaScript的履行会堵塞页面的烘托。假如脚本履行时刻过长,会导致页面无呼应或卡顿现象。
- 许多的DOM操作:DOM操作会影响页面的烘托,特别是在许多DOM操作时。假如需求频繁地更新DOM元素,能够考虑运用虚拟DOM等技能来削减DOM操作次数。
- 许多的网络恳求:浏览器在烘托页面时需求下载和解析HTML、CSS、JavaScript和图画等资源。假如有许多的资源需求下载,会导致页面加载时刻过长。
- 许多的款式和布局核算:假如页面包含许多的款式和布局核算,会影响页面的烘托功用。
- 堵塞烘托的JavaScript:假如脚本堵塞了页面的烘托,就会导致卡顿或页面无呼应。
首屏优化
-
紧缩、分包、删去无用代码
- 经过紧缩代码、分包加载和删去无用代码等技能,能够减小页面的体积,加速页面的加载速度。
-
静态资源别离
- 将页面中的静态资源(如CSS、JavaScript和图画等)与HTML文档别离,能够使得浏览器能够并行加载这些资源,然后进步页面的加载速度
-
JS脚本非堵塞加载
- 将JS脚本异步加载,能够削减页面的烘托堵塞,然后进步页面的加载速度。能够运用
defer
和async
等特色来完结JS的非堵塞加载
- 将JS脚本异步加载,能够削减页面的烘托堵塞,然后进步页面的加载速度。能够运用
-
缓存战略
- 合理地设置缓存战略,能够削减对服务器的恳求,加速页面的加载速度。能够运用HTTP呼应头中的
Cache-Control
和Expires
等特色来设置缓存战略
- 合理地设置缓存战略,能够削减对服务器的恳求,加速页面的加载速度。能够运用HTTP呼应头中的
-
SSR
- 服务器端烘托(Server Side Rendering)能够在服务器端生成HTML文档,削减客户端烘托的作业量,然后进步页面的加载速度。SSR适用于杂乱的单页面运用或对SEO有要求的运用
-
预置loading、骨架屏
- 在页面加载进程中,能够预置一个loading动画或骨架屏,以进步用户体会。这些技能能够在页面加载完结之前,先显现一些占位元素,给用户一个等候的感觉,然后削减用户等候的焦虑和不安
综合运用这些技能,能够大大进步页面的加载速度和用户体会。在进行首屏优化时,需求综合考虑页面的功用、体会和功用等方面,找到最合适的优化计划
烘托优化
-
GPU加速
- 将杂乱的图形处理使命交给GPU来处理,能够加速页面的烘托速度。能够运用CSS3的
transform
和opacity
等特色来敞开GPU加速
- 将杂乱的图形处理使命交给GPU来处理,能够加速页面的烘托速度。能够运用CSS3的
-
削减回流、重绘
- 回流和重绘是影响页面功用的首要因素之一。能够经过防止运用影响布局的特色、批量修改DOM元素等技能来削减回流和重绘操作
-
离屏烘托
- 离屏烘托是将页面中的部分内容在单独的图层中进行烘托,然后削减对主烘托线程的堵塞。能够运用CSS3的
transform
和position
等特色来敞开离屏烘托。
- 离屏烘托是将页面中的部分内容在单独的图层中进行烘托,然后削减对主烘托线程的堵塞。能够运用CSS3的
-
懒加载
- 将页面中的非必要资源(如图片和视频等)推迟加载,能够加速页面的加载速度。能够运用
Intersection Observer
和Lazyload
等技能来完结懒加载
- 将页面中的非必要资源(如图片和视频等)推迟加载,能够加速页面的加载速度。能够运用
JS优化
-
防止内存走漏
-
有或许呈现内存走漏的场景
- 大局变量:大局变量会一向存在于内存中,直到程序完毕才会被开释。假如程序中定义了许多的大局变量,就会导致内存占用过多,然后导致内存走漏。
- 闭包:闭包会在函数中保存局部变量和参数,假如函数履行后,闭包中的变量没有被开释,就会导致内存走漏。为了防止内存走漏,应该合理运用闭包,并留意开释不需求的变量。
- 循环引证:循环引证是指两个或多个方针之间彼此引证,形成了一个死循环,导致内存无法开释。为了防止循环引证,应该及时开释不需求的引证,并运用垃圾回收机制来主动开释内存。
- 定时器和事情监听器:定时器和事情监听器会持续占用内存,直到被铲除或被免除绑定。假如程序中存在许多的定时器和事情监听器,就会导致内存占用过多,然后导致内存走漏。
- DOM节点:DOM节点也会占用内存空间,假如程序中存在许多的DOM节点,就会导致内存占用过多,然后导致内存走漏。为了防止内存走漏,应该及时铲除不需求的DOM节点
-
内存走漏会导致不必要的内存占用和程序溃散。能够运用
let
和const
要害字声明变量,防止变量污染和内存走漏
-
-
循环尽早break
- 在循环中,假如现已找到了需求的成果,能够运用
break
句子尽早完毕循环,防止无用的迭代和核算
- 在循环中,假如现已找到了需求的成果,能够运用
-
合理运用闭包
- 闭包能够在函数中保存局部变量和参数,防止大局变量的污染和走漏。可是,假如运用不当,也会导致内存走漏和功用下降
-
削减Dom拜访
- DOM操作是JavaScript功用的一个瓶颈。能够运用缓存和批量操作等技能来削减DOM拜访次数,然后进步JavaScript的功用
-
防抖、节约
- 防抖(debounce): 防抖是指在必定时刻内,假如接连触发事情,那么只履行一次方针函数,了解为王者荣耀的回城。常用于输入框实时查找、窗口巨细调整等场景。防抖的完结原理是:设置一个定时器,在指定的推迟时刻内,假如再次触发事情,则从头计时。只有在推迟时刻内没有再次触发事情时,才会履行方针函数。
- 节约(throttle): 节约是指在必定时刻内,不管触发多少次事情,方针函数都只履行一次,了解为技能CD。常用于翻滚事情、鼠标移动等场景。节约的完结原理是:设置一个间隔时刻,在这个时刻内,不管事情触发多少次,都只履行一次方针函数。一旦超过这个间隔时刻,就会再次履行方针函数。
总结: 防抖和节约的首要差异在于,防抖是在必定时刻内只履行一次方针函数,而节约是在必定时刻内操控方针函数履行次数。它们都能够有效地削减函数履行频率,下降功用开销,进步用户体会。
- 防抖和节约是用来操控函数调用频率的技能。能够运用
setTimeout
和requestAnimationFrame
等API来完结防抖和节约(或许用第三方库也行)
-
Web Workers
- Web Workers是一种在后台线程中履行JavaScript代码的技能。能够将耗时的核算使命和数据处理等操作放到Web Workers中履行,防止堵塞主线程,进步页面的呼应速度
跨端容器
为什么需求跨端
-
开发本钱、功率
- 跨端开发能够协助下降本钱和进步开发功率。运用跨端技能,开发者只需编写一份代码,就能够在多个渠道(如iOS、Android和Web)上运转。这能够削减开发和保护的作业量,节约时刻和资源。一起,开发团队能够更快地推出新功用和修复问题,因为他们只需关注一份代码库。
-
共同性体会
- 跨端开发能够保证在不同渠道上供给共同的用户体会。运用跨端技能,开发者能够更简略地坚持运用的外观和功用共同,不管用户在什么设备上运用。这有助于进步用户满意度和用户留存率。
-
前端开发生态
- 跨端开发受益于强壮的前端生态体系。许多流行的前端结构和库,如React Native、Flutter和Ionic,都支撑跨端开发。这些东西为开发者供给了丰厚的资源和丰厚的社区支撑,协助他们更轻松地完结跨端功用。
跨端计划
- webview
- 小程序
- RN/WeeX
- Lynx
- Flutter
跨端容器 – WebView
跨端容器中的WebView是一种在移动运用中嵌入网页内容的组件。WebView答应开发者将HTML、CSS和JavaScript等Web技能直接嵌入到移动运用中,然后完结跨渠道的运用开发。经过WebView,能够在原生运用中展现网页内容,一起为开发者供给了一些与原生功用交互的才能
WebView的首要优点包含:
- 跨渠道兼容性:运用WebView,开发者能够运用Web技能为多个渠道(如iOS和Android)创立运用。这能够节约开发时刻和本钱,一次开发处处运用,学习本钱低,一起保证运用在各个渠道上供给共同的用户体会。
- 代码重用:WebView答应开发者在移动运用中重用现有的Web代码。这意味着,关于已有Web运用的公司来说,能够更简略地将其产品扩展到移动渠道。
- 简化更新进程:随时发布,即时更新,不用下载安装包。WebView使得运用内容的更新变得愈加简略。因为WebView直接加载Web内容,开发者能够在服务器端更新运用内容,而无需从头提交整个运用到运用商店进行审阅。
- 经过JSBridge和原生体系交互,能够完结一些愈加杂乱的功用
可是,WebView也有一些局限性:
- 功用:相比于原生运用,依据WebView的运用功用或许较差。这首要是因为WebView需求加载和运转Web内容,这会耗费更多的体系资源。在某些情况下,这或许导致较慢的加载速度和不流通的用户体会。
- 原生功用拜访约束:尽管WebView供给了一些与原生功用交互的才能,但它依然遭到必定的约束。为了完结某些特定的原生功用,开发者或许需求编写额定的渠道特定代码。
- 用户体会差异:尽管WebView能够保证跨渠道的共同性,但它或许无法彻底符合不同渠道的规划规范。因而,在某些情况下,依据WebView的运用或许无法供给与原生运用相同水平的用户体会。
- Webview,即网页视图,用于加载网页Url,并展现其内容的控件
- 能够内嵌在移动端App内,完结前端混合开发,大多数混合结构都是依据Webview的二次开发;比方lonic、Cordova
跨端容器 – 常用WebView分类
- 常用webview、Android,IOS,国产Android
- WebView(Android):这是Android渠道的原生WebView组件,用于在Android运用中加载并显现Web内容。依据Android版别和设备制造商的不同,WebView的体现或许会有所差异。这或许导致一些兼容性和功用问题。
- X5 WebView(腾讯X5内核):这是由腾讯公司推出的一种WebView处理计划,用于处理Android体系上WebView的碎片化问题。X5内核依据腾讯QQ浏览器的内核,供给了更安稳、更高功用的WebView组件。它能够在各种Android设备和体系版别上供给共同的体现,削减兼容性问题。
- UIWebView(iOS,已弃用):这是iOS渠道的原生WebView组件,用于在iOS运用中加载并显现Web内容。UIWebView自iOS 2.0开端引进,但在iOS 8.0中被WKWebView取代。自iOS 12.0以来,UIWebView已被官方弃用,不再引荐运用。
- WKWebView(iOS):这是iOS渠道上的新一代WebView组件,取代了已弃用的UIWebView。WKWebView自iOS 8.0开端引进,它具有更好的功用和更丰厚的功用,如支撑多进程、JavaScript功用改进等。苹果公司引荐开发者运用WKWebView来在iOS运用中加载并显现Web内容。
platform(渠道) | webview(组件) | 内核 |
---|---|---|
Android4.4 | webview | Webkit |
Android4.4以上 | webview | chromium |
Android 国内部分 | X5 webview | chromium 改造版 |
IOS | UIwebview | Webkit |
IOS8 以上 | WKwebview | Webkit |
跨端容器 -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 宣布的调用
- 前端和客户端分别完结对应功用模块
跨端容器 – 完结一个简易JSBridge
JSBridge是一种在WebView中完结原生与JavaScript之间通讯的技能
// 创立一个空方针,用于存储回调函数
const callbacks = {};
// 生成仅有ID的函数,用于标识每个回调函数
function generateUniqueId() {
return 'callback_' + Date.now() + '_' + Math.random().toString(36).substr(2, 6);
}
// 调用原生办法的函数
function callNative(action, params, callback) {
// 生成仅有ID
const callbackId = generateUniqueId();
// 将回调函数存储到callbacks方针中
callbacks[callbackId] = callback;
// 创立一个包含操作、参数和回调ID的方针,用于发送给原生端
const message = {
action,
params,
callbackId,
};
// 将方针转换为JSON字符串
const messageStr = JSON.stringify(message);
// 调用原生办法(具体完结取决于渠道和环境)
// 在Android中,一般会运用JavaScriptInterface
// 在iOS中,一般会运用window.webkit.messageHandlers.<handlerName>.postMessage
window.AndroidBridge.postMessage(messageStr);
}
// 原生调用JS的函数
function nativeCallback(callbackId, result) {
// 从callbacks方针中获取对应的回调函数
const callback = callbacks[callbackId];
// 判别回调函数是否存在
if (callback) {
// 调用回调函数并传入成果参数
callback(result);
// 从callbacks方针中删去现已调用过的回调函数
delete callbacks[callbackId];
}
}
// 将办法露出给大局方针,以便原生代码调用
window.JSBridge = {
callNative,
nativeCallback,
};
//代码块内容由ChatGPT4给出
跨端容器 – 小程序
- 微信、付出宝、百度小程序、小米直达号
- 烘托层-webview
- 双线程,多webview架构
- 数据通讯,Native转发
跨端容器 – React Native/WeeX
- 原生组件烘托
- React/Vue结构
- virtual dom
- JSBridge
- React Native: React Native是Facebook开发的一个开源结构,它答应开发者运用React和JavaScript编写原生移动运用。React Native的首要特色是”Learn once, write anywhere”(学习一次,到处编写),这意味着开发者能够在不同渠道(如iOS和Android)上运用相同的技能栈构建原生运用。
React Native的优势包含:
代码复用:React Native答应开发者在多个渠道上复用大部分代码,然后削减开发时刻和本钱。
热重载:React Native支撑热重载功用,答应开发者在不从头编译整个运用的情况下检查代码更改的作用,进步开发功率。
原生功用:尽管React Native运用JavaScript编写,但它将JavaScript代码转换为原生组件,然后供给了接近原生运用的功用。
丰厚的生态体系:React Native拥有庞大的社区支撑,开发者能够运用许多第三方库和组件来加速开发进程。
- Weex: Weex是由阿里巴巴开发的一个开源结构,它答应开发者运用Vue.js和JavaScript编写原生移动运用。Weex的方针是完结”Write once, run everywhere”(编写一次,到处运转),即运用一套代码构建多个渠道的原生运用。
Weex的优势包含:
- 代码复用:相似于React Native,Weex也支撑在不同渠道上复用代码,然后下降开发本钱。
- 原生烘托:Weex将Vue.js组件转换为原生组件进行烘托,然后完结了较高的功用。
- 插件体系:Weex供给了一个丰厚的插件体系,开发者能够运用这些插件来轻松完结原生功用,如地图、付出等。
- 模块化:Weex答应开发者将运用拆分为多个模块,这有助于完结高度模块化的开发进程,进步代码可保护性。
跨端容器 – Lynx
-
依据Vue结构
- Lynx选用Vue.js作为其根底结构,答应开发者运用Vue.js编写运用。Vue.js是一种渐进式JavaScript结构,它使开发者能够轻松地构建可扩展、高功用的运用。依据Vue.js的规划准则,Lynx能够供给简练、模块化的代码结构,以及良好的开发体会
-
绑定于JS Core / V8
- Lynx挑选JS Core(iOS渠道)或V8(Android渠道)作为其JavaScript引擎。这意味着Lynx运用在运转时,JavaScript代码将在高功用的JavaScript引擎中履行。经过运用这些优异的JavaScript引擎,Lynx能够保证运用在不同渠道上具有安稳、高功用的运转体现
-
JSBinding
- Lynx运用JSBinding技能完结JavaScript与原生代码之间的通讯。这种技能答应JavaScript直接调用原生办法,并使原生代码能够履行JavaScript回调。经过JSBinding,Lynx完结了高效的原生与JavaScript之间的通讯,下降了功用丢失
-
Native UI /Skia
- Lynx运用Native UI组件和Skia作为其烘托引擎。Native UI组件意味着Lynx运用在运转时,界面将运用原生组件进行烘托。这能够保证运用具有接近原生运用的功用和用户体会。一起,Lynx还选用了Skia图形库,它是一种高功用的2D图形烘托引擎,用于制作图形和文本。Skia使Lynx运用在烘托杂乱界面时能够坚持流通的帧率和高质量的视觉作用
跨端容器 – Flutter
Flutter是Google开发的一个开源UI东西包,旨在为开发者供给一种构建优美、高功用的跨渠道运用的处理计划。Flutter具有一些独特的特色,包含依据Widget的规划、Dart VM以及运用Skia图形库
-
wideget
- 在Flutter中,一切UI元素都被称为Widget。Widget是Flutter运用的基本构建块,它们能够嵌套、组合以及自定义,然后创立杂乱的用户界面。Flutter供给了丰厚的预制Widget,如文本、按钮、列表等,开发者能够直接运用这些Widget,也能够经过组合和扩展它们来构建自定义的Widget
-
dart vm
- Flutter运用Dart言语进行开发,Dart是一种强类型、面向方针的编程言语,它既能够编译成JavaScript代码(用于Web运用),也能够编译成机器码(用于移动运用)
- 在移动端,Flutter运用运转在Dart VM(虚拟机)中。Dart VM供给了即时编译(JIT)和预编译(AOT)两种编译方式。在开发进程中,Dart VM选用即时编译,这使得Flutter具有热重载功用,开发者能够在不从头编译整个运用的情况下检查代码更改的作用。在发布运用时,Dart VM会选用预编译,将Dart代码编译成高效的机器码,以进步运用的功用
-
skia图形库
- Flutter运用Skia图形库进行UI烘托。Skia是一种高功用的2D图形烘托引擎,用于制作图形和文本。因为Flutter直接运用Skia进行烘托,它无需依赖于原生UI组件,能够完结一致的跨渠道UI烘托。这使得Flutter运用具有高度的可定制性,一起还坚持了流通的功用和优美的视觉作用。
跨端容器 – 通用原理
- UI组件
- 烘托引擎
- 逻辑操控引擎
- 通讯桥梁
- 底层API抹平外表差异
跨端计划比照
跨端考虑
- 同样是依据webview烘托,为什么小程序体会比webview流通?
这首要归功于小程序在架构和优化方面的一些特色。以下是一些要害因素:
- 优化的烘托引擎: 小程序的烘托引擎经过针对性优化,以习惯移动设备的功用特色。这使得小程序在处理动画、翻滚等界面交互时愈加流通。此外,小程序还选用了一些高效的Web烘托技能,如硬件加速、层组成等,然后进步了烘托功用。
- 别离的逻辑层和烘托层: 小程序将逻辑层(JavaScript代码)和烘托层(UI界面)分隔处理。逻辑层运转在Web容器中,而烘托层则运转在一个独立的原生视图中。经过这种别离,小程序能够在不影响UI烘托的情况下履行JavaScript代码,然后进步了运用的流通度。
- 约束和优化的API: 小程序供给了一组约束和优化的API,这些API专门针对移动设备的功用和用户体会进行了调整。经过运用这些API,开发者能够更高效地编写适用于移动设备的运用,然后进步运用的流通度。
- 资源约束: 小程序对资源的巨细和数量有严格的约束,这迫使开发者在规划运用时充分考虑功用优化。较小的资源包意味着更快的加载速度,然后进步了运用的发动速度和运转功用。
- 预加载和缓存机制: 小程序具有预加载和缓存机制,这使得运用在首次发动时能够快速加载和烘托,然后进步了用户体会。此外,缓存机制还能够削减网络恳求和数据传输,下降运用的推迟。
总归,尽管小程序和依据WebView的运用都是经过WebView烘托,但小程序在烘托引擎、架构规划、API、资源约束以及预加载和缓存等方面进行了针对性优化,这些优化使得小程序的体会比WebView运用更流通。
- 未来的跨端计划会是什么?
….(我也布吉岛呢)
课程总结