JavaScript代码是怎么在浏览器里面运行起来的?
JavaScript代码是怎么在浏览器里面运行的?下面简单探索一下
浏览器内核
浏览器内核(Rendering Engine),常见的叫法如:排版引擎、解释引擎、渲染引擎,现在流行称为浏览器内核。
| 浏览器 | 内核 | 说明 |
|---|---|---|
| IE | Trident | IE、猎豹安全、360极速浏览器、百度浏览器 |
| FireFox | Gecko | 可惜这几年已经没落了,打开速度慢、升级频繁、猪一样的队友flash、神一样的对手chrome。 |
| Safari | Webkit | 从Safari推出之时起,它的渲染引擎就是Webkit,一提到 webkit,首先想到的便是 chrome,可以说,chrome 将 Webkit内核 深入人心,殊不知,Webkit 的鼻祖其实是 Safari。 |
| Chrome | Chromium/Blink | 在 Chromium 项目中研发 Blink 渲染引擎(即浏览器核心),内置于 Chrome 浏览器之中。Blink 其实是 WebKit 的分支。大部分国产浏览器最新版都采用Blink内核。二次开发 |
| Opera | Blink |
浏览器渲染过程

HTML首先会被浏览器内核中的HTML Parser解析,最终会构建成一颗DOM树。CSS会被浏览器内核中的CSS Parser解析,形成CSS规则,CSS规则和DOM树结合形成一个渲染树,通过layout(布局)生成最终的渲染树。
为什么要有
layout呢?因为要适配不同尺寸的屏幕。有了渲染树之后就可以绘制展现出来了。
常见的js引擎
SpiderMonkey:第一款js引擎,由Brendan Eich开发(js作者)。
Chakra:微软开发,由于IE浏览器。
JavascriptCore:webkit的js引擎,Apple公司开发。
V8:Google开发的强大js引擎,也帮助Chrome从众多浏览器中脱颖而出。
浏览器内核和js引擎的关系
这里用webkit为列,webkit最重要的两部分:
WebCore: 负责HTML、CSS的解析、布局、渲染等相关工作;JavascriptCore:解析、执行js代码。
下面是Chromium的架构图

普通JavaScript引擎(笨重)
作用:javascript引擎帮助我们将js代码编译成CPU认识的指令集,最终被cpu执行。
普通JavaScript引擎除了编译之外还要负责执行以及内存管理。 js是解释形语言,由引擎直接读取源码,一边编译一边执行,这样效率相对较低,而编译形语言(如c++)是把源码直接编译成可直接执行的代码执行效率更高。

