Problem: too much JavaScript in your page to handle 3rd party widgets (e.g. Like buttons) Possible solution: a common piece of JavaScript to handle all third parties' needs
问题:页面中JavaScript太多,无法处理第三方的小部件(例如,“赞”按钮)可能的解决方案:一块通用JavaScript可以满足所有第三方的需求
![3t1jsi](https://i-blog.csdnimg.cn/blog_migrate/edd0ee8c5c7d309a94843883d8a05efd.png)
什么JavaScript?(What JavaScript?)
If you've read the previous post, you see that the most features in a third party widget are possible only if you inject JavaScript from the third party provider into your page. Having "a secret agent" on your page, the provider can take care of problems such as appropriately resizing the widget.
如果您已阅读上一篇文章,您将看到只有在将第三方提供程序中JavaScript注入页面中的情况下,第三方小部件中的大多数功能才可以使用。 您的页面上有“秘密特工”,提供者可以解决诸如适当调整窗口小部件大小的问题。
为什么这是个问题? (Why is this a problem?)
Third party scripts can be a SPOF (an outage), unless you load them asynchronously. They can block onload
, unless the provider lets you load it in an iframe (and most don't). There can be security implications because you're hosting the script in your page with all permissions associated with that. And in any case, it's just too much JavaScript for the browser to parse and execute (think of mobile devices)
第三方脚本可以是SPOF(中断),除非您异步加载它们。 他们可以阻止onload
,除非提供程序允许您将其加载到iframe中(大多数情况下不这样做)。 这可能会带来安全隐患,因为您正在将脚本托管在页面中,并具有与此相关的所有权限。 在任何情况下,浏览器都无法解析和执行太多JavaScript(以移动设备为例)
If you include the most common Like, Tweet and +1 buttons and throw in Disqus comments, you're looking at well over 100K (minified, gzipped) worth of JavaScript (wpt for this jsbin)
如果包括最常见的一样,鸣叫和+1按钮和Disqus评论扔,你看远远超过100K(精缩,gzip压缩的)价值JavaScript( WPT对于这个jsbin )
This is more than the whole of jQuery, which previous experiments show can take the noticeable 200ms just to parse and evaluate (assuming it's cached) on an iPhone or Android.
这远不止整个jQuery,先前的实验表明,整个jQuery只需花费200毫秒即可在iPhone或Android上进行解析和评估(假设已缓存)。
所有这些JS都做什么? (What does all of this JS do?)
The JavaScript used by third parties is not always all about social widgets. The JS also provides API call utilities, other dialogs and so on. But the tasks related to social widgets are:
第三方使用JavaScript并不总是与社交小部件有关。 JS还提供API调用实用程序,其他对话框等。 但是与社交小部件有关的任务是:
- Find html tags that say "there be widget here!" and insert an iframe at that location, pointing to a URL hosted by the third party 找到说“这里有小部件!”的html标签。 并在该位置插入一个iframe,指向第三方托管的网址
- Listen to requests from the new iframes fulfill these requests. The most common request is "resize me, please" 监听来自新iframe的请求,以满足这些请求。 最常见的要求是“请调整大小”
Now, creating an iframe and resizing it doesn't sound like much, right? But every provider has to do it over and over again. It's just a wasted code duplication that the browser has to deal with.
现在,创建iframe并调整其大小听起来并不多,对吧? 但是每个提供商都必须一遍又一遍地做。 这只是浏览器必须处理的浪费的代码重复。
Can't we just not duplicate this JavaScript? Can we have a common library that can take care of all widgets there are?
我们不能只是不重复此JavaScript吗? 我们可以拥有一个可以处理所有小部件的公共库吗?
C3PO草案 (C3PO draft)
Here's a demo page of what I have in mind. The page is loading third party widgets: like, tweet, +1 and another one I created just for illustration of the messaging part.
这是我所想到的演示页面。 该页面正在加载第三方小部件:例如tweet,+ 1和我创建的另一个小部件,仅用于说明消息传递部分。
It has a possible solution I drafted as the c3po
object. View source, the JS is inline.
它有一个可能的解决方案,我起草为c3po
对象。 查看源代码,JS是内联的。
What does c3po do?
c3po是做什么的?
The idea is that the developer should not have to make any changes to existing sites, other than remove FB, G, Tw, etc JS files and replace with the single c3po library. In other words, only the JS loading part should be changed, not the individual widgets code.
这个想法是,除了删除FB,G,Tw等JS文件并替换为单个c3po库之外,开发人员无需对现有网站进行任何更改。 换句话说,仅应更改JS加载部分,而不更改各个小部件代码。
c3po is a small utility which can be packaged together with the rest of your application code, so there will be no additional HTTP requests.
c3po是一个小型实用程序,可以与您的其余应用程序代码打包在一起,因此不会有其他HTTP请求。
解析和插入iframe (Parsing and inserting iframes)
The first task for c3po is to insert iframes. It looks for HTML tags such as
c3po的首要任务是插入iframe。 它寻找HTML标记,例如
<div class="fb-like" data-href="http://phpied.com"></div>
Similar tags are generated by each provider's "wizard" configuration tools.
每个提供商的“向导”配置工具都会生成类似的标签。
In place of this tag, there should be an iframe, so the result (generated html) after c3po's parsing should roughly be like:
代替此标记,应该有一个iframe,因此c3po解析后的结果(生成的html)应该大致类似于:
<div class="fb-like" data-href="http://phpied.com">
<iframe
src="http://facebook.com/plugins/like.php?href=http://phpied.com">
</iframe>
</div>
The way to do this across providers is to just have every data-
attribute passed as a parameter to the 3rd party URL.
跨提供程序执行此操作的方法是仅将每个data-
属性作为参数传递给第三方URL。
Third parties can be setup using a register()
method:
可以使用register()
方法设置第三方:
// FB
c3po.register({
'fb-like':
'https://www.facebook.com/plugins/like.php?',
'fb-send':
'https://www.facebook.com/plugins/send.php?',
});
// Tw
c3po.register({
'twitter-share-button':
'https://platform.twitter.com/widgets/tweet_button.html#'
});
// ...
The only additional parameter passed to the third party URL is cpo-guid=...
, a unique ID so that the iframe can identify itself when requesting services.
传递给第三方URL的唯一附加参数是cpo-guid=...
,这是唯一的ID,以便iframe在请求服务时可以标识自己。
The parsing and inserting frames works today, as the demo shows. The only problem is you don't know how big the iframes should be. You can guess, but you'll be wrong, given i18n labels and different layouts for the widgets. It's best if the widget tells you (tells c3po) how big it should be by sending a message to it.
如演示所示,现在可以使用解析和插入帧。 唯一的问题是您不知道iframe应该多大。 您可以猜测,但鉴于i18n标签和小部件的不同布局,您会错了。 最好是该小部件通过向其发送消息来告诉您(告诉c3po)应该有多大。
X域消息传递 (X-domain messaging)
What we need here is the iframe hosted on the provider's domain to communicate with the page (and c3po script) hosted on your page. X-domain messaging is hard, it requires different methods for browsers and I'm not even going to pretend I know how it works. But, if the browser supports postMessage
, it becomes pretty easy. At the time of writing 94.42% of the browsers support it. Should we let the other 5% drag us down? I'd say No!
这里我们需要的是托管在提供者域上的iframe,以便与您网页上托管的页面(和c3po脚本)进行通信。 X域消息传递很难,它需要针对浏览器的不同方法,我什至不假装我知道它是如何工作的。 但是,如果浏览器支持postMessage
,它将变得非常容易。 在撰写本文时,有94.42%的浏览器支持它。 我们应该让其他5%拖累我们吗? 我会说不!
c3po is meant to only work in the browsers that support postMessage, which means for IE7 and below, the implementers can resort to the old way of including all providers' JS. Or just have less-than-ideally-resized widgets with reasonable defaults.
c3po只能在支持postMessage的浏览器中工作,这意味着对于IE7及更低版本,实现者可以采用包括所有提供商的JS的旧方法。 或者只是具有不理想大小的小部件以及合理的默认值。
When the widget wants something, it should send a message, e.g.
当小部件需要某些东西时,它应该发送一条消息,例如
var msg = JSON.stringify({
type: 'resize',
guid: '2c23263549d648000',
width: 200,
height: 300
});
parent && parent.postMessage(msg, '*');
See the example widget for some working code.
有关一些工作代码,请参见示例小部件。
The c3po code that handles the message will check the GUID and the origin of the message and if all checks out it will do something with the iframe, e.g. resize it.
处理该消息的c3po代码将检查GUID和消息的来源,并且如果全部签出,它将对iframe进行某些操作,例如调整其大小。
Again, take a look at the demo code to see how it all clicks together
再次查看演示代码,看看它们如何一起单击
下一个?(Next?)
As you see in the demo, only the example widget is resized properly. This is because it's the only one that sends messages that make sense to c3po.
如您在演示中所见,只有示例窗口小部件的大小正确调整了。 这是因为它是唯一向c3po发送有意义的消息的消息。
Next step will be to have all widget providers agree on the messages and we're good to go! The ultimate benefit: one JS for all your widget-y needs. One JS you can package with your own code and have virtually 0 cost during initial load. And when you're ready: c3po.parse()
and voila! - widgets appear.
下一步将是让所有窗口小部件提供程序都同意消息,我们很乐意! 最终的好处:一个JS可以满足您所有的小部件需求。 您可以使用自己的代码打包一个JS,在初始加载期间的成本实际上为0。 当您准备就绪时: c3po.parse()
和瞧! -小部件出现。
Of course, this is just a draft for c3po, I'm surely missing a lot of things, but the idea is to have soemthing to start the dialogue and have this developed in the open. Here's the github repo for your forking pleasure.
当然,这只是c3po的草稿,我肯定会遗漏很多东西,但是其想法是要有一些东西来开始对话并公开进行开发。 这是供您欣赏的github回购。
Make sense? Let's talk.
有道理? 说吧
Tell your friends about this post on Facebook and Twitter
在Facebook和Twitter上告诉您的朋友有关此帖子的信息