经验分享-延缓执行 JavaScript 提升网页加载速度
在我们的web开发当中,我们会涉及到大量的外部JS代码,众所周知,加载这些外部的JS代码是一件非常耗时的事情,因为他影响到用户体验,加载不好的话会影响我们做的效果,因此延缓执行 JavaScript 是一个能有效提高网页加载速度以及提升用户阅读体验质量的途径。
通过我把要执行的JS代码这样一调用,页面加载速度确实提高了50%多,你可以用谷歌工具测试一下确实很快
我们先来设想一下:在页面加载过程当中发生了什么事情,首页是加载HTML 和 CSS 。等这些在浏览器里能够正确地(被渲染出来之后,在开始执行JS代码。假设有个别的JS文件突然中止,只要这个JS文件没有语法错误,那么网页最终一定会被正确的加载;因此延迟JS加载可以采用2种方法执行:
一种情况是页面dom元素全部加载完成之后,在执行页面内部的JS代码
第二种情况就是动态的加载javascript文件,如果多个JS文件之间存在依赖,确保主要的JS文件写在底部以便最后加载:下面就说说具体的实现代码:
看我的博客顶部的导航,
每当页面打开的时候他加载的速度是很快的,我就是采用第二种方法动态加载javascript文件来实现的,主要的代码片段
<script type="text/javascript">// <![CDATA[ _lazyLoadScripts = new Array(); _lazyExecutedCallbacks = new Array(); // ]]></script> <script type="text/javascript" src="/scripts/jquery-1.4.4.min.js"></script> <script type="text/javascript" src="/scripts/website-load.js"></script>
解释一下上面代码的意思:“_lazyLoadScripts” 和 “_lazyExecutedCallbacks” 是两个用来存变量的数组,你要加载的变量都需要写在这里面;可能这样看你看不懂,我用我博客的例子说明;看实际的代码:
<!--加载元素--> <script type="text/javascript">// <![CDATA[ _lazyLoadScripts = new Array();//外部要执行的JS代码需要定义到这个数组, _lazyLoadScripts.push("https://files.cnblogs.com/58top/jquery.lazyload.mini.js","https://files.cnblogs.com/magetu/jquery.scripts-13501165562.js"); _lazyExecutedCallbacks = new Array();//定义一个变量数组, _lazyExecutedCallbacks.push(function ()//然后吧需要执行的JS代码写在里面,也就是入栈操作 { $("head").append('<!--[if IE 6]><link rel="stylesheet" type="text/css" href="https://files.cnblogs.com/58top/iehacks.css" /><script src="https://files.cnblogs.com/58top/ie6pngfix.js"><\/script><script src="https://files.cnblogs.com/58top/zh_CN.js"><\/script><![endif]-->'); $("#header").after('<div id="mainnav-sticky-wrapper" class="sticky-wrapper is-sticky" style="height: 48px;"><div id="mainnav" style="" >'+ '<div class="rapidxwpr">'+ '<div id="topmenu">'+ '<ul class="sf-menu sf-js-enabled sf-shadow">'+ '<li ><a href="http://www.cnblogs.com"><span>博客园</span></a></li>'+ '<li ><a href="http://www.cnblogs.com/58top"><span>首页</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/admin/EditPosts.aspx"><span>管理</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/category/399677.html"><span>前端开发</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/category/331530.html"><span>CSS</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/category/330174.html"><span>jQuery</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/category/330797.html"><span>HTML5</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/category/330308.html"><span>Photography</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/category/332697.html"><span>创意设计</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/category/402990.html"><span>字体设计</span></a></li>'+ '<li class="" ><a href="http://www.cnblogs.com/58top/rss"><span>订阅</span></a></li>'+ '</div>'+ '<div class="navsocial">'+ '<ul>'+ '<li class="twitter"><a target="_blank" rel="external nofollow" href="http://list.qq.com/cgi-bin/qf_invite?id=a17d3955b24fb6a3208154a6ef7aa86bd47a549d90b4253e">Twitter</a></li>'+ '<li class="facebook"><a target="_blank" rel="external nofollow" href="https://pinterest.com/58top/">Facebook</a></li>'+ '<li class="rss"><a target="_blank" rel="external nofollow" href="">RSS</a></li>'+ '<li class="pinterest"><a target="_blank" rel="external nofollow" ">Pinterest</a></li>'+ '</ul>'+ '</div>'+ '</div>'+ '</div></div>'); }); // ]]></script> <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script> <script type="text/javascript" src="https://files.cnblogs.com/58top/website-lazy-load1.js"></script>//这个是要执行动态加载的函数,最终所有的变量都在这个函数里面执行
这些被压入(push)到 “_lazyExecutedCallbacks” 里的 JS 代码和被插入到 “_lazyLoadScripts” 里的外部 JS 文件全部都会在 “website-lazy.js” 里被执行,执行的代码片段如下
1 2 // 执行关联的外部JS代码,通过for循环读取每个JS文件 3 function loadScriptsAfterDocumentReady() 4 { 5 if (_lazyLoadScripts && _lazyLoadScripts != null) 6 { 7 for (var i = 0; i < _lazyLoadScripts.length; i++) 8 { 9 var scriptTag = document.createElement('script'); 10 scriptTag.type = 'text/javascript'; 11 scriptTag.src = _lazyLoadScripts[i]; 12 var firstScriptTag = document.getElementsByTagName('script')[0]; 13 firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag); 14 } 15 } 16 } 17 18 // 执行回调的JS代码.同样的通过for循环读取JS代码了 19 function invokeLazyExecutedCallbacks() 20 { 21 if (_lazyExecutedCallbacks && _lazyExecutedCallbacks.length > 0) 22 for(var i=0; i<_lazyExecutedCallbacks.length; i++) 23 _lazyExecutedCallbacks[i](); 24 } 25 26 // 执行最终的方法当页面加载完成之后. 27 jQuery(document).ready(function () 28 { 29 loadScriptsAfterDocumentReady(); 30 invokeLazyExecutedCallbacks(); 31 });
如果你的网站需要广泛地加载外部 JS 文件,那么将它们写在 “website-load.js” 里动态的加载进来,这样能最大程度的提高用户体验
通过我把要执行的JS代码这样一调用,页面加载速度确实提高了50%多,因此非常推荐这样方法,你也可以实际的用一下这个方法,非常棒,欢迎留下你的使用心得,一起交流