乐趣区

关于javascript:理解-JavaScript-的运行环境

前言

​ 感觉本人做前端这行业,应该要靠近两年了吧。在这两年或者三年(大四的时候也在接触)中,天天跟着 JavaScript 语言打交道。从大学开始学习的 JavaScript 语法JQuery 库,而后到为了找工作学习 Vue2, 却找了一个应用 React 的公司,以及在平时学习最新进去的 Vue3。下面一系列的过程,全都是在跟 JavaScript 打交道。所谓的打交道,就是在应用过程中,不停的应用根底语法进行开发,就没有而后呢 ……

​ 兴许,如果没有想着要晋升本人的实力程度,这样就行了,实现就是指标。然而大多数人,应该都还是想晋升本人的实力的(其中也包含我吧)。所以,应用 JavaScript 编程,不仅须要对根本语法进行把握,也要对其中的一些原理进行理解吧。

因为理解假相,你能力取得真知的自在。

​ 在平时筹备面试的时候,总会看到一些关键词 浏览器内核JavaScript 引擎。那么这两个到底是干什么的呢?在其中起到了什么作用呢?

​ 我跟随着 前端大神 coderwhy老师的脚步,理解假相,记录此篇。(此篇基本上是纯理论,然而如果懂了,获益良多)

意识 JavaScript

JavaScript 是一门编程语法,简略的来说,是一门高级的编程语言。为啥说是 高级的编程语言 呢?

那么有高级编程语法,那么就有低级编程语法。

  • 机器语言(低级):所谓的机器指令(二进制编码 01010011111000)
  • 高级语法:C、C++、Java、JavaScript 等

针对计算机而言,基本就不意识所谓的高级语言,写的啥齐全看不懂。想要被计算机所意识,那么所谓的高级语言就须要转换成机器指令。所以,JS 代码就会被转化成机器语言,被计算机的 CPU 所意识。

大抵就是这么一回事。

这个解析的过程就是 JS 引擎,上面会更加具体的阐明。

浏览器的工作原理

有没有深刻的思考过:JavaScript 代码是如何在浏览器中被执行的?

比方:浏览器中输出 http://www.baidu.com,其中做了什么?

步骤解析:

  1. 输出 http://www.baidu.com, 就会被浏览器解析成一个 ip 地址(假如: 111:222:333:444), 依据这个 ip 地址,就会找到一台服务器,服务器就会返回一个 index.html 文件,用来解析。(留神: 这里并不是把所有的动态资源到返回了,在框架时代,就应该是所谓的 分包 操作吧。打包成多个 chunk.js, 用到时再加载)。
  2. 在解析 index.html 过程中,如果遇到 link 标签,就会去服务器中下载对应的 css 文件;如果遇到了 script 标签,就回去服务器中下载对应的 js 文件。

在下面的过程中,拿到 index.html 文件,被解析,是被谁所解析的呢?

答案是:浏览器内核

意识浏览器内核

在筹备面试题的时候,或多或少都会理解到浏览器的内核。

不同的浏览器有不同的内核组成。

常见的几种内核:

  • Gecko: 晚期被 Netscape 和 Mozilla Firefox 浏览器应用。
  • Trident: 微软开发,被 IE4~IE11 浏览器应用,然而 Edge 浏览器曾经转向 Blink。
  • Webkit: 苹果基于 KHTML 开发,开源的,用于 Safari,Google Chrome 之前也在应用。
  • Blink: 是 Webkit 的一个分支,Google 开发,目前利用于 Chrome、Edge,Opera 等。

事实上,浏览器的内核指的是 浏览器的排版引擎

排版引擎:也称为浏览器引擎,页面渲染引擎。从字面量的大抵意思:浏览器内核就是解决页面布局的。

浏览器渲染流程

依据下面的图解,能够得出以下信息:

  • HTML 通过 HTML Parser 生成解析 DOMTree,Style 通过 CSS Parser 解析生成 StyleRules。
  • DOMTree 和 StyleRules 联合,生成渲染树(RenderTree)
  • 执行 layout 过程,确定每个节点在屏幕上的确切坐标。
  • 渲染树 绘制(Painting),而后展现在屏幕上。

留神:下面的步骤并不是严格程序执行的。浏览器引擎会以最快的速度展现内容。简略的来说,就是一边解析 HTML 一边构建渲染树,构建一部分,就会把当前的元素渲染进去。如果款式没有加载进去,就会以浏览器默认的款式展现。

正是因为浏览器引擎的尽快展现内容,就会造成款式还没加载就展现的问题。这就是常常产生的 FOCU(flash of unstyled content)或则 白屏问题。

CSS 加载不会阻塞 DOM 树的解析

通过下面的图解能够看出,HTML 解析和 CSS 解析,是并行的。所以 CSS 加载不会阻塞 DOM 树的解析

CSS 加载会阻塞 DOM 树的渲染

渲染树(RenderTree)是 DOMTree 和 StyleRules 的联合。所以,就算 DOMTree 加载实现,也要等到 CSS 加载实现并解析实现,能力生成渲染树。

