在讲这个问题之前,先来补充几个知识点,如果对此已经比较了解可以直接跳过
1. 大多数浏览器的组件构成如图
在最底层的三个组件分别是网络,UI后端和js解释器。作用如下:
(1)网络- 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作
(2)UI 后端- 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口
(3)JS解释器- 用来解释执行JS代码
ps:上图和知识点主要来自《HOW BROWSERS WORK: BEHIND THE SCENES OF MODERN WEB BROWSERS》 想深入了解的同学可以重点看下。
2. 大多数浏览器(比如chrome)让一个单线程共用于执行javascrip和更新用户界面。这个线程通常被称为“浏览器UI线程”, 每个时刻只能执行其中一种操作,这意味着当Javascript代码正在执行时用户界面无法响应输入,反之亦然。这样做是因为javascript代码的作用就是操作DOM更新用户界面,用同一个线程来做负责这两件事情可以更高效
3. 浏览器UI线程的工作基于一个简单的队列系统,任务会被保存到队列中直到进程空闲。一旦空闲,队列中的下一个任务就被重新提取出来并运行。这些任务要么是运行javascript代码,要么执行UI更新,包括重绘和重排。
4. 重点再强调下,javascript是单线程运行,千万别被setTimeout()和setInterVal()这种函数迷惑而误以为它是多线程。
ok,基础点讲解完毕,让我们进入正题,来讲解在浏览器中javascript的执行过程。
一、原理
一般而言,<script>标签每次出现都会霸道地让页面等待脚本的解析和执行,无论当前的Javascript是内嵌的还是包含了外链文件,页面的下载和渲染都必须停下来等待脚本执行完成。这在页面的生存周期中是必要的,因为脚本执行过程中可能修改页面内容,一个典型的例子就是在页面中使用document.write()。
当javascript代码是内嵌在html里面时,这点还是比较容易理解,但当javascript是外链文件时稍微有点负载,因为存在一个加载过程,而且浏览器加载好这个js文件之后往往还对其缓存。
首先,我们用以下这个例子来说明下缓存问题
<html>
<head>
<script type='text/javascript' src='js/f2.js'></script>
</head>
<body>
</body>
</html>
第一次打开页面时:
第二次打开页面时:
从上例中可以明显看出,像chrome之类的高版本浏览器会对js文件进行缓存,作用是不言而喻,减少网络请求。
其次,第二个问题,当一个javascript文件被加载时是否会阻塞其他javascript文件或者其他文件的加载。《高性能Javascript》一书中对这个问题做了较好的解答:各种浏览器的低版本的处理是当一个javascript文件在加载时,会同时阻塞页面其他文件的加载(包括其他javascript文件),但IE8,Firfox3.5,Safari 4和Chrome 2都允许并行下载javascript文件,但遗憾的是,javascript下载过程仍然会组舍其他资源的下载,比如图片。尽管javascript脚本的下载过程不会相互影响,但页面仍然必须等待所有的javascript代码下载并执行完成才能继续。
这里说句题外话:浏览器对同一域名下的并发链接数也是有限制的,其他一些参数如下:
二、技巧
1. 脚本位置
由于脚本会阻塞页面其他资源的下载,因此推荐将所有的<script>标签放到<body>标签的底部,已尽量减少对整个页面下载的影响。
2. 将能合并的js文件合并
3. 无阻塞脚本
现在比较常用的方法就是动态加载执行脚本。你的原理是通过DOM,你几乎可以用Javascript动态创建HTML中的所有内容,其根本在于,<script>标签与页面中其他元素并无差异:都能通过DOM引用,都能在文档中移动,删除和创建。文件在改该<script>元素被添加到页面时开始现在,它不会阻止其他文件下载,只在执行阶段阻塞渲染。特别强调:《高性能javascript》一文中说“这种技术的重点在于:无论何时启动下载,文件的下载和执行都不会阻塞页面其他进程”,这并不是说它在执行不会阻塞其他javascript代码,而是要强调不会阻塞其他资源的下载等其他任务。
具体的代码如下:
function loadScript(url){
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = url;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
}
4. 神奇的setTimeout()
这里我不过多的将setTimeout()的原理,有兴趣的读者可以具体去看《高性能javascript》的第六章。我重点强调下,setTimeout的第二个参数并不是一个精确的时间,二是必须在javascript线程空闲时才能运行。利用这个特性,如下代码简单可以实现等待其他js代码执行完毕后再执行function里面的代码。
setTimeout(function(){
// do some before other javascripe codes had processed
}, 25)
但在function里面不要使用document.write()方法,因为执行setTimeout里面函数时往往已经到了页面onload之后,此时再执行 document.write 将导致当前页面的内容被清空,因为它会自动触发 document.open 方法。
参考文章:
《高性能Javascript》
HOW BROWSERS WORK: BEHIND THE SCENES OF MODERN WEB BROWSERS
Google Chrome源码剖析【一】:多线程模型
javascript异步加载详解
分享到:
相关推荐
本软件还可以通过对javascript的变量名称和过程名称进行编码,从而起到混淆ja代码的作用,保护您的劳动成功。 JS代码压缩,基本原理为: 1. 压缩多余的空格和换行符 2. 删除注释,因为注释只对程序员有用而对于浏览...
浏览器是我们日常上网的主要工具,它的工作原理复杂而精妙,涉及到网络通信、解析渲染、JavaScript执行等多个环节。这篇博文将深入探讨新式网络浏览器的工作原理,揭示其幕后的技术细节。 首先,我们要理解浏览器的...
本软件还可以通过对javascript的变量名称和过程名称进行编码,从而起到混淆ja代码的作用,保护您的劳动成功。 JS代码压缩,基本原理为: 1. 压缩多余的空格和换行符 2. 删除注释,因为注释只对程序员有用而对于浏览...
在JavaScript的世界里,主文件是程序运行的起点,它负责组织和协调整个项目的执行流程。 深入到JavaScript的知识点,我们需要了解以下关键点: 1. **变量声明**:JavaScript支持var、let和const三种变量声明方式,...
3. 动态代码修改:在开发过程中,可以使用`redefine`命令快速测试代码变更效果,而无需重启应用。 总结,Arthas作为强大的Java诊断工具,其丰富的命令集和高级特性为开发者提供了便捷的问题定位和优化手段,提高了...
在动态进度条的场景下,JavaScript会监听某些事件(比如点击按钮启动任务),根据任务的执行情况更新进度条的状态。例如,可以设置定时器模拟任务的进度,然后使用jQuery选择器找到对应的layui-progress元素并调整其...
这篇博客文章“各种微博分享按钮代码(转载)”主要介绍了如何在网站上集成这些分享功能,以便用户一键将网页内容分享到他们的微博账户。 在网页开发中,微博分享按钮的实现通常涉及HTML、CSS以及JavaScript技术。...
在JavaScript中,对对象进行类型判断是编程过程中常见的需求,特别是在处理动态数据或者需要执行不同操作根据对象类型时。本文将深入探讨如何在JavaScript中判断一个对象是否属于特定的类或构造函数。 首先,...
2. **WebView漏洞**:WebView组件如果没有正确配置,攻击者可能通过JavaScript调用未注册的Java类,执行任意代码。预防措施包括限制JavaScript接口的使用,验证所有传入参数,并尽可能避免使用JS到Java的桥梁。 3. ...
虽然JSP默认使用Java作为脚本语言,但它也支持其他语言,就像ASP支持javascript和VBScript一样。 **JSP的优势和特性** 1. **易用性与灵活性**:JSP提供了丰富的服务器端标签库,使得即使是对Java不太熟悉的开发者...
本篇文章将深入探讨一种实现"复制文章自动加上版权的功能"的方法,通过编程代码来阐述这一过程。 首先,我们需要明确这个功能的工作原理。当用户尝试复制网页上的文本时,系统会在复制的内容中自动嵌入版权信息。这...
2. **A2019工具介绍**:A2019是一款RPA工具,它的功能可能包括录制、编辑、调试自动化流程,并且支持多种脚本语言,如JavaScript和Java,以实现定制化的需求。 3. **Java脚本基础**:学习Java的基础语法,包括数据...
标题中的“sb3转exe”指的是将一个名为sb3的文件转换为可执行的exe文件。在编程和软件开发领域,sb3通常是Scratch 3.0项目文件的扩展名,这是一种基于图形化编程的教育工具,适用于初学者学习编程。而将sb3文件转换...
获取页面标题是通过JavaScript执行的,这展示了如何使用`JavascriptExecutor`执行JavaScript代码并返回结果。在本例中,我们获取了当前页面的标题并打印出来。 接下来,我们点击"创建相册"链接,然后输入新相册的...
JavaScript AutoScroller是一个JavaScript类,用于在浏览器窗口中自动滚动元素,帮助开发者在Web页面上实现自动滚动效果。通过定义AutoScroll类,我们可以方便地将页面元素按设定的规则进行滚动。 AutoScroller类的...
"工具"标签可能意味着博客中提到的解决方法可能涉及到使用其他辅助工具,如调试器(如Chrome DevTools)来跟踪代码执行,或者使用版本控制工具(如Git)来管理代码的修改。 压缩包中的"menu.js"文件很可能就是含有...
本软件还可以通过对javascript的变量名称和过程名称进行编码,从而起到混淆ja代码的作用,保护您的劳动成功。 JS代码压缩,基本原理为: 1. 压缩多余的空格和换行符 2. 删除注释,因为注释只对程序员有用而对于浏览...
本软件还可以通过对javascript的变量名称和过程名称进行编码,从而起到混淆js代码的作用,保护您的劳动成果。 JS代码压缩,基本原理为: 1. 压缩多余的空格和换行符 2. 删除注释,因为注释只对程序员有用而对于浏览...
需要注意的是,虽然这些工具极大地简化了文件上传流程,但设计师们仍需对网络安全有所了解,确保在使用过程中不会泄露敏感信息,且应遵循正确的版权和引用规则,如描述中提到的“转载请注明出处”。在本例中,...
为了实现这一点,开发者可能采用了跨平台的编程语言,如Java或JavaScript,并可能利用了Web技术,使得软件能够在不同的操作系统上运行。 在运行方面,程序说明提到“本程序放在任意目录下,都可以运行”。这表明该...