客户端容器 | 青训营笔记

70 阅读5分钟

浏览器架构

QAVO98GWS295}A6EGEKK3.png

浏览器分工

  • 浏览器(主进程):主要负责页面展示逻辑,用户交互,子进程管理;包括地址栏、书签、前进、后退、收藏夹等。
  • GPU进程:负责UI绘制,包含整个浏览器全部UI
  • 网络进程:网络服务进程,负责网络资源加载
  • 标签页(渲染进程):控制tab内的所有内容,将Html、Css和Javascript转换为用户可交互的网页
  • 插件进程:控制网站运行的插件,比如flash、ModHeader等
  • 其他进程:适用程序Storage/Network/Audio Service等

渲染进程-多线程架构

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

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

浏览器的渲染过程

DOM解析—>CSS解析—>样式计算—>布局树—>图层树—>绘制—>合并图层

渲染进程-页面绘制

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

从输入URL到页面加载的全过程

  1. 首先在浏览器中输入URL。

    • 检查输入的内容是否是一个合法的URL连接
    • 判断输入的URL是否完整,如果不完整,浏览器可能会对域进行猜测,补全前缀或者后缀
    • 使用用户设置的默认搜搜引擎来进行搜索
  2. 查找缓存:浏览器先查看浏览器缓存-系统缓存-路由缓存中是否有该地址页面,如果有则显示页面内容。如果没有则进行下一步。

    • 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
    • 操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统, 获取操作系统的记录(保存最近的DNS查询缓存);
    • 路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
    • ISP缓存:若上述均失败,继续向ISP搜索。
  3. DNS域名解析:浏览器向DNS服务器发起请求,解析该URL中的域名对应的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议

  4. 建立TCP连接:解析出IP地址后,根据IP地址和默认80端口,和服务器建立TCP连接

  5. 发起HTTP/HTTPS请求(建立TLS连接)

    浏览器发起读取文件的HTTP/HTTPS请求,请求报文作为TCP三次握手的第三次数据发送给服务器。

    • 向服务器发起TCP连接请求
    • 当这个请求到达服务端后,通过TCP三次握手,建立TCP的连接。
  6. 服务器响应请求并返回结果

    • 当浏览器到web服务器 的连接建立后,浏览器会发送一个初始的HTTP GET请求,请求目标通常一个HTML文件。服务器收到请求后,将发回一个HTTP响应报文,内容包括相关响应头和HTML正文。

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

  7. 关闭TCP连接:通过四次挥手释放TCP连接

  8. 浏览器解析渲染页面:

    • 处理HTML标记并构建DOM树
    • 处理CSS标记并构建CSS规则树
    • 构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树
    • 布局:计算出每个节点在屏幕中的位置(几何信息)
    • 绘制:即遍历render树,并使用UI后端层绘制每个节点。

XU)1ZRQ{EC$W3YOACNILL(4.png

  1. JS引擎解析过程:调用JS引擎执行JS代码(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)

    • 创建window对象:window对象也叫全局执行环境,当页面产生时就被创建,所有的全局变量和函数都属于window的属性和方法,而DOM Tree也会映射在window的doucment对象上。当关闭网页或者关闭浏览器时,全局执行环境会被销毁。
    • 加载文件:完成js引擎分析它的语法与词法是否合法,如果合法进入预编译
    • 预编译:在预编译的过程中,浏览器会寻找全局变量声明,把它作为window的属性加入到window对象中,并给变量赋值为'undefined';寻找全局函数声明,把它作为window的方法加入到window对象中,并将函数体赋值给他(匿名函数是不参与预编译的,因为它是变量)。而变量提升作为不合理的地方在ES6中已经解决了,函数提升还存在。
    • 解释执行:执行到变量就赋值,如果变量没有被定义,也就没有被预编译直接赋值,在ES5非严格模式下这个变量会成为window的一个属性,也就是成为全局变量。string、int这样的值就是直接把值放在变量的存储空间里,object对象就是把指针指向变量的存储空间。函数执行,就将函数的环境推入一个环境的栈中,执行完成后再弹出,控制权交还给之前的环境。JS作用域其实就是这样的执行流机制实现的。

前端性能performance

XU)1ZRQ{EC$W3YOACNILL(3.png

首屏优化

  1. 压缩、分包、删除无用代码
  2. 静态资源分离
  3. JS脚本非阻塞加载
  4. 缓存策略
  5. SSR
  6. 预置loading、骨架屏

渲染优化

  1. GPU加速
  2. 减少回流、重绘
  3. 离屏渲染
  4. 懒加载

JS优化

  1. 防止内存泄漏
  2. 循环尽早break
  3. 合理使用闭包
  4. 减少Dom访问防抖、节流
  5. Web Workers

为什么需要跨端

  1. 开发成本、效率
  2. —致性体验
  3. 前端开发生态 KR.png

跨段方案

  • webview
  • 小程序
  • RN/Weex
  • Lynx
  • Flutter 7008U1NSYEE1HL2BCO9%75R.png

跨端容器-常用WebView分类

常用webview,Android,IOS、国产Android 99E$EHW2DESODROZDI3.png

跨端容器-WebView使用原生能力

Javascript调用Native

  • API注入: Native获取Javascript环境上下文,对其挂载的对象或者方法进行拦截
  • 使用Webview URL Scheme 跳转拦截
  • IOS上 window.webkit.messageHandler直接通信

Native 调用Javascript

  • 直接通过webview暴露的API执行S代码
  • los webview.stringByEvaluatingJavaScriptFromString
  • Android webview.evaluateJavascript

跨端容器-React Native/WeeX

  1. 原生组件渲染
  2. React/Vue框架
  3. virtual dom
  4. JSBridge

B0ZC~F%7DFK$JV9.png

跨端容器-Flutter

  1. wideget
  2. dart vm
  3. skia图形库 saJOIlo7.png

跨端方案对比

9VW{Q3FM}Z$LO_O@V36W7.png