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

浏览器渲染过程

  1. HTML首先会被浏览器内核中的HTML Parser解析,最终会构建成一颗DOM树

  2. 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最重要的两部分:

  1. WebCore: 负责HTML、CSS的解析、布局、渲染等相关工作;
  2. 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的简易流程

  1. 浏览器内核将源码以流的方式交给v8引擎,v8引擎获取到源码并进行编码转换

  2. 词法分析Scanner,将代码转成tokens

  3. 语法分析Parser、Preparser,直接将tokens转换成AST树结构

  4. 字节码生成

  1. parser就是直接将tokens转换成AST树结构

  2. preParse称之为预解析,为什么需要预解析呢?

  • 这是因为并不是所有的js代码一开始就会被执行,如果对所有的js代码都进行解析,会影响网页运行效率。所以v8引擎就实现了延迟解析的方案,将不必要的函数进行预解析,也就是只解析暂时需要的内容,而对函数的全量解析是在函数被调用时才会进行

  • 比如我们在一个函数outer内部定义了另外一个函数inner,那么inner函数就会进行预解析

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

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

我是 甜点cc

微信公众号:【看见另一种可能】

热爱前端开发,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚。本号主要致力于分享个人经验总结,希望可以给一小部分人一些微小帮助。

希望能和大家一起努力营造一个良好的学习氛围,为了个人和家庭、为了我国的互联网物联网技术、数字化转型、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我。

JavaScript代码是怎么在浏览器里面运行起来的?的更多相关文章

  1. [代码收藏]设为首页和加入收藏的JavaScript代码(兼容多浏览器)

    其实不少非IE内核浏览器都仍不支持通过代码将网页设为主页和加入收藏的功能,因此说是兼容,其实只是一个try,catch后的提醒而已. 加入收藏: /* * author : 2010-12-27 11 ...

  2. Async/Await是这样简化JavaScript代码的

    译者按: 在Async/Await替代Promise的6个理由中,我们比较了两种不同的异步编程方法:Async/Await和Promise,这篇博客将通过示例代码介绍Async/Await是如何简化J ...

  3. Selenium常用API的使用java语言之19-调用JavaScript代码

    虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法.在这种情况下,就可以借助JavaScript来控制浏览器的滚动条.WebDriver提供了execu ...

  4. 浏览器地址栏运行JavaScript代码

    这个很多人应该还是知道的,在浏览器地址栏可以直接运行JavaScript代码,做法是以javascript:开头后跟要执行的语句.比如: javascript:alert('hello from ad ...

  5. TraceGL监控Node.js应用或者浏览器JavaScript代码

    https://github.com/traceglMPL/tracegl TraceGL能够监控Node.js应用或者浏览器JavaScript代码的运行过程和细节.可视化的用户界面也很友好

  6. VS2010Web默认的浏览器设置和VS里调试JavaScript代码的设置

    前言 重装系统后,VS调用的Web浏览器不是IE了,VS调式不了JavaScript代码了.这两天一直在试终于搞定了.这里查找的问题当然主要是VS里面调式JavaScript代码了. 第一种方式设置V ...

  7. 使用C#解析并运行JavaScript代码

    如果想在C#编程中解析并运行JavaScript代码,常见的方式有两种: 利用COM组件“Microsoft Script Control”,可参见:C#使用技巧之调用JS脚本方法一 利用JScrip ...

  8. 《浏览器工作原理与实践》<08>调用栈:为什么JavaScript代码会出现栈溢出?

    在上篇文章中,我们讲到了,当一段代码被执行时,JavaScript 引擎先会对其进行编译,并创建执行上下文.但是并没有明确说明到底什么样的代码才算符合规范. 那么接下来我们就来明确下,哪些情况下代码才 ...

  9. 《浏览器工作原理与实践》<07>变量提升:JavaScript代码是按顺序执行的吗?

    讲解完宏观视角下的浏览器后,从这篇文章开始,我们就进入下一个新的模块了,这里我会对 JavaScript 执行原理做深入介绍. 今天在该模块的第一篇文章,我们主要讲解执行上下文相关的内容.那为什么先讲 ...

  10. 检测浏览器版本类型的JavaScript代码,终极版

    下面的JavaScript代码,不仅可以判断PC端浏览器类型,还可以判断安卓.iOS.其他智能手机.平板电脑或游戏系统. 说废话貌似不是我的风格哈,直接上代码吧: var client = funct ...

随机推荐

  1. Java常用类的使用

    Java常用类 1. Optional 在我们的开发中,NullPointerException可谓是随时随处可见,为了避免空指针异常,我们常常需要进行 一 些防御式的检查,所以在代码中常常可见if( ...

  2. Java 多线程:锁(一)

    Java 多线程:锁(一) 作者:Grey 原文地址: 博客园:Java 多线程:锁(一) CSDN:Java 多线程:锁(一) CAS 比较与交换的意思 举个例子,内存有个值是 3,如果用 Java ...

  3. 使用Pipeline抽象业务生命周期流程

    上篇关于流程引擎的文章还是快两年以前的<微服务业务生命周期流程管控引擎>,这中间各种低代码平台层出不穷,虽然有些仅仅是OA+表单的再度包装,但有些的确是在逻辑和操作单元层面进行了真正的高度 ...

  4. 使用C#编写一个.NET分析器(一)

    译者注 这是在Datadog公司任职的Kevin Gosse大佬使用C#编写.NET分析器的系列文章之一,在国内只有很少很少的人了解和研究.NET分析器,它常被用于APM(应用性能诊断).IDE.诊断 ...

  5. 5.使用nexus3配置npm私有仓库

    当我们运行前端项目的时候,常常在解决依赖的时候会加上一个参数npm install --registry=https://registry.npm.taobao.org将源指定为淘宝的源,以期让速度加 ...

  6. Node.js躬行记(23)——Worker threads

    Node.js 官方提供了 Cluster 和 Child process 创建子进程,通过 Worker threads 模块创建子线程.但前者无法共享内存,通信必须使用 JSON 格式,有一定的局 ...

  7. electron 基础

    electron 基础 前文我们快速的用了一下 electron.本篇将进一步介绍其基础知识点,例如:生命周期.主进程和渲染进程通信.contextBridge.预加载(禁用node集成).优雅的显示 ...

  8. 通过js实现随机生成图片

    这次给大家分享一个通过js向HTML添加便签,实现随机代码生成的案例,代码已经放在下方,这里我在下面准备了50张图片,但是没有放在博文中,如果读者想要练习,可以自己下载一些图片,建议下载的多一些. & ...

  9. aardio + PHP 可视化快速开发独立 EXE 桌面程序

    aardio 支持与很多编程语言混合开发.网络上大家分享的 aardio + Python 混合开发的文章很多,aardio + PHP 的文章却很少. 其实 aardio 与 PHP 混合开发是真的 ...

  10. 微信小程序中视频的显示与隐藏

    在微信小程序中实现视频的播放与暂停 需求: 视频列表中只能有一个视频在播放 点击视频实现播放与暂停功能 加载完成显示图片,点击后变为视频播放 从上次播放的位置进行播放 思路: 定义一个标记变量,控制视 ...