CDN动态加载配置

852 阅读1分钟

为了提高首屏渲染速度,减少白屏时间,我们会使用cdn加载第三方js,一般都是写在index.html,缺点就是一次性加载所有资源,影响首屏渲染;所以,需要动态加载,在哪里使用就在哪里加载。

动态向body元素中插入script、link标签。

具体做法如下:

  1. 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;
  1. 处理定制页面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 };
    }
  }
}
  1. 定制页面使用mixin混入的方式,在需要动态加载cdn的页面混入

  import initCdnCustomize from '@/config/mixins/initCdnCustomize';
  export default {
    mixins: [initCdnCustomize]
  }
​