浏览器工作原理和V8引擎

982 阅读5分钟
  • TSJS

    其实TS还是基于JS的 只是因为JS里面没有类型检测(也就是对变量 函数参数等类型进行限制) 这可能会对我们的项目带来一些安全隐患

  • 浏览器工作原理

image.png

  • 浏览器内核

不同浏览器都不不同的浏览器内核

image.png

排版引擎也叫做 浏览器引擎。。。其实都是浏览器内核

  • 浏览器渲染过程

image.png

js代码是由谁来执行的?

JavaScript引擎
  • 高级的编程语言都是需要转化成最终的机器指令来执行的
  • 编写的JS代码无论是是交给浏览器或Node执行 最后都是需要被CPU执行的
  • 我们需要使用JS引擎JS代码翻译成CPU指令来执行

浏览器内核和js引擎的关系

  • WebCore 负责html解析 布局 渲染等工作

  • jscore 解析 执行js代码

  • 小程序中的js代码就是jsCore执行的

  • 另一个强大的js引擎就是V8引擎

V8引擎的原理

是由C++编写的 Google高性能的 js和WebAssembly引擎 用于chrome和node.js

v8可以独立运行 也可以嵌入任何的c++应用程序中

js(源代码) => Parse => AST(抽象语法树) => Ignition

image.png

tips:

  • parse是解析的意思 这里工作的作用是进行词法分析
const name = "professor"
tokens: {type:'keyword', value:'const'}
	{type:'identifier' value:'name'}
  • 抽象语法树就是把js代码
  • map:是es6最新的语法 map遍历数组 用法👇

let numbers = [1,2,3]

let dou = numbers.map((number) => number * 2)

  • 抽象语法树(AST) :这个东西的应用场景很广泛 例👇

    • babel
    • ts代码 -> AST => new AST => generate code => js代码
    • vue template => AST => createVNode
  • TurboFan

这个的作用就是可以让解析成机器码的指令先保存起来 当有多个相同的操作的时候 function sum(n1, n2)这种类似的时候 就可以直接执行 不用再继续变成汇编指令重新解析 可以大大的提供效率

  • Deoptimization

这个的作用是 当遇到参数不对的时候 会重新把机器码转化为字节码进行解析 sum("aa", "bb")这样的话就会判断错误

所以V8引擎的简单流程其实可以是 js => AST =>

image.png

image.png

image.png

image.png

❗作用域提升

  • 关于全局函数执行过程

image.png

image.png

> #### 反正这个大概的意思就是说呢 在编译的时候发现是一个函数的时候 就会自动生成一个`函数执行上下文(FEC)` 然后这个东西里面就会又放着一个 `内存地址` 这个全局对象面对的就不是 `GO` 了 而是 `AO(activation Object)活跃对象` 也就是那个这个活跃对象里面会放着函数里面的数据变量 随着函数内部代码的编译 数据也会逐渐更新 初始值都是`undefined` 等到这个函数执行完的时候这个新的地址也会随之被销毁掉 但是那个 `AO` 会一直保留下来 直到下次调用的时候再继续改变 `AO` 里面的值 所以在`AO`里面函数的值对应的是函数那个栈的内存地址

image.png

image.png

当函数执行的时候 就会给函数分配一个函数存储空间 然后就会调用函数执行上下文 在全局对象的函数名所对应的value值指向的就是那个函数存储空间 编译执行的时候遇到这个函数名的时候就找到这个函数存储空间的地址 然后再创建一个函数地址 创建函数执行上下文执行函数

  • 执行函数的时候就会创建一个函数执行上下文
  • 函数执行上下文里面包含一个 VO(指向的可能是AO也可能是GO) 还有函数执行的代码

AO内的数据刚开始都是undefine的 函数除外 然后会随着函数的执行逐渐给AO赋值

环境变量和记录

早期的ECMA标准中是这样的👇

每一个执行上下文都会被关联到一个环境变量(variable object, VO),源代码中的变量和函数声明会被作为属性添加到VO中 对于函数来说参数也会被添加到VO中 最新的ECMA标准是这样的👇 每一个执行上下文都会关联到一个环境变量(VariableEnvironment)中,执行代码中变量和函数的声明会作为环境记录,添加到变量环境中

image.png

  • 定义一个普通变量代表会出现一个GO对象 GO对象中的变量初始值为undefined

  • 定义一个函数则代表会出现一个FEC 函数执行对象

image.png

image.png 直接执行的时候 遇到的变量或者函数就是放在GO里面 遇到函数的时候 函数里面内容的编译就是放在AO里面

function foo() {
    m = 10
}
console.log(m); //10functionfoo() {
    var m = 10
}
console.log(m); //undefined

image.png

  • 代码的执行过程中都是需要分配内存的

  • JS对于基本数据类型内存的分配都是在执行的时候直接在栈空间进行分配的

  • JS对于复杂数据类型内存的分配会在堆内存中开辟出一块空间 空间的指针返回值变量引用

  • Js中的垃圾回收

由于手动管理的效率实在是太低了 而且对于开发的的要求也很高 一不小心就会产生内存泄漏 所以像 Java中的JVM, js运行环境中的js引擎 都会内存 垃圾回收器(GC)

image.png

\