浏览器原理与实践

153 阅读9分钟

浏览器工作原理

宏观视角下的浏览器

  • 1991年,功能简单,不支持图片
  • Mosaic 浏览器出现,可以显示图片,为了区分浏览器是否能显示图片,出现了 UserAgent
  • UserAgent的作用:1.判断浏览器类型,采用兼容方案;2.判断是否为移动端;3.标识H5容器,方便调用H5容器特定接口;4.注意userAgent伪装成本很低,不要过于依赖。

Chromiun多进程架构

  • Browser进程:主进程,负责浏览器界面,页面管理
  • Render进程:渲染进程
  • NPAPI插件进程
  • GPU进度:当GPU硬件加速打开时才会创建

多进程架构的目的所在

  1. 职责分离,故障范围小
  2. 隔离性
  3. 性能

tcp协议:如果保证页面文件能够被完整送达浏览器

  • FP(First Paint)是指从页面加载到首次开始绘制的时长
  • 通过IP地址信息把数据包发送给指定的电脑,而UDP通过端口号把数据包分发给正确的程序
  • UDP不能保证数据可靠性,但是传输速度却非常快。UDP并不提供重发机制,UDP在发送之后也无法知道是否能达到目的地。UDP协议并不知道如何组装这些数据包。
  • TCP(传输控制协议)是一个面向连接、可靠的、基于字节流的传输层通信协议。
  • TCP提供重传机制;引入数据包排序机制,用来保证乱序的数据包组合成一个完整文件
  • TCP为了保证数据可靠性,牺牲了数据包的传输速度,因为三次握手数据包校验机制等把传输过程中的数据包的数量提高了一倍。

http请求流程

  • 在真正发起网络请求之前,浏览器会先在浏览器缓存中查询是否有要请求的文件。
  • 浏览器缓存是一种在本地保存资源副本,以供下次请求时直接使用的技术。

浏览器中的javascript执行机制

  • javascript代码执行过程中,先做变量提升,而之所以需要变量提升,是因为javascript代码在执行之前需要先编译
  • 在编译阶段,变量和函数会放在变量环境中,变量的默认值会被设置为undefined;在代码执行阶段,javascript引擎会从变量环境中去查找自定义的变量和函数。

v8工作原理

  • javaScript是一种弱类型、动态的语言。弱类型:意味着不需要告诉javascript引擎这个或那个变量是什么数据类型,javascript引擎在运行代码的时候自己会计算出来;动态:意味着你可以使用同一个变量保存不同类型的数据。

javaScript垃圾回收

  • 垃圾数据回收分为手动回收和自动回收两张策略。
  • javaScript java python 等语言,产生的垃圾数据是由垃圾回收器来释放的,并不需要手动通过代码来释放。
  • 当一个函数执行结束后,JavaScript引擎会通过向下移动Esp来销毁该函数保存在栈中的执行上下文。
  • V8会把堆分为新生代和老生代两个区域,新生代中存放的是生存时间短的对象,老生代中存放的生存时间久的对象。
  • 新生区通常只支持1~8M的容量,而老生区支持容量很大,对于两块区域,V8分别使用两个不同垃圾回收器,以便更高效地实施垃圾回收。
  • 副垃圾回收器,主要负责新生代垃圾回收; 主垃圾回收器,主要负责老生代的垃圾回收。

垃圾回收器的工作流程

  1. 标记空间中活动对象和非活动对象。活动对象:就是还在使用对象;非活动对象:就是可以进行垃圾回收的对象。
  2. 回收非活动对象所占据的内存。其实就是在所有标记完成之后,统一清理内存中所有被标记为可回收的对象
  3. 内存的整理。
  • 副垃圾回收器
    1. 新生代中采用Scavenge 算法来处理。scavenge算法,就是把新生代空间对半划分为两个区域,一半是对象区域,一半是空闲区域。
    2. 新加入的对象都会放到对象区域,当对象区域快被写满时,就需要执行一次垃圾清理操作。
    3. 复制存放对象到空闲区域并进行排列,复制后空闲区域就没有内存碎片了。
    4. 完成复制后,对象区域和空闲区域进行角色翻转,就是原来空闲变成对象区域,对象区域变成空闲区域。这样就完成垃圾对象的回收操作。角色翻转还能在新生代中这两个区域无限重复使用下去 javascript引擎采用了对象晋升策略,就是经过两次垃圾回收依然还村活的对象,会被移动到老生区
  • 主垃圾回收器 主垃圾回收器采用标记-清除(Mark-Sweep)算法进行垃圾回收。 为了降低老生代垃圾回收而造成卡段,V8将标记过程分为一个个子标记过程,同时让垃圾回收标记和javascript应用逻辑交替进行,知道标记阶段完成,这个算法称为增量标记算法

