foomo-docs/blog/impact-of-3rd-party-scripts-on-performance.html
2024-06-10 09:44:34 +00:00

62 lines
14 KiB
HTML

<!doctype html>
<html lang="en" dir="ltr" class="blog-wrapper blog-post-page plugin-blog plugin-id-default" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.0.0">
<title data-rh="true">Impact of 3rd party scripts on performance | foomo project docs</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://www.foomo.org/blog/impact-of-3rd-party-scripts-on-performance"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docusaurus_tag" content="default"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docsearch:docusaurus_tag" content="default"><meta data-rh="true" property="og:title" content="Impact of 3rd party scripts on performance | foomo project docs"><meta data-rh="true" name="description" content="Issue with performance"><meta data-rh="true" property="og:description" content="Issue with performance"><meta data-rh="true" property="og:type" content="article"><meta data-rh="true" property="article:published_time" content="2022-01-20T00:00:00.000Z"><meta data-rh="true" property="article:author" content="https://github.com/themre"><meta data-rh="true" property="article:tag" content="frontend,performance"><link data-rh="true" rel="icon" href="/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://www.foomo.org/blog/impact-of-3rd-party-scripts-on-performance"><link data-rh="true" rel="alternate" href="https://www.foomo.org/blog/impact-of-3rd-party-scripts-on-performance" hreflang="en"><link data-rh="true" rel="alternate" href="https://www.foomo.org/blog/impact-of-3rd-party-scripts-on-performance" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://SUATUVZDDM-dsn.algolia.net" crossorigin="anonymous"><link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="foomo project docs RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="foomo project docs Atom Feed">
<link rel="search" type="application/opensearchdescription+xml" title="foomo project docs" href="/opensearch.xml"><link rel="stylesheet" href="/assets/css/styles.78fe5ce6.css">
<script src="/assets/js/runtime~main.638e5c2c.js" defer="defer"></script>
<script src="/assets/js/main.1248442c.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return localStorage.getItem("theme")}catch(t){}}();t(null!==e?e:"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><b class="navbar__title text--truncate">foomo</b></a><a class="navbar__item navbar__link" href="/docs/general">General</a><a class="navbar__item navbar__link" href="/docs/frontend">Frontend</a><a class="navbar__item navbar__link" href="/docs/backend">Backend</a><a class="navbar__item navbar__link" href="/docs/devops">DevOps</a><a class="navbar__item navbar__link" href="/docs/projects">Projects</a></div><div class="navbar__items navbar__items--right"><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/blog">Blog</a><div class="navbarSearchContainer_Bca1"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0"><div class="container margin-vert--lg"><div class="row"><aside class="col col--3"><nav class="sidebar_re4s thin-scrollbar" aria-label="Blog recent posts navigation"><div class="sidebarItemTitle_pO2u margin-bottom--md">Recent posts</div><ul class="sidebarItemList_Yudw clean-list"><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/go-race-conditions-testing-and-coverage">Go race conditions testing and coverage</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/accuracy-of-decimal-computations">Accuracy of decimal computations</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/why-bundle-size-is-important">Why bundle size is important?</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/prometheus-cardinality-issues">Prometheus Is Out Of Memory. Again.</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/searching-for-search-engines">The never ending search a search engine 2022-01 edition</a></li></ul></nav></aside><main class="col col--7" itemscope="" itemtype="https://schema.org/Blog"><article itemprop="blogPost" itemscope="" itemtype="https://schema.org/BlogPosting"><meta itemprop="description" content="Issue with performance"><header><h1 class="title_f1Hy" itemprop="headline">Impact of 3rd party scripts on performance</h1><div class="container_mt6G margin-vert--md"><time datetime="2022-01-20T00:00:00.000Z" itemprop="datePublished">January 20, 2022</time></div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/themre" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://github.com/themre.png" alt="Marko Trebižan" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/themre" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Marko Trebižan</span></a></div><small class="avatar__subtitle" itemprop="description">Frontend Dev</small></div></div></div></div></header><div id="__blog-post-container" class="markdown" itemprop="articleBody"><h2 id="issue-with-performance">Issue with performance</h2>
<p>When building an ecommerce site or an application where performance is a great deal for the users, you need to keep your application fast and responsive. Frontend developers have already many use-cases when the UI becomes laggy and this increases when 3rd party scripts are being included, such as Google Tag Manager or various Live chats (e.g. Intercom).</p>
<p>This does not only influences the users when using the site but also Lighthouse score gets lower which also influences page rankings. So the most naive and easy way for this is to defer loading of such scripts but when you need to get all the data from the start of the application, such tactic is not an option. So what else can we do?</p>
<h2 id="partytown-to-the-rescue">Partytown to the rescue</h2>
<p>Developers at BuilderIO created an library <a href="https://github.com/BuilderIO/partytown">Partytown</a> that would allow relocating resources from 3rd party scripts off the main thread.
We won&#x27;t dive into specifics how it works, because they explain it nicely on their GitHub page.</p>
<p>In our stack we use <a href="https://nextjs.org/">Next.js</a> React framework and we will go through the basic steps that will allow us to include Partytown for Google Tag Manager.</p>
<h3 id="setup">Setup</h3>
<p>Partytown script needs to be located inside our application and live on the same domain. Since we&#x27;re using monorepo structure, we need to copy this script across all our frontend application. For that we used CopyPlugin webpack plugin in our Next.js config file:</p>
<pre><code class="language-javascript">config.plugins.push(
...
new CopyPlugin({
patterns: [
{
// we copy script from node_modules partytown package to `~partytown` folder in our package that serves static files
from: path.join(path.dirname(require.resolve(&#x27;@builder.io/partytown&#x27;)), &#x27;lib&#x27;),
// paths for SSR and client side rendering differ
to: path.join(`${isServer ? &#x27;..&#x27; : &#x27;.&#x27;}/static/assets/`, &#x27;~partytown&#x27;),
},
],
})
);
</code></pre>
<p>Partytown&#x27;s requirement is that it needs to know what script should it load into own web worker. For that we set script type to <code>text/partytown</code>. This will prevent script to load on initial load.</p>
<p>Inside <code>_document.tsx</code> we add this:</p>
<pre><code class="language-javascript">&lt;Head&gt;
...
// include Partytown and set custom path due to multiple frontends
&lt;Partytown lib={`${addTrailingSlash(this.props.basePath)}_next/static/assets/~partytown/`} debug={false} /&gt;
// tag 3rd party script with partytown type
&lt;script type=&quot;text/partytown&quot; src={`https://www.googletagmanager.com/gtm.js?id=${id}`} /&gt;
...
&lt;/Head&gt;
</code></pre>
<h2 id="results">Results</h2>
<p>So now, does it work? We used one of our large Ecommerce sites to test the landing Lighthouse score.</p>
<p>This was before adding Partytown:</p>
<p><img alt="Lighthouse before Partytown" src="/assets/images/lighthouse_before-dc68b4a70a257ec6284efc219a989c7e.jpg" width="800" height="842"></p>
<p>Here you can see 2 critical things: almost 1s of total blocking time (TBT) and 9s of time to interactive (TTI).</p>
<p>After we added Partytown, we got this:</p>
<p><img alt="Lighthouse after Partytown" src="/assets/images/lighthouse_after-252d381900343cee3782f1d9c3e27442.jpg" width="840" height="845"></p>
<p>Time to interactive went from 9s to 6.1s which is almost 33% improvement and total blocking time was reduce by more than 50%! We were more than impressed how easy it was to improve our performances.</p>
<p>Side note: Both screenshots were compressed using <a href="https://squoosh.app/">Squoosh App</a>.</p>
<h1 id="next-steps">Next steps</h1>
<p>After successful testing of Partytown for Google Tag Manager script, we are more than interested in trying it out on our other scripts. One important topic will be to test Partytown with other service-worker related libraries and how to use them together.</p></div><footer class="row docusaurus-mt-lg blogPostFooterDetailsFull_mRVl"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/frontend">frontend</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/performance">performance</a></li></ul></div><div class="col margin-top--sm"><a href="https://github.com/foomo/foomo-docs/tree/main/foomo/blog/2022-01-20-exploring-partytown/index.mdx" target="_blank" rel="noopener noreferrer" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_Z9Sw" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Blog post page navigation"><a class="pagination-nav__link pagination-nav__link--prev" href="/blog/searching-for-search-engines"><div class="pagination-nav__sublabel">Newer Post</div><div class="pagination-nav__label">The never ending search a search engine 2022-01 edition</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/blog/debugging-go-map-races-in-k8s"><div class="pagination-nav__sublabel">Older Post</div><div class="pagination-nav__label">debugging Go map races in k8s</div></a></nav></main><div class="col col--2"><div class="tableOfContents_bqdL thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#issue-with-performance" class="table-of-contents__link toc-highlight">Issue with performance</a></li><li><a href="#partytown-to-the-rescue" class="table-of-contents__link toc-highlight">Partytown to the rescue</a><ul><li><a href="#setup" class="table-of-contents__link toc-highlight">Setup</a></li></ul></li><li><a href="#results" class="table-of-contents__link toc-highlight">Results</a></li></ul></div></div></div></div></div><footer class="footer"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">github</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://github.com/foomo" target="_blank" rel="noopener noreferrer" class="footer__link-item">https://github.com/foomo</a></li></ul></div><div class="col footer__col"><div class="footer__title">legal</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/etc/imprint">Imprint</a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">© 2024 bestbytes</div></div></div></footer></div>
</body>
</html>