Skip to content

js异步加载方式 #27

Open
Open
@TieMuZhen

Description

@TieMuZhen

js动态添加script标签

(function(){
    var scriptEle = document.createElement("script");
    scriptEle.type = "text/javasctipt";
    scriptEle.async = true;
    scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
    var x = document.getElementsByTagName("head")[0];
    x.insertBefore(scriptEle, x.firstChild);       
 })();

但是这种加载方式执行完之前会阻止onload事件的触发,而现在很多页面的代码都在onload时还执行额外的渲染工作,所以还是会阻塞部分页面的初始化处理。

注意:
页面加载完成有两种事件:

  • ready事件:表示文档结构(DOM结构)已经加载完成(不包含图片等非文字媒体文件),
  • onload事件:指示页面包含图片等文件在内的所有元素都加载完成。(可以说:ready 在onload 前加载)

onload时的异步加载

(function(){
    if(window.attachEvent){
        window.attachEvent("load", asyncLoad);
    }else{
        window.addEventListener("load", asyncLoad);
    }
    var asyncLoad = function(){
        var ga = document.createElement('script');
         ga.type = 'text/javascript';
        ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga, s);
    }
})();

这种方法只是把插入script的方法放在一个函数里面,然后放在window的onload方法里面执行,这样就解决了阻塞onload事件触发的问题。

注: DOMContentLoadedload的区别。前者是在document已经解析完成,页面中的dom元素可用,但是页面中的图片,视频,音频等资源未加载完,DOMContentLoaded作用同jQuery中的ready事件;后者的区别在于页面所有资源全部加载完毕。

$(document).ready()

需要引入jquery,兼容所有浏览器

$(document).ready(function() {
     alert("加载完成!");
 });

<script>标签的async="async"属性

  • async属性规定一旦脚本可用,则会异步执行
  • async属性仅适用于外部脚本
  • 此方法不能保证脚本按顺序执行
  • 他们将在onload事件之前完成
  • async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。
<script type="text/javascript" src="xxx.js" async="async"></script>

对于async标记,浏览器的解析过程是这样的:

  • 浏览器开始解析HTML网页
  • 解析过程中,发现带有async属性的script标签
  • 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本
  • 脚本下载完成,浏览器暂停解析HTML网页,开始执行下载的脚本
  • 脚本执行完毕,浏览器恢复解析HTML网页

<script>标签的defer="defer"属性

  • defer要等到整个页面在内存中正常渲染结束,才会执行。
  • 兼容所有浏览器
  • 此方法可以确保所有设置了defer属性的脚本按顺序执行
<script type="text/javascript" defer></script>

对于defer标记,浏览器的解析过程是这样的:

  • 浏览器开始解析HTML网页
  • 解析过程中,发现带有defer属性的script标签
  • 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本
  • 浏览器完成解析HTML网页,此时再执行下载的脚本

es6模块type="module"属性

浏览器对于带有type=”module”<script>都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,等同于打开了<script>标签的defer属性 。如下:

<script type="module" src="XXX.js"></script>

ready()与onload()的区别

window.onload()(不推荐)

  • 加载时机: 必须等待网页全部加载完毕(包括图片等),然后再执行JS代码。
  • 执行次数: 只能执行一次,如果第二次,那么第一次的执行会被覆盖。
  • 简写: 无。
    举例:
window.onload = function() { console.log("text1");};
window.onload = function() { console.log("text2");}; 

// ƒ () { console.log("text2");}  // 结果只输出第二个

$(document).ready()

  • 加载时机: 只需要等待网页中的DOM结构加载完毕,就能执行JS代码。
  • 执行次数: 可以执行多次,不会覆盖上一次。
  • 简写:$(function () {})
    举例:
$(document).ready(function(){console.log("Hello")});
$(document).ready(function(){console.log("Hello")});

// Hello
// Hello

注意

asyncdefer这两个属性只是script标签在header标签中使用的,如果你把它放在body后面是无效的

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions