Home  >  Article  >  Web Front-end  >  Javascript loading and execution

Javascript loading and execution

伊谢尔伦
伊谢尔伦Original
2016-11-22 13:12:061002browse

First of all, I want to talk about the loading and execution of Javascript. Generally speaking, browsers have two major characteristics for running Javascript: 1) it is executed immediately after loading, 2) when executed, it will block the subsequent content of the page (including the rendering of the page and the downloading of other resources). Therefore, if multiple js files are introduced, then for the browser, these js files are loaded serially and executed in sequence.

Because javascript may operate the DOM tree of the HTML document, browsers generally do not download js files in parallel like css files, because this is caused by the particularity of js files. Therefore, if your javascript wants to operate the subsequent DOM elements, basically the browser will report an error saying that the object cannot be found. Because when Javascript is executed, the subsequent HTML is blocked, and there is no subsequent DOM node in the DOM tree. So the program reported an error.

Traditional way

So, when you write the following code in the code:

<scripttype="text/javascript"  src="http://coolshell.cn/asyncjs/alert.js"></script>

Basically speaking, the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag in the head will block the loading of subsequent resources and the generation of the entire page. I made a special example for you to take a look at: Example 1. Note: There is only one sentence in my alert.js: alert("hello world"), which makes it easier for you to see how javascript blocks the following things.

So, you know why many websites put javascript at the end of the web page, or use events such as window.onload or docmuemt ready.

In addition, because most Javascript codes do not need to wait for the page, we have asynchronous loading function. So how do we load asynchronously?

document.write method

So, you may think that document.write() can solve the problem without blocking. Of course you would think that after document.write the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag, you can execute the following things, which is correct. This is true for Javascript code in the same script tag, but for the entire page, this will still block. The following is a piece of test code:

