客户端容器

117 阅读7分钟

(一)浏览器架构

1.演进

  1. 单进程架构:早期的浏览器架构
  2. 多进程架构:现代浏览器主流的架构,把每个进程(主进程等)隔离起来,运行在独立的沙箱里,安全性较高
  3. 面向服务架构:2的升级版,运行之前需要定义接口,通过调用接口
  4. 对比: Pasted image 20230421113440.png

2.任务管理器

打开谷歌的工具可以看到它的各个进程 Pasted image 20230421113752.png

3.多进程分工

  1. 主进程:主要负责页面展示逻辑,用户交互,子进程管理
  2. GPU进程:负责UI绘制,包含整个浏览器的UI
  3. 网络进程:加载网络资源
  4. 标签页(渲染进程):控制tab中的所有内容,将html,css和javascript转化Wie用户可交互的网页
  5. 插件进程:控制网站运行的插件
  6. 其他进程:

4.思考

早期的硬件比较昂贵,硬件发展不足,所以存在单进程 面向服务架构未来会替代多进程,他会根据用户的硬件来适配,当硬件不足时,会降低为多进程架构。

(二)渲染进程

1.常见浏览器内核

Pasted image 20230421114657.png

2.多进程架构

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

3.JS引擎VS渲染引擎

  1. 解析执行JS
  2. XML解析生成渲染树,显示在屏幕中
  3. 桥接方式通信

4.多线程工作流程

  1. 网络线程负责加载网页资源
  2. JS引擎解析JS脚本并且执行
  3. 在JS解析引擎空闲时,渲染线程会立刻工作
  4. 在用户交互、定时器操作等产生回调函数放入任务对列中
  5. 事件线程进行事件循环,将队列中的任务取出交给JS引擎执行

5.笔试题

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)

先输出最后一行的时间,20,接着接口回调到第一个setTimeout ,输出20,第二个输出30,但是实际偏差会在4秒以内。

(三)chrome浏览器的原理

1.如何展示网页

  1. 浏览器地址栏在输入url之后发生什么

2.输入处理

  1. 浏览器的UI线程会先检测用户输入的是URL地址,还是一个query查询
  2. 如果是URL地址,则会直接请求站点资源
  3. 如果是query,则会将输入发送给搜索引擎

3.开始导航

  1. 按下回车之后,UI线程通知网络线程发起一个网络请求,获取站点内容
  2. 在请求过程中,tab处于loading状态中

4.读取响应

  1. 在接收到http响应后,先检查响应头的媒体类型
  2. 如果响应的主体是一个HTML文件,浏览器将内容交给渲染进程处理
  3. 如果拿到的是其他类型的文件,比如ZIP,exe等,则交给下载管理器处理

5寻找渲染进程

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

6资源加载

  1. 在收到主进程的消息后。开始加载HTML文档
  2. 除此之外,还需要加载子资源,比如图片或者css样式文件

7构建渲染树

  1. 构建DOM树,将HTML文本转化为浏览器能够理解的结构
  2. 构建CSSOM树,将css代码转化为浏览器可以理解的CSSOM
  3. 构建渲染树,渲染树是DOM树和CSSOM树的结合

8页面布局

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

9页面绘制

  1. 构建图层:为特定的节点生成专用的图层
  2. 绘制图层:一个图层分为多个绘制指令,然后将指令按顺序组成一个绘制列表,交给合成线程
  3. 合成线程接受指令生成图块
  4. 栅格线程将图块进行栅格化
  5. 展示在屏幕上

首屏优化

  1. 压缩、分包、删除无用的代码
  2. 静态资源分离
  3. JS脚本非阻塞加载
  4. 缓存策略
  5. SSR :
  • 更快的首屏加载:这一点在慢网速或者运行缓慢的设备上尤为重要。服务端渲染的 HTML 无需等到所有的 JavaScript 都下载并执行完成之后才显示,所以你的用户将会更快地看到完整渲染的页面。除此之外,数据获取过程在首次访问时在服务端完成,相比于从客户端获取,可能有更快的数据库连接。这通常可以带来更高的核心 Web 指标评分、更好的用户体验,而对于那些“首屏加载速度与转化率直接相关”的应用来说,这点可能至关重要。

  • 统一的心智模型:你可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换。

  • 更好的 SEO:搜索引擎爬虫可以直接看到完全渲染的页面。

  1. 预置loading,骨架屏

渲染优化

  1. GPU加速
  2. 减少回流,重构
  3. 离屏渲染
  4. 懒加载 懒加载,即延迟加载(Lazyload)。简单来说就是一个长页面中需要展示很多图像的时候,如果在进入页面的时候一次性把所有图片加载完,需要很长的时间。为了提升用户体验,我们使用懒加载,当图片出现在浏览器可视区域时,才加载图片。例如各种电商页面。
  • 加快页面打开速度,提升用户体验
  • 减少服务器压力和浏览器的负担

js优化

  1. 防止内存泄漏: 产生内存泄漏:使用全局变量会有内存泄漏的风险;有一些dom,dom删除了,但是js变量没清空,dom引用会一直存在;定时器,忘记清楚会导致内存泄漏,可以封装一种可以自动清除的定时器
  2. 尽快结束循环:满足条件后尽快结束
  3. 合理使用闭包:减少单列元素的创建
  4. 减少Dom的访问
  5. 防抖,节流:防止多次提交,最后只会提交我们最后一次结果;保证在规定时间之内多次调用,只会调用一次结果。
  6. web workers:和js引擎相互独立,可以用在图片,音频等方面的处理

(三)跨端容器

1为什么需要

  1. 减少开发成本,效率
  2. 一致性体验
  3. 前段开发生态

2跨端方案

Pasted image 20230421211125.png

1.WebView

  1. 即网页视图,用于加载网页URL,展示其内容的控件
  2. 可以内嵌在移动端APP内,实现前段混合开发,大多数都是基于WebView的二次开发,
WebView 分类

Pasted image 20230422225225.png

WebView 的优势
  1. 一次开发,学习成本低
  2. 随时发布,即时更新
  3. 移动设备性能不断提升,性能有保障
  4. 通过JSBridge和原生系统交互,实现负责功能
WebView 使用原生能力
  1. JavaScript调用Native
    1. API注入:Native获取JS环境的上下文,对挂载的对象或者方法进行拦截
    2. 使用 WebView URL Scheme 跳转拦截
    3. IOS 上 使用此方法 window.webkit.messageHandler 可以直接通信
  2. Native调用JS
    1. 一般直接通过webview 暴露的API执行JS代码,每个APP都会自己约定好自己的通信格式
    2. IOS WebView.stringByEvaluatingJavaScriptFromString
    3. Android WebView.evaluateJavascript
WebView <->Native 通信

Pasted image 20230422230419.png

跨端方案对比

Pasted image 20230422231257.png