浏览器中的页面循环系统

浏览器中的页面

  • HTML解析器并不是等整个文档加载完成之后再解析的,而是网络进程加载了多少数据,HTML解析器便解析多少数据
  • 如何去系统地优化页面
    1. 减少JavaScript脚本执行时间
    2. 避免强制同步布局
    3. 避免布局抖动
    4. 合理利用css合成动画
    5. 避免频繁的垃圾回收
  • webComponent
    • 什么是组件化?
      1. 对内高内聚,对外低耦合。

浏览器中的网络

http/0.9三个特点

  1. 只有一个请求行,没有请求头和请求体
  2. 服务器也没有返回头信息
  3. 返回的文件内容是以ASCII字符流传输的,因为都是HTML格式文件所以使用ASCII字符码传输是最合适的。

http/1.0

浏览器中展示的不单是HTML文件了,还包括了javascript、css、图片音频、视频等不同类型文件 支持多种类型文件下载是http/1.0一个核心述求

  1. 新增了请求头和响应头
  2. 引入了状态码
  3. 提供了Cache机制:用来缓存已经下载过的数据
  4. 请求头还加入用户代理的字段

http/1.1

  1. 增加持久连接
  2. 不成熟的http管道化:如果tcp通道中某个请求因为某些原因没有及时返回,那么就会堵塞后面所有请求,造成队头堵塞。http/1.1管线化将多个HTTP请求整批提交给服务器,虽然整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器请求。
  3. 提供虚拟主机的支持:HTTP/1.1请求头中增加了Host字段,用来表示当前域名地址,服务器可以根据不同的Host值做不同处理。
  4. 引入Chunk transfer机制,服务器会将数据分割成若干个任意大小的数据块
  5. 客户端Cookie、安全机制
  6. 浏览器为每个域名最多同时维护6个TCP持久连接
  7. 使用CDN的实现域名分片机制 缺点:对带宽的利用率却并不理想 原因: 1.TCP的慢启动;2.同时开启了多条TCP连接,那么这些连接会竞争固定的带宽;3.队头阻塞

HTTP/2

http/2的思路就是一个域名只使用一个TCP长连接来传输数据,这样整个页面资源下载过程只需要一次慢启动,同时避免了多个TCP连接竞争带宽所带来的问题。 http/2实现资源并行请求、

特性

  1. 可以设置请求的优先级
  2. 服务器推送
  3. 头部压缩

多路复用实现

http/2添加了一个二进制分帧层 缺陷:TCP队头堵塞 在TCP传输过程中,由于单个数据包的丢失造成的阻塞称为TCP上的队头堵塞

浏览器安全

同源策略

  1. DOM层面:限制了来自不同源的JavaScript脚本对当前DOM对象读写的操作
  2. 数据层面:限制了不同源站点读取当前站点的cookie、indexDB、LocalStorage等数据
  3. 网络层面:限制通过XMLHttpRequest等方式将站点数据发送给不同源的站点。

阻止xss攻击策略

  1. 服务器对输入脚本进行过滤或转码
  2. 充分利用csp
  3. 使用httpOnly属性

CSRF攻击

  1. 充分利用好cookie的SameSite属性 SameSite属性用来限制第三方Cookie,从而减少安全风险 1.1. SameSite=Strict:完全禁止第三方Cookie,跨站点时,任何情况都不会发送cookie.(只有网页的URL与请求目标一致,才会带上Cookie) 1.2. SameSite=Lax:导航到目标网址的GET请求。链接、预加载、get表单会带。 1.3. SameSite= None:前提必须同时设置Secure属性,cookie 只能通过Https协议发送。

  2. 验证请求的来源站点(referer是HTTP请求头中一个字段,记录了该HTTP请求的来源地址)

  3. 服务器策略优先判断Origin,请求头没有包含Origin属性,在根据实际情况判断使用referer属性

  4. CSRF Token

buffer详解

js语言自身只有字符串数据类型,没有二进制的数据类型,但是当需要处理类似于TCP流或文件流是,必须使用二进制。在node.js中引入Buffer类,该类是创建一个专门用来储存二进制数据的缓存区。

提高加载速度

  • 多个cdn域名:预加载:dns预期
  • 合并请求:nginx
  • 缓存:from disk memory localstorage
  • tcp网络连接优化:tcp调优
  • 资源大小:gzip,webp,imgap压缩,cookie体积
  • HTTP2,Keep-alive