<scripttype="text/javascript"language="javascript">
    function loadjs(script_filename) {
        document.write(&#39;<&#39; + &#39;script language="javascript" type="text/javascript"&#39;);
        document.write(&#39; src="&#39; + script_filename + &#39;">&#39;);
        document.write(&#39;<&#39;+&#39;/script&#39;+&#39;>&#39;);
        alert("loadjs() exit...");
    }
    var script = &#39;http://coolshell.cn/asyncjs/alert.js&#39;;
    loadjs(script);
    alert("loadjs() finished!");
</script>
<scripttype="text/javascript"language="javascript">
   alert("another block");
</script>

What do you think is the order of alerts? You can try it in different browsers. Here is the test page you want to close: Example 2.

script's defer and async attributes

IE has supported the defer tag since IE6, such as:

<scriptdefertype="text/javascript"src="./alert.js">
</script>

For IE, this tag will cause IE to download the js file in parallel and hold its execution until the entire DOM is loaded. (DOMContentLoaded), multiple defer 3f1c4e4b6b16bbbd69b2ee476dc4f83a will also be run in the order in which they appear when executed. The most important thing is that after 3f1c4e4b6b16bbbd69b2ee476dc4f83a is added to defer, it will not block subsequent DOM rendering. But because this defer is only for IE, it is generally used less.

Our standard HTML5 also adds an attribute for asynchronous loading of javascript: async. No matter what value you assign to it, as long as it appears, it will start loading js files asynchronously. However, asynchronous loading of async has a serious problem, that is, it faithfully implements the military rule of "execute immediately after loading". Therefore, although it does not block the rendering of the page, you cannot control it. The order and timing of his execution. You can take a look at this example to get a feel for it.

The browsers that support async tags are: Firefox3.6+, Chrome 8.0+, Safari 5.0+, IE 10+, Opera does not support it yet (from here), so this method is not very good. Because not all browsers can do it.

Dynamic creation of DOM method

This method is probably the most used.

functionloadjs(script_filename) {
    varscript = document.createElement(&#39;script&#39;);
    script.setAttribute(&#39;type&#39;,&#39;text/javascript&#39;);
    script.setAttribute(&#39;src&#39;, script_filename);
    script.setAttribute(&#39;id&#39;,&#39;coolshell_script_id&#39;);
    script_id = document.getElementById(&#39;coolshell_script_id&#39;);
    if(script_id){
        document.getElementsByTagName(&#39;head&#39;)[0].removeChild(script_id);
    }
    document.getElementsByTagName(&#39;head&#39;)[0].appendChild(script);
}
varscript =&#39;http://coolshell.cn/asyncjs/alert.js&#39;;
loadjs(script);

This method has almost become the standard way to load js files asynchronously. For a demonstration of this method, please see: Example 3. This method has also been exploited by JSONP, that is, I can specify a background script (such as PHP) for the src of the script, and this PHP returns a javascript function whose parameter is a json string, and returns Call our predefined javascript function. You can take a look at this example: t.js (This example is a small example of asynchronous ajax calling that I collected on Weibo before)

Asynchronous loading of js on demand

The above DOM method example solves the problem of asynchronous loading The problem of inserting Javascript, but it does not solve the problem that we want it to run according to the timing we specify. Therefore, we only need to tie the above DOM method to a certain event.

For example:

Binded to the window.load event - Example 4

You must compare the execution differences between Example 4 and Example 3. I specifically used a code in both examples. Bright javascript, look at the execution of the code highlighted script and the execution of my alert.js, you will know the difference)

window.load = loadjs("http://coolshell.cn/asyncjs/alert.js")

Binded to a specific event - Example 5

<p style="cursor: pointer"onclick="LoadJS()">Click to load alert.js </p>

    这个示例很简单了。当你点击某个DOM元素,才会真正载入我们的alert.js。

更多

但是,绑定在某个特定事件上这个事似乎又过了一点,因为只有在点击的时候才会去真正的下载js,这又会太慢了了。好了,到这里,要抛出我们的终极问题——我们想要异步地把js文件下载到用户的本地,但是不执行,仅当在我们想要执行的时候去执行。

要是我们有下面这样的方式就好了:

varscript = document.createElement("script");
script.noexecute =true;
script.src ="alert.js";
document.body.appendChild(script);
//后面我们可以这么干
script.execute();

    可惜的是,这只是一个美丽的梦想,今天我们的Javascript还比较原始,这个“JS梦”还没有实现呢。

所以,我们的程序员只能使用hack的方式来搞。

有的程序员使用了非标准的script的type来cache javascript。如:

<scripttype=cache/scriptsrc="./alert.js"></script>

    因为”cache/script”,这个东西根本就不能被浏览器解析,所以浏览器也就不能把alert.js当javascript去执行,但是他又要去下载js文件,所以就可以搞定了。可惜的是,webkit严格符从了HTML的标准——对于这种不认识的东西,直接删除,什么也不干。于是,我们的梦又破了。

所以,我们需要再hack一下,就像N多年前玩preload图片那样,我们可以动用object标签(也可以动用iframe标签),于是我们有下面这样的代码:

functioncachejs(script_filename){
    varcache = document.createElement(&#39;object&#39;);
    cache.data = script_filename;
    cache.id ="coolshell_script_cache_id";
    cache.width = 0;
    cache.height = 0;
    document.body.appendChild(cache);
}

    然后,我们在的最后调用一下这个函数。请参看一下相关的示例:示例六

在Chrome下按 Ctrl+Shit+I,切换到network页,你就可以看到下载了alert.js但是没有执行,然后我们再用示例五的方式,因为浏览器端有缓存了,不会再从服务器上下载alert.js了。所以,就能保证执行速度了。

关于这种preload这种东西你应该不会陌生了。你还可以使用Ajax的方式,如:

varxhr =newXMLHttpRequest();
xhr.open(&#39;GET&#39;,&#39;new.js&#39;);
xhr.send(&#39;&#39;);

    到这里我就不再多说了,也不给示例了,大家可以自己试试去。

最后再提两个js,一个是ControlJS,一个叫HeadJS,专门用来做异步load javascript文件的。


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn