• 浏览器中的Javascript

  客户端javascript就是运行在浏览器中的javascript,现代的浏览器已经有了很好的发展,虽然它是一个应用程序,但完全可以把它看作是一个简易的操作系统,因为像windows、linux等操作系统提供的文档存储、网络调用、绘制图像等功能在浏览器中也同样都可以得到支持,所以就像操作系统中的应用程序叫做桌面应用一样,浏览器中可互动的web文档也叫做web应用。

  在web应用中,浏览器是javascript的运行环境,这个运行环境不仅包含了javascript解释器以使js程序可以正确的运行,还为解释器提供了其他服务的接口来扩展了javascript的功能,比如发起网络调用、DOM编程等。当一个页面开始加载的时候js解释器就会启动,启动后做的第一件事就是初始化一个全局对象,这个全局对象在不同运行环境中会有不同的标识符表示和内容,在nodeJS中这个全局对象叫global,而在浏览器中这个全局对象叫window。一个window对象就代表一个窗体,里面除了包含javascript语法内置的函数和对象外,还包括浏览器为其扩展的功能对象,这些功能对象就是前面说的服务接口,是浏览器提供的服务的对象化表示。

  • Javascript的执行

  解释器启动之后就可以执行javascript代码了,在浏览器中触发javascript代码运行的情况只有两种:

  • 文档加载的时候:浏览器在加载解析页面文档的过程中如果遇到了<script>标签引用或者包含的js代码,解释器就会执行一遍。
  • 事件触发的时候:这种情况是异步且由事件驱动的,解释器执行的代码是前一种情况下为事件注册的处理函数。

  其中第一种情况要尤其注意,当浏览器在下载执行js文件的时候,页面的解析和渲染是被阻塞的,也就是说页面的其他有关资源会停止下载(比如css文件、图片等),同时DOM树的构建也会暂停,因为js程序的执行是有可能影响到DOM树的结构的(比如说使用到了document.write方法),DOM树的解析一暂停,页面的UI渲染也会被迫暂停。这样就会产生性能问题,如果js文件过大或者js代码执行时间过长,浏览器等待响应的时间就越久。所以考虑到性能问题,浏览器中js脚本应该尽可能的是无阻塞的脚本。

  • 无阻塞脚本

  由阻塞脚本的阻塞过程可以知道,无阻塞的脚本可以从两个方面来考虑:不阻塞页面相关资源的下载和不阻塞页面UI的渲染。

    要是单单实现不阻塞其他资源的下载只有一种方法,就是在<script>标签中添加defer或者async,这种方法的效果是实现并行下载,也就是说当js文件在下载的时候不会阻塞其他资源的下载,它俩的区别是下载完后js代码执行的时机,defer会一直推迟到页面解析完,而async会在js文件下载完后立即执行,但js文件在执行过程中还是会阻塞页面解析和渲染的。由于浏览器对这种方法的支持不是很充分,所以这并不是一个兼容性很强的方法。

  其他的几种方法就是既不阻塞下载也不阻塞渲染了,首先是一种讨巧的方法,就是把<script>标签放到<body>底部,因为浏览器是一边解析渲染一边显示出来的,等解析到body标签最底部的时候页面也就完全在浏览器中显示出来了,这时候再下载和执行js文件基本上不存在阻塞这回事情了,但是要注意的是放到最后面的js文件尽量不要再对DOM进行操作,因为更改了DOM可能会产生回流或者重绘,回流和重绘也是非常耗性能的两个操作,影响用户的使用体验。还有一点是asp.net程序要注意的是在webform编程中,如果后台代码要用到前台的js函数,那么放在body标签底部的函数是注册不过去的,后台只能注册放在head标签中的函数。

  还有一种方法是创建动态脚本元素,这种方法可以说是做到了异步无阻塞,在js文件下载和执行的时候都不会阻塞页面的解析和渲染。该方法需要动态的创建script标签,并把标签添加到head元素中,比如

var script = document.createElement('script');
script.type='text/javascript';
script.src='xxxxx.js';
document.getElementsByTagName('head')[0].appendChild(script);

当代码执行到最后一句的时候js文件开始下载,下载完后立即执行,这整个过程不会阻塞页面解析和渲染。这是动态创建带有src属性的script标签的时候,还有另外一种动态创建内联脚本的方式,该方法通过Ajax请求获取到js脚本内容,再动态创建script标签把脚本内容注入到script标签当中。这种方法不是很常用因为有一个缺点就是获取的js内容只能是同域中的。

  一个性能良好的页面不只是要做到无阻塞脚本,还有很多其他方面要注意的。 其中一条就是不要让一段js代码执行太长时间,因为javascript语言中不存在任何线程机制,并且js引擎也是单线程模型的,所以js代码的执行都是同步的,长时间的占用执行线程会使其他的js代码无法得到执行。如果必须要计算一个密集的任务,那么可以把这个任务通过setTimeout或setInterval分离成多个异步子任务。这里的同步和异步看起来似乎有些矛盾,javascript怎么可能既是单线程同步的又是多线程异步的呢? 原因在于浏览器的机制。

  • Javascript单线程与事件的异步

  虽然javascript引擎是单线程的,但是浏览器是多线程的,在一个浏览器进程中一般有四个线程:javascript引擎线程、渲染引擎线程、浏览器事件线程(我也不知道叫什么)、http请求线程。在javascript引擎线程中有一个执行队列,里面的任务是同步的依次执行,而在浏览器事件线程中有一个任务队列,当某个事件触发时,该事件对应的回掉函数会放到这个任务队列中,这个任务队列是一个先进先出结构,当javascript引擎线程中的任务都执行完毕后,会从浏览器事件线程中的任务队列里读取任务放到javascript引擎线程中的执行队列里去执行,这个过程是不断循环的,这有个专业术语叫Event Loop。所以就算setTimeout(fun,0)这种看起来是立即执行的函数也并不一定会立即执行的,这个fun函数会先放到任务队列里面等待执行队列中的任务执行完毕才会被执行,所以fun函数的执行会延迟一段时间,这么样子的写法只是改变了fun函数的执行顺序。

  