随着技术的发展,对JavaScript性能的要求越来越高,V8引擎就是在此背景下产生的,它产生的目的就是为了提高javascript执行的性能。
V8引擎(轻量)
V8引擎是一个JavaScript引擎实现,最初由一些语言方面专家设计,后被谷歌收购,随后谷歌对其进行了开源。
V8使用C++开发,在运行JavaScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8将其编译成原生机器码(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如内联缓存(inline caching)等方法来提高性能。
将javascript代码转换成AST
V8引擎会先将javascript代码转换成AST(抽象语法树),事实上所有的编程语言都会将源代码解析成抽象语法树(abstract syntax tree, AST)。
AST是计算机科学中很早的一个概念,不是V8特有的(只是V8在转换过程中做了非常多的优化),更不是javascript特有的。
AST的用途
AST的作用也不仅仅是用来在V8的编译上,比如我们常用的babel插件将 es6->es5 、ts->js 、死区分析、Dead Code、编译压缩打包、css预处理器、eslint等等,这些功能的实现都离不开AST。
AST编译过程

V8执行js的简易流程
浏览器内核将源码以流的方式交给v8引擎,v8引擎获取到源码并进行编码转换
词法分析Scanner,将代码转成tokens
语法分析Parser、Preparser,直接将tokens转换成AST树结构
字节码生成
parser就是直接将tokens转换成AST树结构
preParse称之为预解析,为什么需要预解析呢?
这是因为并不是所有的js代码一开始就会被执行,如果对所有的js代码都进行解析,会影响网页运行效率。所以v8引擎就实现了延迟解析的方案,将不必要的函数进行预解析,也就是只解析暂时需要的内容,而对函数的全量解析是在函数被调用时才会进行
比如我们在一个函数outer内部定义了另外一个函数inner,那么inner函数就会进行预解析

下面看一下在线解析AST的示例

浏览器内核与JS引擎本篇就简单聊这么多,先浅浅的了解一下。关于V8的东西很多,也有很多非常绝妙的设计,更多V8相关的戳这里,一步步解锁吧!

我是 甜点cc☭
微信公众号:【看见另一种可能】
热爱前端开发,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚。本号主要致力于分享个人经验总结,希望可以给一小部分人一些微小帮助。
希望能和大家一起努力营造一个良好的学习氛围,为了个人和家庭、为了我国的互联网物联网技术、数字化转型、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我。
JavaScript代码是怎么在浏览器里面运行起来的?的更多相关文章
- [代码收藏]设为首页和加入收藏的JavaScript代码(兼容多浏览器)
其实不少非IE内核浏览器都仍不支持通过代码将网页设为主页和加入收藏的功能,因此说是兼容,其实只是一个try,catch后的提醒而已. 加入收藏: /* * author : 2010-12-27 11 ...
- Async/Await是这样简化JavaScript代码的
译者按: 在Async/Await替代Promise的6个理由中,我们比较了两种不同的异步编程方法:Async/Await和Promise,这篇博客将通过示例代码介绍Async/Await是如何简化J ...
- Selenium常用API的使用java语言之19-调用JavaScript代码
虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法.在这种情况下,就可以借助JavaScript来控制浏览器的滚动条.WebDriver提供了execu ...
- 浏览器地址栏运行JavaScript代码
这个很多人应该还是知道的,在浏览器地址栏可以直接运行JavaScript代码,做法是以javascript:开头后跟要执行的语句.比如: javascript:alert('hello from ad ...
- TraceGL监控Node.js应用或者浏览器JavaScript代码
https://github.com/traceglMPL/tracegl TraceGL能够监控Node.js应用或者浏览器JavaScript代码的运行过程和细节.可视化的用户界面也很友好
- VS2010Web默认的浏览器设置和VS里调试JavaScript代码的设置
前言 重装系统后,VS调用的Web浏览器不是IE了,VS调式不了JavaScript代码了.这两天一直在试终于搞定了.这里查找的问题当然主要是VS里面调式JavaScript代码了. 第一种方式设置V ...
- 使用C#解析并运行JavaScript代码
如果想在C#编程中解析并运行JavaScript代码,常见的方式有两种: 利用COM组件“Microsoft Script Control”,可参见:C#使用技巧之调用JS脚本方法一 利用JScrip ...
- 《浏览器工作原理与实践》<08>调用栈:为什么JavaScript代码会出现栈溢出?
在上篇文章中,我们讲到了,当一段代码被执行时,JavaScript 引擎先会对其进行编译,并创建执行上下文.但是并没有明确说明到底什么样的代码才算符合规范. 那么接下来我们就来明确下,哪些情况下代码才 ...
- 《浏览器工作原理与实践》<07>变量提升:JavaScript代码是按顺序执行的吗?
讲解完宏观视角下的浏览器后,从这篇文章开始,我们就进入下一个新的模块了,这里我会对 JavaScript 执行原理做深入介绍. 今天在该模块的第一篇文章,我们主要讲解执行上下文相关的内容.那为什么先讲 ...
- 检测浏览器版本类型的JavaScript代码,终极版
下面的JavaScript代码,不仅可以判断PC端浏览器类型,还可以判断安卓.iOS.其他智能手机.平板电脑或游戏系统. 说废话貌似不是我的风格哈,直接上代码吧: var client = funct ...
随机推荐
- 快速排序C语言版图文详解
算法原理:选一个数位基准,将序列分成两个部分,一边全是比它小序列,另一边全是比它大序列.然后再分别对比他小的序列和比再次进行基准分割.依次分割下去,得到一个有序的队列. 原理图示: 编辑 编辑 ...
- Containerd和Docker的关系
联系 容器运行时(Container Runtime)是Kubernetes(k8s)最重要的组件之一,负责管理镜像和容器的生命周期.Kubelet通过Container Runtime Interf ...
- ES小知识点
elasticsearch.yml配置文件 network.host: _site_ # network.host设置为"_site_",表明它绑定到我们的本地电脑的IP地址 di ...
- Docker网络详解——原理篇
安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络). none .host 网络模式 简介 Host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP ...
- 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用
刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...
- Python对字符数据进行清洗
import re mystr = "hahaAAA哈哈綂123./!#鱫愛" str1 = ''.join(re.findall('[\u4e00-\u9fa5]',mystr) ...
- 文件管理工具“三剑客” #Everything #SpaceSniffer #Clover
前言: 本文收集了我日常使用的三个文件管理工具: 文件搜索神器--Everything 磁盘文件占用分析工具--SpaceSniffer 文件资源管理器--Clover 下面我从工具解决的痛点和使用技 ...
- 洛谷P2860 [USACO06JAN]Redundant Paths G (tarjan,边双缩点)
本题的大意就是加最少的边使得图成为边双. 多举例子,画图分析可得:最终答案就是叶子节点(度数为1的点)的个数加1在除以2. 那么我们的目的就转化为找叶子节点: 首先通过tarjan找到割边,再dfs将 ...
- 洛谷P1120 小木棍 (搜索+剪枝)
搜索的经典题. 我们要求木根的最小长度,就要是木根的数量尽可能多,可以发现木根的长度一定可以整除所有小木棒的总长度,从小到大枚举这个可能的长度,第一次有解的就是答案. 关心的状态:当前正在拼哪根木棍, ...
- Filter 筛选器(一)之 ActionFilter-- IAsyncActionFilter 和 ActionFilterAttribute
微软官网例子:Filter筛选器 使用场景(执行顺序): IAsyncActionFilter 使用异步actionFilter 只需要实现 他的 :OnActionExecutionAsync 方法 ...