为了提高首屏渲染速度,减少白屏时间,我们会使用cdn加载第三方js,一般都是写在index.html,缺点就是一次性加载所有资源,影响首屏渲染;所以,需要动态加载,在哪里使用就在哪里加载。
动态向body元素中插入script、link标签。
具体做法如下:
- cdn公共配置文件
const CDN_CONFIG = {
// cdn公共配置
echarts: {
js: [
'https://cdn.bootcdn.net/ajax/libs/echarts/5.1.2/echarts.min.js'
],
css: []
},
xxx: {
js: [],
css: []
}
}
// 定制页面cdn配置
const customizePage = {
STOREMANAGE: [CDN_CONFIG.echarts]
}
export default customizePage;
- 处理定制页面cdn引入
import cdnConfig from '@/config/config/cdn.config'; // 引入cdn配置文件
export default {
data () {
return {
customizeCdnArr: [],
docs: {
js: { tagName: 'script', attrName: 'src' },
css: { tagName: 'link', attrName: 'href' }
}
}
},
mounted () {
const { customizedModuleName } = this.$route.params
let cdns = cdnConfig[customizedModuleName];
this.customizeCdnArr = this.cdnFun(cdns);
if (cdns && !(this.hasInitCdn('js') || this.hasInitCdn('css'))) return; // 当前定制页面是否配置cdn,且需要初始化cdn(js/css)
this.hasInitCdn('js') && this.loadCdn('js', this.customizeCdnArr.js, function () {
console.log('All Js are loaded');
});
this.hasInitCdn('css') && this.loadCdn('css', this.customizeCdnArr.css, function () {
console.log('All Css are loaded');
});
},
methods: {
loadCdn (tag, array, callback) {
const { tagName, attrName } = this.docs[tag];
var loader = function (src, handler) {
var node = document.createElement(tagName);
node[attrName] = src;
node.onload = node.onreadystatechange = function () {
node.onreadystatechange = node.onload = null;
handler();
}
if (tag == 'js') {
document.body.appendChild(node);
} else {
var head = document.getElementsByTagName("head")[0];
(head || document.body).appendChild(node);
}
};
(function run () {
if (array.length != 0) {
loader(array.shift(), run);
} else {
callback && callback();
}
})();
},
hasInitCdn (tag) {
let flag = false;
const { tagName, attrName } = this.docs[tag];
let nodeArr = Array.from(document.querySelectorAll(tagName)).map(i => i[attrName]);
this.customizeCdnArr[tag].length && !nodeArr.includes(this.customizeCdnArr[tag][0]) && (flag = true);
return flag;
},
cdnFun (arg) {
let js = [];
let css = [];
arg.forEach(item => {
console.log(item);
js = js.concat(item.js);
css = css.concat(item.css);
});
return { js, css };
}
}
}
- 定制页面使用mixin混入的方式,在需要动态加载cdn的页面混入
import initCdnCustomize from '@/config/mixins/initCdnCustomize';
export default {
mixins: [initCdnCustomize]
}