简体   繁体   English

为什么像Hotjar和Google Analytics这样的网站使用复杂的跟踪代码而不仅仅是<script>标记?

[英]Why do websites like Hotjar and Google Analytics use complex tracking code instead of just a <script> tag?

Website that use JS tracking usually use this kind of code : 使用JS跟踪的网站通常使用这种代码:

 <script> (function(h,o,t,j,a,r){ h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; h._hjSettings={hjid:9999,hjsv:5}; a=o.getElementsByTagName('head')[0]; r=o.createElement('script');r.async=1; r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; a.appendChild(r); })(window,document,'//static.hotjar.com/c/hotjar-','.js?sv='); </script> 

In the end, those scripts just add a <script> tag to the <head> of the page, so surely there must be a reason why they're doing it this way. 最后,这些脚本只是将<script>标签添加到页面的<head>中,所以肯定必须有这样一个原因,即他们这样做。

Is it for ad-blocking bypass reasons ? 它是否适用于广告屏蔽旁路的原因? Wouldn't the generated request be the same as if it was hardcoded in the <head> ? 生成的请求不会像在<head>硬编码一样吗?

I'm the chief architect at Hotjar so I'll explain the reasons why we did it in this particular way. 我是Hotjar的首席架构师,所以我将解释为什么我们以这种特殊的方式做到这一点。

  1. We need to do things before the main script is loaded. 我们需要在加载主脚本之前做一些事情。

    h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; h.hj = h.hj ||函数(){。(h.hj.q = h.hj.q || [])推(参数)};

That particular line allows us to store actions to execute once the main script is loaded. 该特定行允许我们在加载主脚本后存储要执行的操作。 It allows for things like hj('trackVirtualPageView', '/url') to be called before our script is loaded. 它允许在我们的脚本加载之前调用hj('trackVirtualPageView','/ url')之类的东西。

  1. We can store things like settings as part of the snippet. 我们可以将设置之类的内容存储为代码段的一部分。

    h._hjSettings={hjid:9999,hjsv:5}; h._hjSettings = {hjid:9999,hjsv:5};

That could absolutely be added as part of the query string when loading the script. 在加载脚本时,这绝对可以作为查询字符串的一部分添加。 The downside of using that approach is that we would get less optimal caching since it would be impossible for a browser to know that script.js?hjid=1 and script.js?hjid=2 actually loads the same JS file. 使用这种方法的缺点是我们会得到不太优化的缓存,因为浏览器不可能知道script.js?hjid = 1和script.js?hjid = 2实际上加载了相同的JS文件。

  1. What we're doing in the last part is actually just creating a <script async=1> tag and adding it to the <head> which works really well. 我们在最后一部分中所做的实际上只是创建一个<script async=1>标记并将其添加到<head> ,这非常有效。 The reason we're doing it through JS is that we like to make it as easy as possible for our users by only asking them to put code in one place. 我们之所以通过JS这样做是因为我们希望让用户尽可能简单地让代码放在一个地方。

There might be an even better to do what we're doing which I'm blissfully unaware of, and in case there is, please reach out and tell me about it! 可能会有更好的做我们正在做的事情,我很幸福没有意识到,如果有,请联系并告诉我它! :) :)

At least part of the answer is that vendors want to load their libraries in a way that does not block page rendering. 至少部分答案是供应商希望以不阻止页面呈现的方式加载库。

If the browser hits a script element it tries to get the script source, and might prevent the page from rendering until the complete script is downloaded. 如果浏览器遇到脚本元素,它会尝试获取脚本源,并可能会阻止页面呈现,直到下载完整的脚本。 In the bad old days it used to happen that website would show up blank, because the (then synchronous) Google Analytics script could not be downloaded in a timely fashion and stopped the page from rendering. 在过去的糟糕时期过去,网站会显示空白,因为无法及时下载(然后是同步的)Google Analytics脚本并停止呈现页面。 Script injection became an accepted method to make scripts non-blocking. 脚本注入成为使脚本无阻塞的可接受方法。

There are other ways (defer, asynch, etc - for historical interest here is a link to an 2009 article that discusses the issue , because the problem is that old), but script injection is a convenient way to set up a few variables along the way (plus if Google does it it must be the best way, or so seems to be the though process with some companies). 还有其他方法(defer,asynch等 - 为了历史的兴趣,这里有一篇关于讨论该问题的2009年文章的链接 ,因为问题是旧的),但脚本注入是一种方便的方法来设置一些变量沿着方式(如果谷歌这样做,它必须是最好的方式,或者似乎是与某些公司合作的过程)。

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

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