前端--关于客户端javascript的更多相关文章

  1. 前端html、Javascript、CSS技术小结

    简单地总结了一下前端用过的html.javascript.css技术,算是清点一下,做个大略的小结,为进一步的学习给个纲领. 一.HTML 由于HTML5的兴起,简单地判断一个网页是否是html5网页 ...

  2. 前端基础之JavaScript day51

    前端基础之JavaScript   JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中) ...

  3. 前端html+css+JavaScript 需要掌握的单词

    前端html+css+JavaScript 需要掌握的单词   broswer 浏览器(客户端) html 超文本标记语言 css 层叠样式表 javascript 语言名字(类似python/php ...

  4. 前端第三篇---前端基础之JavaScript

    前端第三篇---前端基础之JavaScript 一.JavaScript概述 二.JavaScript的基础 三.词法分析 四.JavaScript的内置对象和方法 五.BOM对象 六.DOM对象 七 ...

  5. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  6. 【JavaScript权威指南(第五版)】笔记之第二部分 客户端JavaScript 第13章~第23章

    第十三章 Web浏览器中的javascript ①   eg:下面两行代码实际上执行的是相同的功能 var answer = 42; window.answer = 42;   ③每个window对象 ...

  7. JavaScript 客户端JavaScript之脚本化HTTP(通过XMLHttpRequest)

    XMLHttpRequest对象的设计目的是为了处理由普通文本或XML组成的响应:但是,一个响应也可能是另外一种类型,如果用户代理(UA)支持这种内容类型的话.   大多数浏览的客户端JavaScri ...

  8. JavaScript 客户端JavaScript之事件(DOM API 提供模块之一)

    具有交互性的JavaScript程序使用的是事件驱动的程序设计模型.   目前使用的有3种完全不同的不兼容的事件处理模型. 1.原始事件模型 (一种简单的事件处理模式) 一般把它看作0级DOM API ...

  9. JavaScript 客户端JavaScript之 Web浏览器的环境

    Web浏览器实现的Javascript,通过Web浏览器实现的JavaScript引入了大量可脚本化的对象(1.Web浏览器 2.HTML 3.HTML中的内容)  Web浏览器中的Javascrip ...

随机推荐

  1. Jmail组件发送邮件说明ASP.NET

    ASP.Net环境下使用Jmail组件发送邮件2008-01-25 18:59实现过程: 不同于在Asp中使用Jmail,直接使用 Server.CreateObject("Jmail.Me ...

  2. VS2010使用附加进程的方式调试IIS中的页面介绍

    1.       对要测试的页面设置断点,然后选择”调试”->”附加到进程”,在进程中选择w3wp.exe进程(需要先打开需测试的页面) 2.       配置完成,当打开你需要测试的页面的时候 ...

  3. String功能测试

    package foxe; import java.io.IOException;import java.util.StringTokenizer; public class MainClass { ...

  4. Windows命令行(DOS命令)教程-3(转载)http://arch.pconline.com.cn//pcedu/rookie/basic/10111/15325_2.html

    五.常用命令 DOS命令总共大约有一百个(包括文本编辑.查杀病毒.配置文件.批处理等),我们这里详细介绍二十个常用的DOS命令. 先介绍一下通配符的概念. 通配符*和? *表示一个字符串 ?只代表一个 ...

  5. JSONP有什么作用

    1.解决跨域访问数据                 由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名.协议.端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求 ...

  6. [Apache系列]怎样在windows下配置apache vhost

    找到你的Apache安装目录,下图为小编的Apache安装的目录 2 点击conf文件夹  进入配置目录,找到httpd.conf 文件, 3 打开httpd.conf 文件,如图, 找到地475行, ...

  7. Lua 字符串函数小结

    1.求字符串长度 string.len(str) 2.大小写转换 string.upper(str) string.lower(str) 3.字符串查找(非全局) --func_string.lua ...

  8. Silverlight js html 相互调用

    1.sl调用js 比如我们在页面中定义一个js函数: <script type="text/javascript">        function fnTest(ms ...

  9. Linux下用Mytop监控MySQL资源

    https://www.centos.bz/2011/11/linux-install-perl-dbd-mysql/ http://blog.csdn.net/rital/article/detai ...

  10. SendMessage参数

    http://download.csdn.net/download/wshjldaxiong/4830242