JS 执行会阻塞 DOM 树的解析

从渲染图能够晓得 HTML 解析成 DOMTree,如果遇到 JavaScript 代码,就会进行解析 HTML,就会把控制权交给 JS 引擎,去执行 JavaScript 代码。当 JavaScript 执行实现后,浏览器再从中断的中央持续解析生成 DOM。

这也是倡议将 script 标签放在 body 标签底部的起因。

非凡状况:

在下面也说过了,CSS 加载不会阻塞 DOM 树的解析。然而呢?如果在解析 DOM 的时候,外面退出 script 标签,引入了 JavaScript 代码(js 是万能的,也能够批改 DOM,也能够批改款式)。如果 JavaScript 代码,须要批改款式,那么就须要期待 CSS 加载结束,能力操作 CSS。所以在这种非凡的状况下,css 加载也是会阻塞 DOM 的解析

优化渲染过程

  • 应用内联的 JS、CSS,缩小 JS、CSS 文件的下载。
  • webpack 等工具对 JS、CSS 文件压缩,缩小文件的大小。
  • 应用 async 或者 defer。
  • 应用 CDN。

意识 JavaScript 引擎

在下面的浏览器渲染过程中,在解析 DOM 的时候,会遇到 JavaScript 代码,那么这下的控制权就会交给 JS 引擎来执行 JavaScript 代码。

为什么须要 JavaScript 引擎?

后面说过,JavaScript 是一门高级的编程语言,想要被计算机 CPU 意识,就须要转化成机器指令。JavaScript 引擎就是来做这一件事的,把 JS 代码转化机器指令

常见的 JavaScript 引擎

  • SpiderMonkey: 第一款 JavaScript 引擎,由 Brendan Eich 开始(也就是 JavaScript 的作者)。
  • Chakra: 微软开发,用于 IE 浏览器。
  • JavaScriptCore: Webkit 中的 JavaScript 引擎,Apple 公司开发。
  • V8: Google 开发的弱小 JavaScript 引擎。

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

这里以 Webkit 内核为例:

Webkit 事实上有两局部组成:

  • WebCore: 负责 HTML 解析、布局、渲染等等事件。
  • JavaScriptCore: 解析、执行 JavaScript 代码。

跟微信小程序架构很类似。

能够看出关系:JavaScript 引擎是浏览器内核组成的一部分。

意识 V8 引擎(理解)

定义

V8 引擎是 C ++ 编写的 Google 开源高性能的 JavaScript 引擎,用于 Chrome 和 Node.js 等。

运行流程

JS 引擎就是把 JavaScript 代码转化成机器指令,在计算机的 CPU 中运行。

Parse 模块 拿到 JavaScript 源码会进行解析生成 AST 树,AST 树简略来说,就是一个固定格局对象,通过一系列的解决,变成字节码(bytecode), 最初变成机器指令。

AST 树应该不生疏吧。在当初的框架时代,react 的 jsx 解析,vue 的 template 解析,还是 ts 解析,babel 解析等等操作,都是离不开生成 AST 树进行转换的。

测试 AST 树结构的地址:https://astexplorer.net

V8 执行的细节

Parse 的 V8 官网地址:https://v8.dev/blog/scanner

JavaScript 源码如何被解析(Parse)的呢?

  • Blink 将源码交给 v8, Stream 获取源码并进行编码转换。
  • Scanner 会进行词法剖析,词法剖析会将代码转化成 tokens。

    const name = 'copyer'
    // 解析成 tokens
    tokens = [{type: 'VariableDeclaration', value: 'const'}, 
        {type: 'Identifier', value: 'name'},
        {type: 'Literal', value: 'copyer'}
    ]

    大抵的模式就是这样的。

  • 而后就是 tokens 转化为 AST 树,会通过两个步骤 Parser 和 PreParser.

    • Parser 就是间接将 tokens 转成 AST 树。
    • PreParser 称为预解析,解决一些最开始不须要执行的代码,不须要转成 AST 树,只须要在调用的时候,才解析。目标就是为了性能优化。
  • 最初就是依据 AST 生成 bytecode,转化成机器指令。

总的来说,下面的一系列步骤,只须要有点印象即可。然而须要理解一个步骤:

Parse 模块解析,这里会进行 词法剖析 语法分析

在开发过程中,变量的晋升就是在语法分析 这一步实现的。

总结

​ 该篇文章齐全就是纯理论,就是为了当前在 JavaScript 方向倒退,有一个更好的意识而已。兴许,对于我来说,明天学习了,感觉懵懵懂懂的晓得了(只有常常应用,相熟了,可能才不会遗记)。然而过几天之后,兴许就可能遗记了。这篇就是为了帮忙我当前更好的回顾一下,我已经理解过,遗记了,我能够再次相熟。

​ 尽管是纯理论,然而不可否认,这些实践的重要性,能够更好的了解咱们在开发中的一些景象和问题。同时也是菜鸟向 JavaScript 学习的进阶的方向。

退出移动版