高性能的javascript之加载顺序与执行原理篇

加载顺序

JavaScript 的加载顺序在浏览器中是从上到下、从左到右的,也就是按照 HTML 文档中<script>标签的出现的顺序进行逐个加载和执行。此外,当遇到<script>标签中的deferasync属性时,也会影响 JavaScript 脚本的加载与执行顺序。

  • defer:表示该脚本在 HTML 文档中的其他元素加载完毕之后再进行加载,也就是等到整个页面被浏览器解析完毕之后才会执行。该属性只对外部脚本文件有效,内部脚本无效。多个带有defer属性的脚本按照在 HTML 文档中出现的顺序进行加载和执行。
  • async:表示该脚本是异步加载的,也就是在 HTML 文档解析过程中不会对其他元素的加载和解析进行阻塞。当该脚本加载完成之后,会立刻被执行,不保证按照在 HTML 文档中的顺序来执行。多个带有async属性的脚本也不保证按照在 HTML 文档中出现的顺序进行加载和执行。

在实际开发中,我们应该根据页面的实际情况,遵循以下原则来进行 JavaScript 脚本的加载:

  • 通常将脚本文件的<script>标签放在页面</body>标签前,可以避免阻塞页面的渲染,提高页面的加载速度;
  • 尽可能使脚本文件较小,减少加载时间;
  • 对于不影响页面渲染或交互的功能,可以采用异步加载的方式,提高页面响应速度和交互体验;
  • 对于同时需要执行的多个 JavaScript 脚本文件,可以将它们合并为一个较大的文件,减少 HTTP 请求次数,提高页面加载速度。

执行原理

JavaScript 代码的执行过程分为两个阶段:解析阶段和执行阶段。

  • 解析阶段:该阶段主要完成的工作是将代码转换成抽象语法树(AST),即将代码解析成可执行的指令序列。在解析阶段中,JavaScript 引擎负责对变量、函数声明等进行预处理,将其进行存储,以供之后的执行阶段调用。同时在解析阶段中,也会对脚本文件进行语法检查,确保代码的正确性。

  • 执行阶段:该阶段主要完成的工作是按照解析阶段生成的指令序列进行逐条执行,并生成最终的运行结果。在执行阶段中,JavaScript 引擎会从函数调用栈(call stack)中获取下一条指令并执行,同时还会通过作用域链(scope chain)等内部机制进行变量访问和函数调用等操作。

在实际开发中,我们需要优化 JavaScript 代码的执行效率,可以采用以下方式:

  • 减少全局变量的使用,避免变量名和函数名的重复,以提高变量和函数的查找速度;
  • 将多次使用的变量和函数进行缓存,避免重复计算和查找;
  • 避免在 JavaScript 循环中频繁地操作 DOM 元素,避免页面的重绘,以提高页面渲染效率;
  • 对于与用户交互相关的 JavaScript 代码,可以采用事件委托(event delegation)的方式来减少 DOM 操作次数,提高页面响应速度和交互体验。

示例一:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>defer示例</title>
  </head>
  <body>
    <script src="a.js" defer></script>
    <script src="b.js" defer></script>
  </body>
</html>

在上述代码中,分别引入了a.jsb.js文件,并设置了defer属性。由于在 HTML 文档中出现的顺序是a.jsb.js,因此这两个文件会按照这个顺序分别进行异步加载。当 HTML 文档加载完成之后,这两个文件的执行顺序是先执行a.js,再执行b.js

示例二:

// 定义一个全局变量
var COUNT = 0;

// 循环一亿次计算全局变量COUNT的值
for (var i = 0; i < 100000000; i++) {
  COUNT++;
}

console.log(COUNT);

