客户端容器-web浏览器以及跨端计划
浏览器架构
首要架构模式介绍:
- 单进程架构:一切模块运转在同一个进程里,包括网络、插件、JavaScript运转环境等
- 多进程架构:主进程、网络进程、烘托进程、GPU进程、插件进程
- 面向服务架构:算是多进程架构的升级版。将本来的UI、数据库、文件、设备、网络等,作为一个独立的根底网络服务
浏览器架构对比
使命管理器
查看途径:【左上角三个点】→【更多工具】→【使命管理器】
使命管理器:
由使命管理器可知,浏览器是一个多进程架构,多进程架构分工:
为什么会有单进程架构?
早期遭到硬件约束,为了节约资源。
面向服务架构是否会代替多进程架构?
有可能会被代替。
烘托进程
首要包括以下线程:
- 主线程(Main thread)(下载资源、履行js、计算款式、进行布局、制作组成)
- 光栅线程(Raster thread)
- 组成线程(Compositor thread)
- 作业线程(Worker thread)
常见浏览器内核
烘托进程内部
烘托进程内部是多线程完成,首要担任页面烘托,脚本履行,事情处理,网络恳求等。
- 解说履行JS
- XML解析生成烘托树,显示在屏幕
- 桥接办法通讯
多线程作业流程
- 网络线程担任加载网页资源
- JS引擎解析JS脚本并履行
- JS解析引擎空闲时,烘托进程当即作业
- 用户交互、定时器操作等发生回调函数放入使命行列中
- 事情线程进行事情循环,将行列里的使命 取出交给JS引擎履行
笔试题
const now = Date.now();
setTimeout(() => {
console.log("time10", Date.now() - now);
}, 10);
setTimeout(() => {
console.log("time30", Date.now() - now);
}, 30);
while (true) {
if (Date.now() - now >= 20) {
break;
}
}
console.log(Date.now() - now);
输出成果:
成果次序解说:
当 js 主线程代码履行完毕,就从音讯行列中按照进入次序依次履行代码,任何一个宏使命履行之前,必须确保微使命行列为空。
事情循环行列:
宏使命行列(macrotask queue): Ajax、setTimeout、setInterval、DOM 监听、UI Rendering 等;
微使命行列(microtask queue): Promise 的 then 回调、Mutation Observer API、queueMicrotask 等。
隐藏福利~ 重视gong zhong hao【安酱xx】,输入【js高级学习笔记】获取3万多字的js高级笔记噢~
成果解说:
函数
setTimeout
接受两个参数:待加入行列的音讯和一个时刻值(可选,默以为 0)。这个时刻值代表了音讯被实际加入到行列的最小延迟时刻。假如行列中没有其它音讯并且栈为空,在这段延迟时刻过去之后,音讯会被立刻处理。但是,假如有其它音讯,setTimeout
音讯必须等候其它音讯处理完。因而第二个参数仅仅表明最少延迟时刻,而非切当的等候时刻
。
Chrome运转原理
浏览器地址输入URL后发生了什么?
之前画的一幅图:
-
输入处理:
- 用户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
时刻都花在哪里?什么情况下卡顿?
web功用常见指标:
First Paint 初次制作(FP)
First contentful paint 初次内容制作 (FCP)
Largest contentful paint 最大内容制作 (LCP)
First input delay 初次输入延迟 (FID)
Time to Interactive 初次可交互时刻 (TTI)
Total blocking time 总阻塞时刻 (TBT)
Cumulative layout shift 累积布局偏移 (CLS)
web功用参阅链接:web.dev/vitals/
首屏优化
- 紧缩、分包、删除无用代码
- 静态资源分离
- JS脚本非阻塞加载
- 缓存策略
- SSR
- 预置loading、骨架屏
烘托优化
- GPU加快:一般是运用css3
- 减少回流、重绘
- 离屏烘托
- 懒加载
JS优化
- 防止内存走漏
- 循环尽早break
- 合理运用闭包
- 减少DOM访问
- 防抖、节省
- Web Worker
跨端容器
为什么需求跨端
- 开发成本、功率
- 共同性体会
- 前端开发生态
有哪些跨端计划
- webview
- 小程序
- RN 、Weex
- Lynx
- Flutter
webview
Webview,即网页视图,用于加载网页Url,并展现其内容的控件。
可以内嵌在移动端App内,完成前端混合开发,大多数混合结构都是根据Webview的二次开发:比方lonic、Cordova、uniapp。
优点:
- 一次开发,处处运用,学习成本低
- 随时发布,即时更新,不用下载安装包
- 移动设备功用不断提高,功用有保障
- 经过JSBridge和原生系统交互,完成杂乱功用
Javascript调用Native:
- API注入: Native获取Javascript环境上下文,对其挂载的目标或许办法进行阻拦
- 运用Webview URL Scheme跳转阻拦
- IOS上window.webkit.messageHandler直接通讯
Native调用Javascript:
- 直接经过webview露出的API履行JS代码
- IOS办法:webview.stringByEvaluatingJavaScriptFromString
- Android办法:webview.evaluateJavascript
Webview 和 Native通讯:
- JS环境中提供通讯的JSBridge
- Native端提供SDK呼应JSBridge发出的调用
- 前端和客户端别离完成对应功用模块
完成一个简略的JSBridge:
interface CallArgs {
callId: string; // 调用Id,唯一标识
module: string; // 调用模块
method: string; // 调用办法
data: any; // 参数
}
const Callbacks = { } // 存放回调函数 callId为key
function applyNative = (payload:CallArgs,callback:Function)=>{
const callId = prefix + callTime++
Callbacks[callId] = callback
const Args0:CallArgs = {
callId:callId,
module:payload.module || 'layout',
method:payload.method || 'randomSize',
data:payload.data
}
if(IOS){
return window.webkitURL.messageHandler.postMessage(JSON.stringify(Args0))
}else{
// 安卓对window上约好的目标进行阻拦
return window.AndroidBridge(JSON.stringify(Args0))
}
}
interface ResponseArgs{
responseId: string;// 回调Id,与callId对应
errCode: number;
errMsg?: string;
data: unknown;
}
// Native 端调用webview,参数都经过序列化
const applyWebview = (res:string)=>{
const response = JSON.parse(res) as ResponseArgs
const {responseId} = response
// 从Callbacks找到对应的回调处理办法
if(typeof Callbacks[responseId]) === 'function'{
Callbacks[responseId](response)
// 回调后删除该次回调函数
delete Callbacks[responseId]
}
}
// 挂在在window上,供native直接调用
window.JSBridge = {
applyNative,
applyWebview
}
小程序
常见小程序:微信小程序、支付宝小程序、百度小程序、小米直达号
小程序架构:
- 烘托层-webview
- 双线程,多webview架构
- 数据通讯,Native转发
React Native / Weex
- 原生组件烘托
- React / Vue 结构
- virtual dom
- JSBridge
在安卓和IOS中展现是不一样的,因为底层仍是调用的安卓或IOS的底层组件。
Lynx
字节自研的一款跨端结构。(暂未开源,字节旗下运用较多)
- Vue
- JS Core / V8
- JSBinding
- Native UI / Skia
Flutter
- wideget
- dart vm
- skia图形库
通用原理
- UI组件
- 烘托引擎
- 逻辑控制引擎
- 通讯桥梁
- 底层API抹平体现差异
跨端计划对比
相同是根据webview烘托,为什么小程序体会比webview流通?
小程序会先把需求的资源下载下来,在运用的时分直接运用;约束了相关DOM操作。
总结
参阅资料
浏览器架构解析:zhuanlan.zhihu.com/p/374543105
浏览器功用:blog.csdn.net/weixin_4247…
web.dev/vitals/
web.dev/optimize-lc…
web.dev/optimize-cl…
web.dev/optimize-fi…
www.npmjs.com/package/web…
developer.chrome.com/docs/crux/
别人笔记详细记载:/post/722374…