Live Demo 👉 All Demo, No Pitch: Content & Commerce / Builder.io & Elastic Path on 12/13
Use Cases
Pricing
Blog
×
Visual CMS
Drag-and-drop visual editor and headless CMS for any tech stack
Theme Studio for Shopify
Build and optimize your Shopify-hosted storefront, no coding required
Resources
Blog
Get StartedLogin☰
You have a great product, and your users are raving about it on Twitter. You want to use the social proof on your page to tell new users how awesome you are. Let's embed some tweets into your site! Twitter makes this easy! Click the tree dots context menu and select Embed Tweet
, then follow the instructions. Twitter gives you a code snipped, which you embed into your page and success! You have a tweet embedded on your page.
We don't give embedding a tweet onto our site much thought, but it turns out that that tweet is quite expensive from a performance perspective. To show you just how expensive that embed is, we have embedded a single tweet and then four tweets into a blank page and asked Google PageSpeed to rank the quality of our site. To make sure that we are measuring just the cost of the embedded tweet, the page we are testing is otherwise blank.
To our surprise, the results are not great!
Here are some highlights of the bad experience people will get on low-powered mobile devices:
Keep in mind this is on the blank page. The situation will get worse as the page becomes more complex with more third-party scripts.
The thing to observe is that the Tweet Embed solution is JavaScript-heavy and requires a lot of JavaScript execution to render the tweet. The more JavaScript on startup, the slower your site.
The natural question is to ask, why is this so expensive? Why does Twitter not care about its users and the end-user experience? Well, it is easy to blame Twitter engineers but let's have some empathy for the engineer that designed this system. They were probably under time pressure to deliver, and so they chose the path of least resistance to deliver the Tweet embed feature.
The Tweet embed is a standard stand-alone application that gets loaded in an iframe. (One iframe per tweet) The application is CSR (client-side rendered) SPA (single page application) written in React. React is a well-tested and loved technology by developers, so the fact that the Twitter engineer chose it for the tweet implementation is unsurprising.
The Twitter engineers could have chosen other rendering technologies, but it would not have significantly impacted the outcome. We have compared a movie app written in seven different frameworks, and the result was mostly the same for all CSR applications. The main winners were the HTML-first frameworks such as Astro and Qwik because those deliver primarily HTML rather than JavaScript — more on that later.
At this point, stepping back and seeing the big picture is important. A single tweet has lowered our site score to 69. Four tweets to 39! But this is but one third-party script. Google reports that an average site has 23 different third-party scripts! So this is but one of many more scripts to be embedded into your site. If one third-party script fares so badly, what do you think a site with 23 different third-party scripts will do? There is just no hope that the site will perform well. The site will have a bad user experience, and people will leave.
It is paramount that we, as site developers, pay attention to third-party scripts and do a better job shielding ourselves from their consequences.
The big realization is that each third-party script is yet another application on your site besides your application. We do things to optimize our application, such as SSR (server-side render)/SSG(static site generation), so why don't third-party scripts do that as well?
Third-party scripts are primarily concerned with the ease of embedding. The primary goal for the Twitter embed is easy embedding for the site developer. When the site developer recognizes that the embed has destroyed the site’s performance, it is too late, and they are unlikely to do much about that. See [3 people problem] later in this article. Because ease of embedding is a priority, the most straightforward thing to do is to cut and paste a JavaScript tag into your site. The CSR (Client Side Rendering) approach will work with any existing solution you use for the site because all the work is done on the client rather than on the server. But precisely, this do-all-work-on-the-client shortcut makes embedding easy. However, the performance of the third-party scripts is poor.
What we need is a way to embed third-party applications in a cut-and-paste way that actually renders using SSR/SSG (rather than CSR). The problem is that most of our frameworks/libraries are CSR-centric, with SSR as an add-on using meta-frameworks. Notable exceptions are Astro and Qwik, which focus on SSR/SSG as a primary delivery mechanism.
Once you dig into site performance for long enough, you realize it all comes down to JavaScript. Actually, it is three things, but two of them have a well-understood solution, so we are left with JavaScript.
To make your site fast, it needs three things:
Most meta-frameworks can do SSR/SSG, so they can send HTML to the client. Meta-frameworks also have good support for Image and CSS optimization. It is not an automatically solved problem, but with a little bit of work on the developer's side, the HTML, Image, and CSS are well-understood problems with well-understood solutions. So if a site fails to deliver on these, it really comes down to the site developer not doing their job or not being aware of how to do it.
The remaining problem is executing less JavaScript on startup. We don't have good solutions for sending less JavaScript to the client. That is because most meta-frameworks and frameworks use hydration to recover their state, which results in too much JavaScript execution on the client. That is why solutions such as Astro, Eleventy, and Qwik are becoming more popular because they are focusing on addressing the JavaScript problem.
So the Twitter engineer implementing the Twitter embed fell into the JavaScript problem because most of our solutions are JavaScript-centric.
To get good performance, third-party scripts need to send HTML and delay the execution of JavaScript for as long as possible. When the site starts up, there is always some amount of JavaScript that needs to run on the main thread, which is the bottleneck. Unfortunately, third-party scripts' current status quo is that each adds even more JavaScript to the startup cost. Some tools such as Partytown try to help with this, but overall this is not a solved problem. Third-party script providers should strive to improve.
But remember that third-party providers are really just packaging their applications into an easily embeddable script tag. They themselves usually use existing frameworks/libraries. These frameworks/libraries are CSR-centric with limited ability to do SSR and delay hydration. So while it is easy to blame third parties for slow site startup performance, in the end, the third parties rely on the same frameworks/libraries as we all do, and most of these frameworks are not focused on minimizing the amount of JavaScript at startup.
In the end, third-party providers don't provide HTML-first solutions because, as an industry, we don't have good HTML-first frameworks to use to deliver those solutions. Sure we have Astro and Eleventy, but these frameworks are more meant for static site generation rather than interactive application delivery.
Let's build the same solution with an HTML-first approach.
What we are trying to do is to do a client-side include of HTML.
Ideally, we want this:
Unfortunately, HTML does not have an <include>
tag, so we are cheating with a bit of JavaScript.
Where the https://qwik-twitter.builder.io/tweet/1606438382561026049.js
returns:
The above is HTML wrapped as JavaScript, with very little actual JavaScript.
The above code allows us to achieve two things:
So there are many frameworks that can do SSR/SSG and hence generate HTML for the client. But most of them come with hydration costs. So for our example, we have chosen Qwik because it uses resumability instead of hydration to make the application interactive. Astro would have also been a good choice because it delays the hydration cost until the island is ready. Anything which does not add JavaScript on startup and produces HTML would have been a great choice.
The nice thing about Qwik is that you get to write your application in a familiar React-like style, but Qwik automatically generates HTML and delays the loading of JavaScript until it is needed (the same application written with React, as we see in Twitter embedded in the example above, results in a lot of JavaScript on startup).
Let's examine the performance improvements with the new approach.
WOW! That’s quite a difference! As you can tell from the above, embedding HTML (even if wrapped in JavaScript) has almost no impact on the startup performance of your site! Even adding multiple tweets does not negatively impact the startup's performance. The only minor negative impact is from CLS (Commutative Layout Shift), which is due to serving images without size information, something that should be a straightforward fix.
The key thing to notice is that all of this is driven by the amount of JavaScript which needs to execute. By reducing the amount of JavaScript, the page became performant. The hard part is not knowing that JavaScript needs to be reduced but knowing how to use existing tools to deliver a minimal amount of JavaScript. This requires a paradigm shift.
If your site uses Twitter Embed and you would like to try this approach, you can do so here: https://qwik-twitter.builder.io/.
Tweet URL
and submit.JS only
is by far the smallest amount of code to paste, but it means that the end user will first see a page without a tweet, and a fraction of a second later, the tweet will show up. This has several shortcomings. The small delay will negatively impact the CLS, and the lack of content will prevent the search engine from indexing the tweet content.HTML + JS
includes HTML in addition to JavaScript. While this tweet will still have a flash of unstyled content, it does have the content, which means the search engine will correctly index it.HTML + JS + CSS
is the best way to inline the content so that there is no flash of unstyled content and the search engine can index it. The JS on end can update the tweet reply, retweets, and favorite stats once it executes.Any system which is not a closed loop will go out of sync. The best systems are such that there is a feedback loop that self-corrects. In the case of a third-party ecosystem, there are three separate people involved and very little feedback between them.
The problem is that the person feeling the slowness is the end user. The person who can do something about it is the third-party developer, but they are not feeling the problem. The first-party developer is aware of the problem but needs the value of the third-party script, so they keep using it as there are few alternatives.
The above creates very little incentive for the problem to get fixed. Add to it the realization that the third-party developer needs better tools for creating the third-party code in an HTML-first manner, and we have a bit of a stalemate in the industry.
So what can we do to improve this?
Average sites have 23 third-party scripts. We add these scripts because they provide value for our sites, whether as social proof or insights into user behavior. To make the scripts easy to embed, they are usually written as CSR (client-side rendered) applications. CSRs come with high startup cost, which is often hidden from the site developer. Most of these third-party scripts are written as CSR applications, meaning they are JavaScript-heavy and need to execute on startup, negatively impacting our site. Multiply this by 23 scripts per page, and the site has little hope of being fast, let alone “blazingly™ fast”.
There is an alternative way to provide value. Instead of CSR, we need HTML-first third-party scripts that delay JavaScript for as long as possible. Such third-party scripts are possible, but they require different kinds of approaches to the problem. This requires support from tools and educating developers. We need to make sure that the easy way to build a site or third-party scripts is also the performant way to build it.
Builder.io is a Visual CMS that let's you drag and drop to create content on your site visually, using your components.
Stop drowning in a backlog of requests - build with your whole team instead.