上述代码中,定义了一个名为COUNT的全局变量,并使用循环计算COUNT的值。在循环中,每次对COUNT进行自增操作,会对全局作用域链进行访问和修改,因此会较慢。如果需要优化执行效率,可以采用将COUNT变量进行缓存的方式,减少对全局作用域链的访问次数。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:高性能的javascript之加载顺序与执行原理篇 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • FireFox JavaScript全局Event对象

    FireFox JavaScript全局Event对象 概述 在 FireFox JavaScript 中,Event 对象是一个全局的对象,它代表着一个事件,包含了事件的相关信息,如事件类型,目标元素等。我们可以使用 Event 对象来获取事件信息。 使用方法 获取事件类型 在事件处理函数中,我们可以使用 event.type 属性来获取事件的类型,例如:…

    JavaScript 2023年6月10日
    00
  • javascript实现用户点击数量统计

    针对“javascript实现用户点击数量统计”,给出详细的攻略如下: 1. 在HTML中使用JavaScript实现点击数统计 步骤1:在HTML中定义一个计数器 首先,在你的HTML文件中定义一个计数器,可以使用一个全局变量来存储它,例如: var count = 0; 这个计数器用来记录用户点击了多少次按钮。 步骤2:在HTML中添加一个按钮 然后,在…

    JavaScript 2023年6月11日
    00
  • 关于element ui中el-cascader的使用方式

    下面就是对于关于Element UI中el-cascader的使用方式的详细讲解攻略: 1. 概述 el-cascader是一种级联选择器,它可以让用户选择特定的数据。el-cascader支持输入、筛选和异步加载选项,它可以很方便的呈现层级关系。本文将从以下几个方面详细讲解el-cascader的使用方式: el-cascader的安装 el-cascad…

    JavaScript 2023年6月10日
    00
  • vue+vant使用图片预览功能ImagePreview的问题解决

    下面是关于“vue+vant使用图片预览功能ImagePreview的问题解决”的完整攻略: 前言 图片预览是一项非常常见的功能,在网页设计与开发中经常会用到。在Vue项目中,由于拥有大量高性能的组件库,开发图片预览功能变得异常简单,其中Vant就是一个非常优秀的Vue组件库之一。 在使用Vant时,我们可以很简单地使用其中提供的ImagePreview组件…

    JavaScript 2023年6月11日
    00
  • JavaScript异常处理

    JavaScript异常处理可以帮助开发人员减少代码中的错误,提高代码的健壮性和稳定性。在 JavaScript 中,异常是由错误或异常条件引起的程序流控制中的偏差,也就是程序出了问题。 JavaScript异常处理通常使用 try-catch 语句块实现。try 语句块包含可能引发异常的代码,而 catch 语句块用于捕捉异常并处理它们。以下是一个基本的 …

    Web开发基础 2023年3月30日
    00
  • Jquery Ajax学习实例 向页面发出请求,返回XML格式数据

    让我们来详细讲解一下JQuery Ajax学习实例,这里我会给出两个示例说明,为了方便描述,我会分成步骤来讲解。 基本概念 在开始之前,我们需要先理解一些基本概念。 AJAX AJAX 是一种与服务器交换数据并更新部分网页而不重载整个页面的技术。AJAX 不是新技术,它是使用了已有的技术,是一种将客户端脚本和服务器端脚本进行异步通信的技术。 JSON JSO…

    JavaScript 2023年6月11日
    00
  • JavaScript对内存分配及管理机制详细解析

    JavaScript对内存分配及管理机制详细解析 1. JavaScript中的内存分配 JavaScript是一种解释型语言,它的内存分配是发生在运行时的。在JavaScript中,内存分配主要发生在两个地方:堆内存和栈内存。 1.1 堆内存 堆内存是指在程序运行时动态分配的内存空间。JavaScript中的对象、数组以及函数都是在堆内存中分配的。这些数据…

    JavaScript 2023年6月10日
    00
  • js获取当前页面路径示例讲解

    下面是“js获取当前页面路径示例讲解”的完整攻略。 什么是页面路径? Web页面的路径是指从Web服务器到Web文档的绝对或相对路径。绝对路径是从根目录开始的完整路径,如:http://www.example.com/index.html;而相对路径则是相对于当前文件所在的路径,如:./index.html。 如何在JS中获取当前页面路径? 获取当前页面路径…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部