| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> 浏览器原理二三事 -> 正文阅读 |
|
[JavaScript知识库]浏览器原理二三事 |
目录 2.3?浏览器渲染进程(Renderer 进程)包含的五种线程 6.2 强制缓存(Expires、Cache-Control) 6.2.1?Cache-Control VS?Expires 6.2.2?Cache-Control: no-cache VS Cache-Control: no-store 1. 如何理解?JavaScript 是单线程的JavaScript 是单线程的:
JavaScript 设计为单线程的原因:
2.?进程与线程2.1 在浏览器中,如何理解进程和线程的关系?以 Chrome 浏览器为例:
为什么浏览器是多进程的?
2.2?浏览器的五种进程打开 Google 中的任务管理器(Shift + Esc 或者 Chrome 更多工具 →?任务管理器) 可以看到展现了四种进程:
2.2.1 浏览器主进程(Browser 进程)只有一个主进程,主要负责:
2.2.2 浏览器渲染进程(Renderer 进程)就是通常所说的浏览器内核,排版引擎?Blink?和?JavaScript?引擎?V8?都运行在该进程中 核心任务:将?HTML、CSS?和?JavaScript?转换为用户可以与之交互的网页(实现 —— 页面渲染、脚本执行、事件处理等) 出于安全考虑,渲染进程都是运行在沙箱模式下 默认情况下,Chrome?会为每个?Tab?标签创建一个渲染进程,互不影响;存在多个标签页时,会自动合并进程 2.2.3 GPU?进程GPU?的使用初衷是为了实现?3D?CSS?的效果 只是随后网页、Chrome?的?UI?界面都选择采用?GPU?来绘制 GPU 进程可以禁用,只有一个 GPU 进程 2.2.4 第三方插件进程主要是负责插件的运行,每种类型的插件,对应一个进程 因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响 2.2.5 网络进程主要负责页面的网络资源加载 之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程 2.3?浏览器渲染进程(Renderer 进程)包含的五种线程前面说过,Renderer 进程的核心任务:将?HTML、CSS?和?JavaScript?转换为用户可以与之交互的网页(实现 —— 页面渲染、脚本执行、事件处理等) 2.3.1 GUI 渲染线程主要负责页面的渲染,解析?HTML、CSS,构建?DOM?树,布局和绘制等 当界面需要重绘(Repaint)或 由于某种操作 引发回流(reflow)时,该线程就会执行 2.3.2 JavaScript 引擎线程该线程主要负责处理?JavaScript?脚本,执行代码 一个 Tab 页(Renderer进程)中,无论什么时候,都只有一个 JavaScript? 线程在运行 JavaScript? 程序 该线程与?GUI?渲染线程互斥,当 JavaScript? 引擎线程执行?JavaScript?脚本时间过长,将导致页面渲染的阻塞 2.3.3 事件触发线程用来控制事件循环,将准备好的事件交给?JavaScript?引擎线程执行 事件触发线程不属于 JavaScript 引擎线程,而是属于浏览器(JavaScript 引擎线程自己忙不过来,需要浏览器再开一个线程协助他) 比如?setTimeout?定时器计数结束,?ajax?等异步请求成功并触发回调函数,或者用户触发点击事件时,该线程会将整装待发的事件,依次加入到任务队列的队尾,等待?JavaScript?引擎线程的执行 2.3.4 定时器触发线程负责执行异步定时器一类的函数的线程,如:?setTimeout,setInterval 浏览器定时计数器,并不是由 JavaScript 引擎计数的,因为 JavaScript?引擎是单线程的,如果处于阻塞线程状态,就会影响记计时的准确性 2.3.5 异步http请求线程负责执行异步请求一类的函数的线程,如:?Promise,axios,ajax?等 2.4?Chrome 打开一个页面需要启动多少进程?
最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。 3.?script 标签上的 async、defer3.1 为什么要使用?async、defer先来谈一下浏览器的渲染机制:浏览器有 GUI 渲染线程与 JavaScript 引擎线程,这两个线程是互斥的关系 JavaScrip t的加载、解析与执行会阻塞 DOM 的构建。也就是说,在构建 DOM 时,HTML 解析器若遇到了JavaScript,那么它会暂停构建 DOM,将控制权移交给 JavaScript 引擎,等 JavaScript 引擎运行完毕,浏览器再从中断的地方恢复DOM构建 综上所述,直接使用 script 标签,会阻塞 DOM 渲染;但如果使用带有 async 和 defer 的 script 标签,就会异步请求这些资源,不会阻塞页面渲染 浏览器渲染过程分为:构建DOM -> 构建CSSOM -> 构建渲染树 -> layout布局 -> 绘制 3.2?async、defer?的区别记忆要点:
3.2.1?执行顺序的区别async 是无顺序的加载,而 defer 是有顺序的加载 async 的执行,并不会按照 script 在页面中的顺序来执行,而是谁先加载完谁执行 defer 的执行,则会按照引入的顺序执行,即便是后面的 script 资源先返回 3.2.2 使用场景的区别defer 可以用来控制 JavaScript 文件的加载顺序;比如 jqery 和 Bootstrap,因为 Bootstrap 中的 JavaScript 插件依赖于 jqery,所以必须先引入jquery,再引入 Bootstrap 文件 如果你的脚本并不关心页面中的 DOM 元素(文档是否解析完毕),并且也不会产生其他脚本需要的数据,使用 async, 如统计、埋点等功能 3.2.3?window.onload 执行顺序的区别使用 defer 的 script 标签,会在 window.onload 事件之前被执行 使用 async 的 script 标签,对 window.onload 事件没有影响,window.onload 可以在之前或之后执行 4.?DOM 事件流(事件执行顺序)4.1 事件流的基本概念DOM 同时支持两种事件模型:
DOM 事件流的三个阶段:
DOM 事件捕获 的具体流程:window??document??html??body??目标元素; DOM 事件冒泡?的具体流程:目标元素??body??html??document??window; 4.2 事件委托(利用事件冒泡的原理)事件委托的原理:
事件委托优点:可以减少事件的注册,节省内存;也可以实现新增对象时,无需再次绑定事件 4.3?addEventListener 的第三个参数第三个参数默认是 false,表示在 事件冒泡 阶段调用; 第三个参数值为 true 时,表示在 事件捕获 阶段调用; 4.4 事件流的执行顺序(先捕获再冒泡)
5. 浏览器空闲时间页面是一帧一帧绘制出来的,一般情况下,设备的屏幕刷新率为 1s 60次,而当 FPS 小于 60 时,会出现一定程度的卡顿现象 5.1 浏览器一帧内做了什么首先需要处理输入事件,能够让用户得到最早的反馈 接下来是处理定时器,需要检查定时器是否到时间,并执行对应的回调 接下来处理?Begin?Frame(开始帧),即每一帧的事件,包括?window.resize、scroll、media、query、change?等 接下来执行请求动画帧?requestAnimationFrame(rAF),即在每次绘制之前,会执行?rAF?回调 紧接着进行?Layout?操作,包括计算布局和更新布局,即这个元素的样式是怎样的,它应该在页面如何展示 接着进行?Paint?操作,得到树中每个节点的尺寸与位置等信息,浏览器针对每个元素进行内容填充 到这时以上的六个阶段都已经完成了,接下来处于空闲阶段(Idle?Peroid) 5.2?requestIdleCallback在空闲阶段(Idle Peroid)时,可以执行 requestIdleCallback 里注册的任务 requestIdleCallback 接受了两个参数:
? 1)第一个参数是一个函数,该函数的入参,可以获取:
? 2)第二个参数,传入 timeout 参数自定义超时时间,如果到了超时时间,浏览器必须立即执行
打印结果: 6. 浏览器缓存6.1 协商缓存(Etag、Last-Modified)6.1.1 协商缓存基本过程1)第一次请求
2)第二次请求
6.1.2?Etag VS Last-Modified当 ETag 和 Last-Modified 同时存在时,服务器优先检查 ETag Etag 是服务器文件的唯一标识,当文件内容变化时,Etag 值也会发生变化 Etag 主要为了解决 Last-Modified 无法解决的一些问题。一些文件也许会周期性的更改,但是它的内容并不改变(也就是说,仅仅改变了修改时间),此时希望重用缓存,而不是重新请求 6.2 强制缓存(Expires、Cache-Control)6.2.1?Cache-Control VS?ExpiresCache-Control:max-age —— 表示缓存内容在 xxx 秒后失效;【优先级更高】 Expires —— 表示服务端返回的到期时间;也就是说,返回的是服务端时间,与客户端时间相比,可能会时间不一致 6.2.2?Cache-Control: no-cache VS Cache-Control: no-storeCache-Control:?no-cache ——?浏览器每次都会向服务器发起请求,来验证当前缓存的有效性 Cache-Control:?no-store ——?响应不被缓存 7.?垃圾回收机制7.1?GC 垃圾回收策略7.1.1 标记清除分为 标记 和 清除 两个阶段:
基本步骤:
7.1.2 引用计数一个对象,如果没有其他对象引用到它,这个对象就是?零引用,将被垃圾回收机制回收 它的策略是 —— 跟踪记录每个变量值被使用的次数 基本步骤:?
7.2?分代式垃圾回收机制V8 采用了一种代回收的策略,将内存分为两个生代:
基本步骤:
? 7.2.1?新生代的垃圾回收方式将内存空间一分为二,分为:
当新生代内存不足时,会将 From 空间中存活的对象,复制到到 To 空间,然后将 From 空间清空,交换 From 空间和 To 空间(将原来的 From 空间变为 To 空间),继续下一轮 7.2.2?老生代的垃圾回收方式V8在老生代中,主要采用了 Mark-Sweep 和 Mark-Compact 相结合的方式 Mark-Sweep 遍历堆内存中的所有对象,并标记活着的对象,在随后的清除阶段,只清除没有被标记的对象,这就导致了 —— 在进行清除回收以后,内存碎片化 Mark-Compact 用来解决内存碎片的问题,将将存活对象向内存一侧移动,清空内存的另一侧,这样空闲的内存都是连续的 7.2.3 新老生代在不同系统的内存大小64 位系统,新生代内存大小为 32MB,老生代内存为 1.4G 32 位系统,新生代内存大小为 16MB,老生代内存为 0.7G 7.3 垃圾回收机制参考文章 |
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/22 18:31:39- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |