简体   繁体   English

懒惰加载addthis脚本? (或延迟加载外部js内容取决于已经触发的事件)

[英]Lazy loading the addthis script? (or lazy loading external js content dependent on already fired events)

I want to have the addthis widget available for my users, but I want to lazy load it so that my page loads as quickly as possible. 我希望为我的用户提供addthis小部件,但我想延迟加载它以便我的页面尽快加载。 However, after trying it via a script tag and then via my lazy loading method, it appears to only work via the script tag. 但是,在通过脚本标记然后通过我的延迟加载方法尝试它之后,它似乎只能通过脚本标记工作。 In the obfuscated code, I see something that looks like it's dependent on the DOMContentLoaded event (at least for Firefox). 在混淆的代码中,我看到一些看起来像是依赖于DOMContentLoaded事件的东西(至少对于Firefox而言)。

Since the DOMContentLoaded event has already fired, the widget doesn't render properly. 由于DOMContentLoaded事件已经触发,因此窗口小部件无法正确呈现。 What to do? 该怎么办?

I could just use a script tag (slower)... or could I fire (in a cross browser way) the DOMContentLoaded (or equivalent) event? 我可以使用脚本标记(较慢)...或者我可以触发(以交叉浏览器方式)DOMContentLoaded(或等效)事件? I have a feeling this may not be possible because I believe that (like jQuery) there are multiple tests of the content ready event, and so multiple simulated events would have to occur. 我有一种感觉,这可能是不可能的,因为我相信(像jQuery)有内容就绪事件的多个测试,因此必须发生多个模拟事件。

Nonetheless, this is an interesting problem because I have seen a couple widgets now assume that you are including their stuff via static script tags. 尽管如此,这是一个有趣的问题,因为我已经看到一些小部件现在假设你通过静态脚本标签包含他们的东西。 It would be nice if they wrote code that was more useful to developers concerned about speed, but until then, is there a work around? 如果他们编写的代码对于关注速度的开发人员更有用,那会很好,但在那之前,是否有解决方法? And/or are any of my assumptions wrong? 和/或我的任何假设是错误的?

Edit: Because the 1st answer to the question seemed to miss the point of my problem, I wanted to clarify the situation. 编辑:因为问题的第一个答案似乎忽略了我的问题,我想澄清一下情况。

This is about a specific problem. 这是一个特定的问题。 I'm not looking for yet another lazy load script or check if some dependencies are loaded script. 我不是在寻找另一个延迟加载脚本或检查是否有一些依赖项是加载脚本。 Specifically this problem deals with 特别是这个问题涉及

  1. external widgets that you do not have control over and may or may not be obfuscated 您无法控制的外部小部件,可能会也可能不会被混淆
  2. delaying the load of the external widgets until they are needed or at least, til substantially after everything else has been loaded including other deferred elements 延迟外部小部件的负载,直到需要它们为止,或至少在其他所有负载包括其他延迟元素之后大致延迟
  3. b/c of the how the widget was written, precludes existing, typical lazy loading paradigms 关于小部件编写方式的b / c,排除了现有的典型延迟加载范例

While it's esoteric, I have seen it happen with a couple widgets - where the widget developers assume that you're just willing to throw in another script tag at the bottom of the page. 虽然它是深奥的,但我已经看到它发生在一些小部件 - 小部件开发人员认为你只是愿意在页面底部引入另一个脚本标记。 I'm looking to save those 500-1000 ms** though as numerous studies by Yahoo, Google, and Amazon show it to be important to your user's experience. 虽然雅虎,谷歌和亚马逊的大量研究表明它对用户的体验很重要,但我希望能节省500到1000毫秒的时间。

**My testing with hammerhead and personal experience indicates that this will be my savings in this case. **我用锤头和个人经验测试表明,这将是我在这种情况下的节省。

The simplest solution is to set parameter domready to 1 when embedding addthis script into your page. 最简单的解决方案是在将addthis脚本嵌入页面时将参数domready设置为1。 Here is an example: 这是一个例子:

<script type="text/javascript" 
src="http://s7.addthis.com/js/250/addthis_widget.js#username=addthis&domready=1">
</script>

I have tested it on IE, Firefox, Chrome, and Safari, and all worked fine. 我已经在IE,Firefox,Chrome和Safari上进行了测试,一切正常。 More information on addthis configuration parameters is available here . 有关addthis配置参数的更多信息,请参见此处

This code solves the problem and saves the loading time that I was looking for. 此代码解决了问题并节省了我正在寻找的加载时间。

After reading this post about how most current js libraries implement tests for a dom loaded event. 在阅读这篇文章后,关于大多数当前的js库如何为dom加载的事件实现测试。 I spent some time with the obfuscated code, and I was able to determine that addthis uses a combination of the mentioned doscroll method, timers, and the DOMContentLoaded event for various browsers. 我花了一些时间使用混淆代码,并且我能够确定addthis使用所提到的doscroll方法,计时器和DOMContentLoaded事件的组合用于各种浏览器。 Since only those browsers dependent on the DOMContentloaded event would need the following code anyway: 由于只有那些依赖于DOMContentloaded事件的浏览器才需要以下代码:

if( document.createEvent ) {
 var evt = document.createEvent("MutationEvents"); 
 evt.initMutationEvent("DOMContentLoaded", true, true, document, "", "", "", 0); 
 document.dispatchEvent(evt);
}

and the rest depend on timers testing for existence of certain properties, I only had to accommodate this one case to be able to lazy load this external JS content rather than using the static script tags, thus saving the time that I was hoping for. 其余的依赖于计时器测试是否存在某些属性,我只需要容纳这一个案例就可以延迟加载这个外部JS内容而不是使用静态脚本标记,从而节省了我希望的时间。 :) :)

Edit: If the goal is simply to have your other contetn load first, try putting the <script> tags near the bottom of your page. 编辑:如果目标只是让您的其他竞争加载,请尝试将<script>标记放在页面底部附近。 It will still be able to catch the DOMContentLoaded and the content that comes before will be loaded before the script. 它仍然能够捕获DOMContentLoaded,并且之前的内容将在脚本之前加载。

Original: 原版的:

in addition to loading on DOMContentLoaded, you could have it load if a certain var is set true. 除了在DOMContentLoaded上加载之外,如果将某个var设置为true,则可以加载它。 eg 例如

var isDOMContentLoaded = false;

document.addEventListener("DOMContentLoaded",function() { isDOMContentLoaded = true; }, false);

then add to the other script file 然后添加到其他脚本文件

if (isDOMContentLoaded) loadThisScript();

Edit in response to comments: 编辑以回应评论:

Load the script, and run the function that the DOMContentLoaded listener fires. 加载脚本,然后运行DOMContentLoaded侦听器触发的函数。 ( read the script if you're not sure what function is being called ). (如果你不确定调用什么函数,请阅读脚本)。

eg 例如

var timerID;
var iteration=0;

function checkAndLoad() {
    if (typeof loadThisScript != "undefined") {
        clearInterval(timerID);
        loadThisScript();
    }
    iteration++;
    if (iteration > 59) clearInterval(timerID);
}

var extScript = document.createElement("script");
extScript.setAttribute("src",scriptSrcHere);
document.head.appendChild(extScript);

timerID = setInterval(checkAndLoad,1000);

The above will try once a second for 60 seconds to check if the function you need is available, and, if so, run it 以上将每秒尝试一次,持续60秒,以检查您所需的功能是否可用,如果是,则运行它

AddThis has a section on how to load their tools asynchronously . AddThis有一节介绍如何异步加载他们的工具

Current 'best' solution: 目前“最佳”解决方案:

<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=[YOUR PROFILE ID]" async="async"></script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM