Skip to content

Instantly share code, notes, and snippets.

@subzey
Last active April 11, 2016 21:38
Show Gist options
  • Select an option

  • Save subzey/7354f356e31a3db6efe13cab04d141c8 to your computer and use it in GitHub Desktop.

Select an option

Save subzey/7354f356e31a3db6efe13cab04d141c8 to your computer and use it in GitHub Desktop.
RND.JS transcript

Here's an english transcript of my talk on RND.JS

Slide

On the slide: "Inserting like Google"

Today I'm going to talk about the embeds. It is when the page contains parts included from the third-party website.

Slide

On the slide: Weather forecast informer

You've seen the embeds before. It can be something useful...

Slide

On the slide: "Have you notice a cat rubs you? There's a reason! Curious facts"

...or nasty ads...

Slide

On the slide: "The scientists proved: The Earth consists of two planets..."

...or ads...

Slide

On the slide: "Cheap iPhone replica! / You're the winner!"

...More ads!

Slide

On the slide: Rambler Top 100 counter

Or something that makes no difference for the user, but is useful for the website admin.

Slide

Every vendor tells their code is easy to embed. A 5 y.o. child can do that and everything would be just fine.

Slide

On the slide: "Embeds" -> "Troubles". A reference to a Soviet cartoon.

But it's not always just fine. Sometimes the embeds are troubles. Let's see what bad can happen.

Slide

Polluting the global scope.

Slide

An actual code that AddThis service runs on a page. It's questionable, should the embed polyfill something or not. But if it is, it should at least do it right. AddThis code doesn't check if the browser already have .bind method.

Slide

Polluting the markup.

Slide

This is a code from GetSatifaction. If you press the button to the left, the popup appears. The popup can be called programmatically, without the button. But the button... You got it, it cannot be hidden.

Slide

Well. It can be hidden. But this selector is obscure. And we even accidentally removed it once.

Slide

Slow loading.

Slide

Here's a typical embed code, a script tag inserted into head that loads the library. And that lib is used somewhere later on the page.

This script is synchronous (blocking). And it's HTTPS. Because security and stuff.

Slide

But SSL handshake is 5-way. Imagine he have a 40 ms ping. Including domain name resolve it turns out that after 120 ms we even didn't send the request headers yet. And rest of the page waits this process to end.

Slide

  • And what if we place this script tag just before the closing body tag?

Slide

Good point. But DOMContentLoaded event is still delayed. And sometimes DOMContentLoaded is not the end of loading, but only the beginning.

Slide

Slow runtime.

Slide

Setting Flash banners aside, there's something that may slow down the page. For example, Qbaka, a JS error reporter. In order to intercept errors it had to pacth the setTimeout, requestAnimation, etc.

As a result, 5..7% of perfomance improvement after the code was removed.

Slide

So. We don't want embeds to stall the page and to pollute it. the same as we want from any script.

Slide

On the slide: "Telemetry".

Let's talk about real world examples. About something that monitors the page and sends info to the server. I'll call this a telemetry.

Slide

Yandex-metrika.

Slide

Here's how their code looked like few years ago. Blocking HTTPS script. Just as I've mentioned above.

Slide

But eventually smart Yandex guys noticed that and decided to use async scripts.

Slide

But the problem with async script is that you cannot tell when exactly it has been loaded. So we should use $.load (an example from the official docs!) to track an event. Becuase if the page was loaded entirely, the async code was loaded for sure.

Slide

Okay. What Google guys did instead.

Slide

Again, this code was used few years ago. They insert an async script as well.

Slide

And in order to track an event you just call a push method of a global object named underscore-gaq passing an array with first value set to underscore-track-event.

Slide

What the?

Slide

But hey! It's actually convenient! Before the async code is loaded, by _gaq.push we just add new item to the array.

Slide

Then the script loads, grabs the contents of that array and pushes it to the server.

Slide

At the same time, window._gaq becomes an object with method "push"...

Slide

...that sends the data immediately.

Slide

On the slide: "First, code is used, and then it is loaded."

So we use same invocation before the script loads and after that.

Slide

And it's worth mentioning modern GA API offers ga() instead of _gaq.push(). It looks better, but it's essentially the same under the hood.

Slide

On the slide: "Widgets".

Let's talk about that is visible to the user. I mean, widgets of all kinds.

Slide

On the slide: "Dynamically generated images"

The oldest way to embed stuff...

Slide

On the slide: I own my for ... years / I'm pregnant for ... days.

...still alive. Pros: It's bullet-proof; virtually any browser from any dumpster can display images. Cons: It's not interactive. And the server load for generating the image is higher that fro generating text. You can generate images that are text, though: SVG.

Slide

Iframes. Just point its src to the specific URL and voila!

Slide

Here's an example. They can be interactive. But only within their sandboxes, not interacting with the host page. It's good for the payment forms, but bad for anything else. You cannot even dynamically resize the iframe element. So if you're providing the width and height attributes in an embed code example, it's forever.

Slide

Can't we instead generate the markup using JS? We can. The docwrite is the easiest way. But the docwrite is evil.

Slide

Not that kind of evil.

Slide

It's this kind of evil: like, c'mon, dude, just use dowrite, try it! It breaks all the abstractions. It works only in sync scripts. Until few years ago browsers even didn't start to download resources later in the document, because docwriting <plaintext> tag would mess up anything.

Slide

Usually, docwrite is used by ads makers. But here's what I've found on vk.com! It's a pure legacy: windows-1251, comments inside script tag, and docwrite of course.

Slide

You may not believe me, but I have a notarized screenshot! (Reference to a russian meme.)

Slide

Moving on. A div with certain id telling where the script should render.

Slide

Here's an example, again, vk.com. We at TradingView have the same embedding method.

Slide

And guess what. Not all our users are happy. And this happens mostly because they forget to actually create a div with the required id. And if they need two widgets on a page, things are getting worse.

Slide

Partially this problem can be solved by using classes.

Slide

Like on this Twitter embed code. thoses classes are hardcoded and connot be overriden by the user.

Also, notice that the like will work even with disabled JavaScript.

But: we still cannot insert those buttons asynchronously. If the link is not in the document at the time script works, it would not be converted to a button.

Slide

There's something that also identifies the script related stuff: the src attribute. I saw this technique on Google Plus button.

Slide

The embed code looks like this. Plain and simple. The script just replaces its own element with button.

Slide

And it can be inserted asynchronously as well.

Slide

On the slide: "In depth"

Let's get a closer look.

Slide

On the slide: "How to find yourself"

How the script should find itself? Bad news: It's hard to get the exact element in the document that represents the currently running script.

Good news: We don't need that.

Slide

All we have to do is to get all the scripts...

Slide

...filter out only those with matching sources...

Slide

...and replace it. In one pass. If there's several matching scripts in the document, first pass will replace all entries. The other calls would just do nothing.

Slide

On the slide: "Configuration"

It's nice when there's a simple unconfigurable button. But what if we have to use settings?

Slide

We can use GET params. Bad idea. The browser cache would not work well.

Slide

Hash params? It's good for iframes, but for the script we have something better.

Slide

Data attributes. Once we have a reference to a script element, we can read its attributes.

Slide

Or - the magic. If the script has src attribute, its content is not executed. But it still can be read! So we can place a JSON here.

Slide

Or YAML.

Slide

Or anything at all.

Slide

For example, LaTeX formulas. Those could just be replaced with images.

Slide

On the slide: "Show me the code!"

And I actually made the demo that does exacly so. For this meetup.

Slide

On the slide: "Conclusion"

Time to wrap up. In conclusion let's just recall that if you're going to write an embed code...

Slide

...do not be a slowpoke, do not shit up the place...

Slide

...do not make your users feel like an idiot.

Slide

Make them feel happy!

Slide

Thank you!

Slide

We're hiring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment