碎碎念:来了阿里之后一直各种忙,熟悉项目、配置、开发流程、内部权限,没多少时间写博客,其实这样是不好的,因为长时间不写博客,你会发现自己在技术上就没有什么进步的点,自然也就不写博客了,所以,博客必须得写,一个月至少一篇!
前言
所谓预加载技术,核心思想就是让浏览器提早去加载未来可能会用到的资源,然后浏览器就会把URL对应的资源给缓存起来。废话不多说,直接上代码!
实现细节
<script type="text/javascript">
setTimeout(function () {
var _lastOpenTime = 0,
host = window.location.host,
address;
const _nowTime = (new Date()).getTime();
//用Node.js起一个本地服务
address = 'http://localhost:5234';
try {
//一天只做一次预加载,这里从localStorage中读取上一次的预加载时间
_lastOpenTime = window.localStorage.getItem('_iframeOpenTime');
} catch (e) {
console.log('first time to using prefetch');
}
if (_lastOpenTime > 0 && (_nowTime - _lastOpenTime < 1000 * 60 * 60 * 24)) {
return;
}
//这个iframe指向预加载资源所在的真正页面,注意到iframe是可以跨域的,这在真正的项目开发中很有用,但这里为了演示,就直接指向一个本地地址
var _iframe = document.createElement('iframe');
_iframe.style.display = 'none';
_iframe.setAttribute('src', address + '/prefetch');
document.body.appendChild(_iframe);
try {
window.localStorage.setItem('_iframeOpenTime', _nowTime);
} catch (e) {
console.log('can not use localStorage');
}
}, 5000);
</script>
加载的iframe中的内容,注意到为了不让预加载的脚本资源直接运行并对网页造成干扰,通过将Image对象的src指定为要加载的脚本地址,成功实现了脚本下载但不执行的效果!具体做法是参照了Stoyan Stefanov大神的这篇文章
<script type="text/javascript">
window.onload = function () {
var testPrefetch = [
'http://localhost:5234/javascripts/jquery-1.9.js',
'http://localhost:5234/javascripts/bootstrap.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/vue-router/0.7.13/vue-router.min.js'
];
var _object;
//Firefox对Image对象做了限制,所以改用object对象,这里先对Firefox做一个判断
var isFirefox = typeof InstallTrigger !== 'undefined';
console.log(isFirefox);
if (!isFirefox) {
for (var i = testPrefetch.length - 1; i >= 0; i--) {
new Image().src = testPrefetch[i];
}
} else {
for (var j = testPrefetch.length - 1; j >= 0; j--) {
_object = document.createElement('object');
_object.data = testPrefetch[j];
_object.width = 0;
_object.height = 0;
document.body.appendChild(_object);
}
}
}
</script>
最终实现的效果如下,第一次加载
当打开包含了预加载的资源的地址时情况
这里考虑到随着项目的增长,预加载的资源可能会越来越多,一个个去加载会很耗费时间,所以我利用现有的模块化构建系统,搭了一个页面,便于管理前端资源。PS:这是阿里内部开发的一套前端模块化开发系统,提高了前端页面的复用性,具体内容保密不多说。
主要的内容就是参考了delai.me的一篇文章,然后我自己给页面搭了个可视化管理的页面。感谢德来兄的技术分享!