客户端容器 | 青训营笔记

82 阅读6分钟
  • web浏览器以及跨端方案

1浏览器架构

1.1浏览器架构演进

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

  • 多进程架构:主进程、网络进程、渲染进程、GPU进程、插件进程->各个进程相对独立

    • 虽然各进程分配独立内存区域,但是有些进程功能可能较大,耦合度高
  • 面向服务架构:将原来的UI、数据库、文件、设备、网络等,作为一个独立的基础服务,模块划分更细

    • 服务模块划分更细,更加内聚,耦合度更低

1.2多进程分工

进程名称进程描述
浏览器(主进程)主要负责页面展示逻辑,用户交互,子进程管理;包括地址栏、书签、前进、后退、收藏夹等
GPU进程负责UI绘制,包含整个浏览器的全部UI,不是tab页里面的东西
网络进程网络服务进程,负责网络资源加载
标签页(渲染进程)控制tab内的所有内容,将html、css和js转换为用户课交互的网页
插件进程控制网站运行的插件,比如flash、modheader
其他进程适用程序:storage/network/audio service

2.渲染进程

2.1常见浏览器内核

2.2多线程架构

  • 渲染进程内部是多线程实现,主要负责页面渲染,脚本执行,事件处理,网络请求
线程功能
js引擎负责解析js脚本,运行js程序,每个渲染进程下面只有一个js引擎线程。与gui渲染线程互斥,如果js任务执行事件过长,会导致页面卡顿
gui渲染负责渲染浏览器界面,解析html、css,构建dom树和render树、布局、绘制。和js引擎线程互斥,gui更新会在js引擎空闲时立即执行
定时器触发定时器所在线程,setTimeout、setInterval计时完毕后,将回调添加到事件队列,等待js引擎执行
网络线程在XHR、Fetch等发起请求后新开一个网络线程请求,如果设置了回调函数,在状态变更时,将回调放入事件队列,等待js引擎执行
事件触发由宿主环境提供,用于控制事件循环,不断地从事件队列了取出任务执行
  • js引擎 vs gui引擎

    • 解析执行js
    • xml解析生成渲染树,显示在屏幕
    • 桥接方式通信

2.3多线程工作流程

  • 网络线程负责加载网页资源
  • 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)//输出?
        

3.Chrome运行原理

3.1如何展示网页

  • 浏览器地址输入url后发生了什么

3.2输入处理

  • 用户url框输入内容后,ui线程会判断输入的是url地址还是一个query查询条件

    • 如果是url,直接请求站点资源
    • 如果是query,将输入发送给搜索引擎
  • 例如输入www.baidu.com和输入百度回车后不同的效果

3.3开始导航

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

  • 请求过程中tab处于loading状态

3.4读取响应

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

3.5寻找渲染进程(render)

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

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

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


渲染进程工作流程

3.6资源加载

  • 收到主进程的消息后,开始加载html文档

  • 除此之外,还需要加载子资源,比如图片、css样式文件以及js脚本

3.7构建渲染树

  • 构建DOM树,将HTML文本转化成浏览器能够理解的结构
  • 构建CSSOM树,浏览器同样不认识CSS,需要将CSS代码转化为可理解的CSSOM
  • 构建渲染树,渲染树是DOM树和CSSOM树的结合

3.8页面布局

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

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

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

3.9页面绘制

  • 构建图层:为特定的结点生成专用图层

  • 绘制图层:一个图层分成很多绘制指令,然后将这些指令按顺序组成一个绘制列表,交给合成线程

  • 合成线程接收指令生成图块

    • 将指令整合
  • 栅格线程将图块进行栅格化

    • 转成位图,使用GPU加速
  • 展示在屏幕上

4.前端优化

4.1首屏优化

  • 压缩、分包、删除无用代码

  • 静态资源分离

  • js脚本非阻塞加载

  • 缓存策略

  • Ssr

  • 预置loading、骨架屏

4.2渲染优化

  • GPU加速

  • 减少回流、重绘

  • 离屏渲染

    • 先提前进行渲染
  • 懒加载

    • 提前加载到本地,需要时从缓存中去

4.3JS优化

  • 防止内存泄露

    • 注意全局变量

    • dom引用

    • 定时器

      • 可以自动清除定时器
  • 循环尽早break

  • 合理使用闭包

  • 减少dom访问

  • 防抖、节流

  • Web workers

5.跨端容器

5.1为什么需要跨端

  • 开发成本低、效率高

    • 多端可以使用
  • 一致性体验

  • 前端开发生态

5.2常见跨端方案

  • Webview

  • 小程序

  • RN/WeeX

  • Lynx:字节内部的方案

  • Flutter

5.3WebView

  • 网页视图,用于加载网页url,并展示其内容的控件

  • 可以内嵌在移动端app内,实现前端混合开发

  • 常见的webview分类

  • 优势

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

  • webview<->native(jsBridge)

5.4小程序

  • 架构

    • 渲染层-webview
    • 双线程,多webview架构
    • 数据通信,native转发

5.5react native/weex

  • 原生组件的渲染
  • react/vue框架
  • Virtual dom:是dom的一个对象
  • jsbridge

5.6Lynx

  • 基于vue框架

5.7flutter

5.8通用原理

  • UI组件
  • 渲染引擎
  • 逻辑控制引擎
  • 通信桥梁
  • 底层API抹平表现差异

5.9对比