• 异步载入JS


      平时最常使用的就是这样的同步载入形式:
       <script src="http://yourdomain.com/script.js"></script>
       同步模式。又称堵塞模式,会阻止浏览器的兴许处理,停止了兴许的解析。因此停止了兴许的文件载入(如图像)、渲染、代码运行。


    js 之所以要同步运行。是由于 js 中可能有输出 document 内容、改动dom、重定向等行为,所以默认同步运行才是安全的。
       曾经的一般建议是把<script>放在页面末尾</body>之前,这样尽可能降低这样的堵塞行为,而先让页面展示出来。


       简单说:载入的网络 timeline 是瀑布模型,而异步载入的 timeline 是并发模型。

    常见异步载入(Script DOM Element)

    (function() { 
    var s = document.createElement('script'); 
    s.type = 'text/javascript'; 
    s.async = true; 
    s.src = 'http://yourdomain.com/script.js'; 
    var x = document.getElementsByTagName('script')[0]; 
    x.parentNode.insertBefore(s, x); 
    })(); 


    比如 Google Analytics 和 Google+ Badge 都使用了这样的异步载入代码:

    (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); 
    })(); 
    
    (function() 
    {var po = document.createElement("script"); 
    po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js"; 
    var s = document.getElementsByTagName("script")[0]; 
    s.parentNode.insertBefore(po, s); 
    })(); 

    百度地图的异步载入:

    	var map;  //全局地图
    	function initialize() {
    		map = new BMap.Map('map');
    		var point = new BMap.Point(121.491, 31.233);
    		map.centerAndZoom(point, 11);
    		//使用鼠标滚轮控制缩放
    		map.enableScrollWheelZoom();
    		//加入地图控件
    		map.addControl(new BMap.NavigationControl());
    		map.addControl(new BMap.ScaleControl());
    		map.addControl(new BMap.OverviewMapControl());
    		map.addControl(new BMap.MapTypeControl());
    		//点击地图就加入标注点
    		map.addEventListener("click", addMarkerService);
    		PanOptions.noAnimation=false;
    	}
    	function loadScript() {
    		var script = document.createElement("script");
    		script.src = "http://api.map.baidu.com/api?

    v=1.5&ak={No}&callback=initialize"; //此为v1.5版本号的引用方式 // http://api.map.baidu.com/api?

    v=1.5&ak=您的密钥&callback=initialize"; //此为v1.4版本号及曾经版本号的引用方式 document.body.appendChild(script); } window.onload = loadScript;


    可是。这样的载入方式在载入运行完之前会阻止 onload 事件的触发,而如今非常多页面的代码都在 onload 时还要运行额外的渲染工作等,所以还是会堵塞部分页面的初始化处理。

    (function() { 
    function async_load(){ 
    var s = document.createElement('script'); 
    s.type = 'text/javascript'; 
    s.async = true; 
    s.src = 'http://yourdomain.com/script.js'; 
    var x = document.getElementsByTagName('script')[0]; 
    x.parentNode.insertBefore(s, x); 
    } 
    if (window.attachEvent) 
    window.attachEvent('onload', async_load); 
    else 
    window.addEventListener('load', async_load, false); 
    })(); 


    这和前面的方式几乎相同,但关键是它不是马上開始异步载入 js ,而是在 onload 时才開始异步载入。这样就攻克了堵塞 onload 事件触发的问题。
    补充:DOMContentLoaded 与 OnLoad 事件
    DOMContentLoaded : 页面(document)已经解析完毕,页面中的dom元素已经可用。可是页面中引用的图片、subframe可能还没有载入完。


    OnLoad:页面的全部资源都载入完毕(包含图片)。

    浏览器的载入进度在这时才停止。
    这两个时间点将页面载入的timeline分成了三个阶段。

     

    异步载入的其他方法
    由于Javascript的动态特性,还有非常多异步载入方法:
    XHR Eval
    XHR Injection
    Script in Iframe
    Script Defer
    document.write Script Tag
    另一种方法是用 setTimeout 延迟0秒 与 其他方法组合。


    XHR Eval :通过 ajax 获取js的内容,然后 eval 运行。
    var xhrObj = getXHRObject();

    xhrObj.onreadystatechange = 
    function() { 
    if ( xhrObj.readyState != 4 ) return; 
    eval(xhrObj.responseText); 
    }; 
    xhrObj.open('GET', 'A.js', true); 
    xhrObj.send(''); 
  • 相关阅读:
    [译]6.1. Data Structures Featured in This Chapter 本章涉及到的数据结构
    Linux中进程结构描述符
    How to uninstall GRUB
    [每日一点]msgsnd函数代码跟踪
    开始从代码入手学习内核
    剖析MagicAjax
    Castle实践6-TypedFactory Facility
    移植MSPetShop3到Castle MonoRail -Model与DAL层的移植(AR)
    热血江湖外挂之【热血江湖自补器 Version 0.1】
    对 "闭包closure" 的一些见解
  • 原文地址:https://www.cnblogs.com/llguanli/p/8321077.html
Copyright © 2020-2023  润新知