JavaScript加载与执行

多数情况下,浏览器是用单一进程处理用户界面和JavaScript脚本执行。所以,JavaScript的处理时间越久,浏览器等待响应事件就越长。

简单地说,就是浏览器每次处理<script>标签,就会让页面等待脚本的解析和执行。这个过程页面渲染和用户交互是完全阻塞的。

一、脚本位置

H4规范指出,<script>标签可以放在<head>和<body>标签内,并允许出现多次。

1.1 将脚本放在底部

正常情况下,多个脚本放到<head>内,浏览器会一个一个脚本加载与执行,如果这个过程耗时过长,通常就会显示空白页面。

IE8,Firefox3.5、Safari4和Chrome2都允许并行下载JavaScript脚本。所以,当加载一个<script>标签时,不会阻塞其他<script>标签,但是会阻塞其他资源的下载,比如图片等。

二、组织脚本

由于<script>标签初始下载都会阻塞页面渲染,所以减少<script>标签的数量会改善阻塞情况。这不仅仅包含外链脚本,也包含内嵌脚本。

2.1 单个100k的文件将比4个25k的文件加载快

考虑到HTTP请求会带来额外的性能开销,单个100k的文件将比4个25k的文件加载快。当依赖多个脚本文件时,尽量合并,用一个<script>标签引入。

2.2 页面引入的脚本尽量是本网站的,而不是其他网站的。

同样考虑HTTP请求的开销,请求本网站的脚本文件会比请求其他网站的脚本文件更快。

三、无阻塞的脚本

减小JavaScript文件大小和控制HTTP请求数

JavaScript倾向于阻塞浏览器的某些处理过程,比如HTTP请求和页面的更新,这是最显著的影响性能的问题。因此,精简代码数量和HTTP请求数很必要。

加载单个较大脚本文件会锁死浏览器一大段时间

尽管下载单个较大脚本文件只产生一次HTTP请求,但是会锁死浏览器一大段时间。因此需要逐步加载JavaScript文件,这样做在某种程度上来说不会阻塞浏览器。

总结的说:就是页面加载完后再加载JavaScript代码。

3.1 延迟的脚本

3.1.1 defer属性

H4给<script>标签定义了一个扩展属性:defer。

带有defer属性的<script>标签可以放到任意一个位置,因为,当解析到带defer的<script>标签时,只会下载脚本,而不会执行脚本,直到DOM加载完成。因为defer不会阻塞浏览器的其他进程,可以和其他资源并行下载。

局限性:只有IE 4+ 和Firefox 3.5+的浏览器支持。

3.2 动态脚本元素

3.2.1 DOM创建<script>标签

<script>标签和其他标签并无差异,可以DOM方法创建、移动、删除<script>元素。

新创建的<script>标签如果下载JavaScript文件,无论何时下载都不会阻塞页面其他进程,放到<head>里都不会影响其他进程。

通常,新创建的<script>标签放到<head>里比放到<body>里面更保险。因为<body>没完全加载完成时,IE浏览器可能抛出‘操作已中止’的异常。

3.2.3 readystatechange事件

IE支持另外一种实现方式,它会触发readystatechange事件。

<script>元素提供一个readyState属性,它的值在外链文件下载过程的不同阶段会发生变化。

该属性有五种取值:

初始状态:uninitialized  开始下载:loading  下载完成:loaded  数据完成下载但不能用:interactive  所以数据已准备就绪:complate

var script = document.createElement("script");
script.type = "text/javascript";

// IE
script.onreadystatechange = function () {
    if (script.readyState == "loaded" || script.readyState == "complate") {
        script.onreadystatechange = null;
        alert("Script loaded.");
    }
}

script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);

上述代码这么做是因为在<script>的生命周期内,并非readyState的每个值都会被用到,这些值也不一定会被用到。最有用的两个值是loaded和complate。

最靠谱的就是检测这两个状态,以确保事件不会处理两次。

3.3 XMLHttpRequest脚本注入

先创建XHR对象,再用它下载JavaScript文件,最后通过创建动态<script>元素将代码注入到页面中:

var xhr = new XMLHttpRequest();
xhr.open("get", "file1.js", true);
xhr.onreadystatechange = function(){
    if (xhr.readyState == 4) {
        if (xhr.state >= 200 && xhr.state < 300 || xhr.state == 304){
            var script = document.screateElement("script");
            script.style = "text/javascript";
            script.text = xhr.responseText;
            document.body.appendChild(scripy);
        }
    }
};
xhr.send(null);

这种方法的好处就是下载下来的脚本文件不会立即执行,另一优点就是它在所有主流浏览器中都可以正常工作。

缺点是请求的脚本文件与页面要在同一个域内。因此大型的web应用不会用这种方法。

3.4 推荐的无阻塞模式

3.4.1 先加载页面初始化所必要的脚本代码,等页面初始化完成,再加载剩下的脚本代码。

<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
    loadScript("the-rest.js", function(){
        Application.init();
    });
</script>

这样确保js执行过程不会阻塞页面其他内容的显示。第二个<script>执行时,DOM结构已经创建完毕,并做好了交互的准备。从而避免了需要另一个事件(比如windows.load)来检测页面是否准备好。

3.4.2 将loadScript()函数直接嵌入到页面,避免多产生一次HTTP请求。

原文地址:https://www.cnblogs.com/aaronthon/p/12218816.html

时间: 2024-10-11 18:14:18

JavaScript加载与执行的相关文章

怎么样加快JavaScript加载和执行效率

概览 无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成.JavaScript 执行过程耗时越久,浏览器等待响应用户输入的时间就越长.浏览器在下载和执行脚本时出现阻塞的原因在于,脚本可能会改变页面或 JavaScript 的命名空间,它们对后面页面内容造成影响.一个典型的例子就是在页面中使用document.write(). JavaScript 代码内嵌示例 <html> <head> <title>Source

加快JavaScript加载和执行效率

JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 JavaScript 的阻塞特性变的复杂,也就是说当浏览器在执行 JavaScript 代码时,不能同时做其他任何事情.本文详细介绍了如何正确的加载和执行 JavaScript 代码,从而提高其在浏览器中的性能. 概览 无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成.JavaScript 执行过程耗时越久,浏览器等待响应用户输入的时间就越长.浏览器

高性能JavaScript 加载和执行

前言 本章主要讲述如何加载脚本使得用户能有良好的用户体验,而核心内容就是JavaScript的异步加载.之前写过一篇不得不说的JavaScript异步加载,相似的内容就不多加描述,讲些不同的东西,主要讲下JavaScript文件加载器labjs的常用方法. 流水账 脚本位置:推荐将所有的<script>标签尽可能放到<body>标签的底部,也就是</body>之前,这样就能在执行js代码之前将用户界面呈现出来,改善用户体验. 组织脚本:由于每个<script>

JavaScript 的性能优化:加载和执行

随着 Web2.0 技术的不断推广,越来越多的应用使用 JavaScript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 JavaScript 的阻塞特性变的复杂,也就是说当浏览器在执行 JavaScript 代码时,不能同时做其他任何事情.本文详细介绍了如何正确的加载和执行 JavaScript 代码,从而提高其在浏览器中的性能. 概览 无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染都必

浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入

在<浏览器环境下JavaScript脚本加载与执行探析之defer与async特性>中,我们研究了延迟脚本(defer)和异步脚本(async)的执行时机.浏览器支持情况.浏览器bug以及其他的细节问题.而除了defer和async特性,动态脚本和Ajax脚本注入也是两种常用的创建无阻塞脚本的方法.总的来看,这两种方法都能达到脚本加载不影响页面解析和渲染的作用,但是在不同的浏览器中,这两种技术所创建的脚本的执行时机还是有一定差异,今天我们再来探讨一下通过动态脚本技术和Ajax注入的脚本在这些方

JavaScript的性能优化:加载和执行

随着 Web2.0 技术的不断推广,越来越多的应用使用 javascript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 JavaScript 的阻塞特性变的复杂,也就是说当浏览器在执行 JavaScript 代码时,不能同时做其他任何事情.本文详细介绍了如何正确的加载和执行 JavaScript 代码,从而提高其在浏览器中的性能. 1.概述 无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染

JavaScript之jQuery-4 jQuery事件(页面加载后执行、事件处理、事件冒泡、事件对象、模拟操作)

一.jQuery 页面加载后执行 代码执行的时机选择 - $(document).ready()方法和 window.onload事件具有相似的功能,但是在执行时机方面是有区别的 - window.onload 事件是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行 - $(document).ready()方法注册的事件处理程序,在DOM完全加载后就可以调用 - 一般来讲, $(document).ready()的执行要优于window.onload事件 - 需要注意的是,

[转]JavaScript 的性能优化:加载和执行

原文链接:http://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/index.html?ca=drs- JavaScript 的性能优化:加载和执行 蔡 愉晟, 软件工程师, IBM 简介: 随着 Web2.0 技术的不断推广,越来越多的应用使用 JavaScript 技术在客户端进行处理,从而使 JavaScript 在浏览器中的性能成为开发者所面临的最重要的可用性问题.而这个问题又因 JavaScript 的阻塞特性变的复杂,也就

浏览器中Javascript的加载和执行

在刚学习Javascript时曾对该问题在小组内做个一次StudyReport,发现其中的基础还是值得分析的. 从标题分析,可以加个Javascript的加载和执行分为两个阶段:加载.执行.而加载即浏览器下载JS脚本的过程,执行时浏览器JS引擎解释执行的过程. 接下来先分析JS脚本加载的过程,加载方式可分为同步加载和异步加载. 同步加载即浏览器加载JS过程中停止对HTML元素的解析,保证JS执行的安全一致性,但如果JS中包含大量计算时,会导致阻塞页面的渲染.常见的JS加载是通过<script>