我是如何处理外部资源引用的

Web Design Feb 26, 2017

如标题所说,不受控制的 JS,主要是说在别人服务器上的,尤其是被 GFW 的,当然了,不只限于 JS 文件,CSS,图片什么的都可以,原理大同小异。

我的博客上面的资源,几乎所有的 JS,图片,都在自己的 CDN,其他的在 VPS,只有 Google Analytics 和 Disqus 引用的第三方 JS。

事情需要从这个博客的 Theme,Namjagbarwa 说起,首页的 card 在 layout 之前,需要保证所有外部资源加载完毕,其代码类似于这样:

$(window).load(function() {

  window.sr = window.ScrollReveal().reveal(cardName, {
      afterReveal: function () {
          if ($postsGrid) {
              $postsGrid.masonry("layout");
          }
      }
  });
});

没加载完的时候是一片空白。界面上什么都没有,造成一种假死的状态。

如果想加入 Disqus 评论个数的功能,需要引入 count.js,所以就导致了没翻墙的情况下,这个资源根本无法加载成功,阻塞了 $(window).load()

即时这个 script 标签设置 async=true,也是会阻塞。

解决办法很巧妙,既然 $(window).load() 只会在所有资源加载完毕的时候触发,那太简单了,把 Disqus 干掉不就好了么。。当然不行,干掉了还怎么显示评论个数。

JS 对资源的判定标准是,Tag 里面有 src Attribute,我们只需要把这个 Attribute 干掉,就能保证 $(window).load() 忽略掉这个 JS。

<script type="text/javascript">
    (function () {
        var s = document.createElement('script'); s.async = true;
        s.type = 'text/javascript';
        s.setAttribute('external_src', '//' + window.disqus_shortname + '.disqus.com/count.js');
        (document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
    }());
</script>

我们把 count.js 的 Attribute 设置为 external_src,就不会再阻塞 rendering,但是资源也没法加载了咋弄,这就更容易了,在 load 之后遍历一下:

$(window).load(function() {
    $('[external_src]').each(function() {
        var external_src = $(this).attr("external_src");
        $(this).attr("src", $(this).attr("external_src")).removeAttr("external_src");
    });
});

这样就完美解决了。

Tags

Jie Li

🚘 On-road / 📉 US Stock / 💻 Full Stack Developer / 🎓 Grad Student / ®️ ENTJ

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.