最近对单页面比较感兴趣,想用单页面实现原生app的效果,但单页面应用将多页面汇集到一个页面上,由此可知初始加载的数据会很大,这样会导致在初始加载网页的时候会有一个比较漫长的等待时长,特别是网络不好的情况下等待时长就更不能让用户满足。
为了解决这个问题,我想到一个解决方法,在页面先不加载js和css文件,首先展示一些准备好的图片或者等待页面(数据尽量小),然后等onload事件触发的时候再一一将js文件和css文件载入到页面。
window.onload = function(){var scripts = ["/static/js/jquery-1.8.3.min.js","/static/js/fuc.js","/static/js/app.js"];var s = 0;scripts.forEach(function(scriptSrc){var head = document.getElementsByTagName('head')[0];var script = document.createElement('script');script.type = 'text/javascript';script.charset = 'utf-8';script.async = true;script.timeout = 120000;script.src = scriptSrc;head.appendChild(script);script.onload=function(){s++;if(s == scripts.length){var load = document.getElementById("load");var app = document.getElementById("app");load.style.display = "none";app.style.display = "block";}}});}
如代码所示,当所有的js都成功加载后,再将主页面对应的div显示出来,这样用户的体验才会比较良好。这里定义了一个变量s,当变量s等于加载的js的数量的时候才会显示主页面,所以如果出现一个没有成功加载都会导致页面不会出现。值得一提的是async这个属性等于true的时候是异步加载,这样加载速度会更加快,但是这也会出现一个问题:如果出现一个js会依赖另一个js的时候就会可能出现错误,就比如上面的代码中的app.js用到了jquery,当app.js加载速度会jquery-1.8.3.min.js更快的时候会提前渲染,此时jquery并没有加载,所以app.js使用到jquery的地方就会报错。
Script异步加载还可以用defer属性,defer属性与async不同的是defer载入成功不会自动渲染而是等到onload事件触发时才会开始执行,而async属性是文件载入成功就立即执行。
因上面我是等着onload方法触发后才开始载入js文件,所以使用async或者defer差别不大
如果是要完全避免上面的问题则是要等依赖的js加载成功,触发script.onload方法时再去加载该js,则可以解决因加载速度比依赖的js的加载速度更快出现的问题。还有一种方法,就是把所有的js打包到一个js里面,我这里是使用了webpack打包程序将整个程序都打包到了一个js,这样加载就不会有问题了。