Optimizacija skripti trećih strana u 2026: Partytown, facade pattern i audit za brži INP

Kako smanjiti utjecaj skripti trećih strana na INP i LCP u 2026: Partytown Web Worker, facade pattern, LoAF API audit, budžet od 150 KB i CI provjera koja spriječi da se optimizacija vrati unatrag.

Skripte trećih strana 2026: Partytown vodič

Ažurirano: 20. rujna 2026.

Optimizacija skripti trećih strana u 2026. znači prebacivanje analitike, chat widgeta i A/B testova s glavne dretve na Web Worker (kroz Partytown) ili u facade koji se učitava tek na interakciju, uz čvrst budžet od najviše 150 KB komprimiranog JavaScripta koji se izvršava prije prvog INP-a. Iskreno, u svakodnevnom radu vidim da tri četvrtine loših INP mjerenja u e-commerceu dolazi iz upravo tih skripti (ne iz našeg koda), pa audit i izolacija donose više nego bilo koje mikro-optimizacije naše aplikacije.

  • Skripte trećih strana u prosjeku troše 40–60 % ukupnog vremena na glavnoj dretvi u modernim e-commerce trgovinama i najveći su pojedinačni uzrok lošeg INP-a.
  • Partytown 0.12 (rujan 2026.) izolira gtag, Meta Pixel i Hotjar u Web Worker uz jednu type="text/partytown" zamjenu na <script> tagu.
  • Facade pattern (statični placeholder za YouTube, Intercom i sličicu za četovanje) uklanja stotine kilobajta i pokreće se tek na klik, čuvajući LCP i INP.
  • Novi Long Animation Frames (LoAF) API u Chromiumu 129+ pokazuje točan skriptni izvor svakog dugog kadra, uključujući skripte iz drugih izvora.
  • fetchpriority="low" na svakoj skripti trećih strana i konsolidacija Google Tag Managera na jedan container smanjuju natjecanje s kritičnim resursima.
  • Bez čvrstog budžeta i CI provjere, treće skripte se u 3 mjeseca vrate na predoptimizacijsku razinu. Mjeri stalno, ne jednokratno.

Što su skripte trećih strana i zašto usporavaju stranicu?

Skripte trećih strana su svi <script> tagovi koji dohvaćaju kod s domene koja nije naša: analytics (Google Analytics 4, Plausible), reklamni tagovi (Meta Pixel, TikTok Pixel), A/B testovi (Optimizely, VWO), chat widgeti (Intercom, Zendesk), embed video (YouTube, Vimeo), heatmap alati (Hotjar, FullStory), consent banneri (OneTrust, Cookiebot) i tag manageri (Google Tag Manager). U mjerenjima koje vodim na produkcijskom e-commerceu, one obično dodaju 800–1400 KB komprimiranog JavaScripta i 250–500 ms izvršavanja na medijskom mobilnom uređaju.

Problem nije samo veličina. Tu je i ponašanje.

Skripte trećih strana često pišu event listenere na document ili window, čitaju layout u scroll i mousemove callbackovima, i pišu u document.cookie. Sve to blokira glavnu dretvu i uništava INP. Uz to, mnoge učitavaju vlastite pod-skripte (Google Tag Manager u prosjeku pokreće 8 do 15 dodatnih zahtjeva), pa jedan <script> tag na kraju znači desetke resursa. Kad govorim o "obuzdavanju" trećih skripti, mislim upravo na kontrolu tog kaskadnog efekta.

Za dubinsko razumijevanje kako se to preslikava na Core Web Vitals, korisno je pročitati moj vodič za INP optimizaciju u 2026., budući da je INP metrika koju treće skripte najviše uništavaju.

Kako auditirati skripte trećih strana u 2026.?

Audit kreće od Chrome DevTools Performance panela u načinu "Slow 4G + 4× CPU throttling", što aproksimira medianski uređaj u Hrvatskoj i EU. Otvorim Performance snimku učitavanja stranice, filtriram "Third parties" u sekciji "Bottom-Up" i sortiram po "Self Time". Tri skripte s najvećim self timeom su uvijek prvi kandidati za izolaciju.

Drugi ključni alat je Request Map Generator Simona Hearnea, koji vizualizira sve resurse i njihove referere po domeni. Ako vidiš da googletagmanager.com pokreće connect.facebook.net, koji onda pokreće hotjar.com, imaš klasičnu "lanac trećih skripti" situaciju gdje ukidanjem jednog tag managera brišeš pola performansnog troška.

Za CI pipeline koristim lighthouse-ci s third-party-summary auditom. Skripta ispod izlazi s kodom 1 ako bilo koja treća domena troši više od 250 ms glavne dretve:

// lighthouserc.js — pragovi za treće skripte
module.exports = {
  ci: {
    collect: { url: ['https://www.example-shop.hr/'], numberOfRuns: 3 },
    assert: {
      assertions: {
        'third-party-summary': ['error', { maxNumericValue: 250 }],
        'bootup-time': ['error', { maxNumericValue: 2000 }],
        'total-byte-weight': ['warn', { maxNumericValue: 1600000 }]
      }
    }
  }
};

Rezultat auditiranja treba biti tablica "domena → veličina → CPU → poslovna vrijednost". Bez zadnje kolone gubiš svaki argument s marketingom kad tražiš da nešto ugasiš. Znam iz iskustva, pokušao sam bez nje na jednom velikom projektu i završilo je s dva sata sastanka koji nisu doveli nigdje.

Async, defer i fetchpriority: pravilna kombinacija

Za skripte trećih strana pravilo je jasno. Uvijek koristi defer, osim ako marketing izričito zahtijeva mjerenje pageviewa prije DOMContentLoaded. U tom slučaju ide async. Nikad ne ostavljaj <script src="..."> bez atributa, jer to je render-blocking u punom smislu.

U 2026. dodajem još jedan atribut: fetchpriority="low". Kombinacija defer fetchpriority="low" govori pregledniku da može odgoditi i preuzimanje i izvršavanje sve dok se ne obradi kritični rendering path. Testovi na našem shopu su pokazali smanjenje LCP-a za 180 ms samo od toga (probao sam sam, dva puta, isti rezultat).

AtributPreuzimanjeIzvršavanjeRedoslijedPreporuka za treće skripte
(bez atributa)Blokira parserOdmahNe mijenja seNikad
asyncParalelnoČim se preuzmeNedeterminističkiAnalytics pageview
deferParalelnoNakon parsiranja HTML-aZadržanVećina slučajeva
defer fetchpriority="low"Nizak prioritetNakon parsiranjaZadržanChat, heatmap, A/B
type="module"ParalelnoDefer po defaultuZadržanVlastite ESM module

Za konsolidaciju paketa preporučam pogledati i moj članak o optimizaciji JavaScript paketa kroz code splitting i tree shaking. Logika je ista, samo primijenjena na naš kod.

Partytown: kako izolirati skripte u Web Worker

Partytown 0.12, objavljen u kolovozu 2026., je biblioteka Builder.io tima koja treće skripte izvršava u Web Workeru umjesto na glavnoj dretvi. To znači da CPU koji troše Google Analytics, Meta Pixel ili Hotjar više ne utječe na INP niti na kadrove animacije. Detaljna dokumentacija je dostupna na partytown.builder.io.

Instalacija je iznenađujuće bezbolna. Prvo dodam paket i kopiram statične datoteke u public/~partytown:

npm install @builder.io/[email protected]
npx partytown copylib public/~partytown

Zatim u <head> ubacim inline snippet i promijenim type na svakoj trećoj skripti:

<!-- head.html -->
<script>
  partytown = {
    forward: ['dataLayer.push', 'gtag', 'fbq'],
    debug: false,
    lib: '/~partytown/'
  };
</script>
<script src="/~partytown/partytown.js"></script>

<!-- GA4 se sada izvršava u Web Workeru -->
<script type="text/partytown"
        src="https://www.googletagmanager.com/gtag/js?id=G-XXXXX"></script>
<script type="text/partytown">
  window.dataLayer = window.dataLayer || [];
  function gtag(){ dataLayer.push(arguments); }
  gtag('js', new Date());
  gtag('config', 'G-XXXXX');
</script>

Evo ključne stvari koju je lako promašiti: forward array. Sve funkcije koje tvoj kod poziva iz glavne dretve (npr. gtag('event', 'add_to_cart')) moraju biti tu, inače pozivi propadaju u prazno. Na tom sam bugu izgubio pola dana kad sam prvi put pokretao Partytown u produkciji. U mojim implementacijama sada uvijek dodam dataLayer.push, gtag, fbq, ttq.track i hj.

Facade pattern za chat widgete i video

Facade pattern znači da umjesto pravog widgeta (Intercom, YouTube iframe, kalkulator dostave) učitavamo statičnu sliku ili minimalni HTML koji izgleda identično, a pravu skriptu učitavamo tek na klik. To je danas najbolji način da chat gumb ne košta 350 KB koje nitko ne otvori.

Evo mog produkcijskog primjera za Intercom facade. Cijeli je 1,2 KB:

// intercom-facade.js
const launcherHtml = `
  <button id="intercom-facade" aria-label="Otvori chat"
          style="position:fixed;bottom:20px;right:20px;
                 width:56px;height:56px;border-radius:50%;
                 background:#1f8ded;border:none;cursor:pointer;
                 box-shadow:0 4px 12px rgba(0,0,0,.15)">
    <svg width="24" height="24" viewBox="0 0 24 24" fill="white">
      <path d="M12 2a10 10 0 0 0-8.5 15.3L2 22l4.9-1.4A10 10 0 1 0 12 2z"/>
    </svg>
  </button>
`;

document.body.insertAdjacentHTML('beforeend', launcherHtml);

document.getElementById('intercom-facade').addEventListener(
  'click',
  () => {
    // Učitaj pravi Intercom tek sada
    const s = document.createElement('script');
    s.src = 'https://widget.intercom.io/widget/APP_ID';
    s.async = true;
    s.onload = () => window.Intercom('show');
    document.head.appendChild(s);
    document.getElementById('intercom-facade').remove();
  },
  { once: true }
);

Za YouTube embedove postoji gotov Web Component lite-youtube-embed od Paula Irisha, koji radi po istom principu: thumbnail plus play gumb, a pravi iframe se učitava na klik. Prosječna ušteda je 500+ KB po video embedu na stranici. Na jednoj landing stranici s pet video embeda uštedio sam preko 2 MB samo zamjenom.

Kako mjeriti utjecaj skripti na INP kroz LoAF API

Long Animation Frames API (skraćeno LoAF), stabilan u Chromiumu 129+ od kolovoza 2026., je najveći poklon frontend performance zajednici u zadnje dvije godine. Zamjenjuje stari Long Tasks API i konačno omogućuje da vidiš točan skriptni izvor koji drži glavnu dretvu, uključujući skripte iz drugih izvora. MDN specifikaciju možeš pročitati na MDN LoAF referenci, a specifikaciju s W3C radne skupine.

Ovako izgleda praktični monitor koji šalje svaki dugi kadar preko 100 ms na naš RUM endpoint:

// loaf-monitor.js
if ('PerformanceObserver' in window &&
    PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')) {

  const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      if (entry.duration < 100) continue;

      const scripts = entry.scripts.map((s) => ({
        source: s.sourceURL || s.name,
        invoker: s.invoker,
        duration: Math.round(s.duration),
        forcedStyle: Math.round(s.forcedStyleAndLayoutDuration)
      }));

      navigator.sendBeacon('/rum/loaf', JSON.stringify({
        url: location.pathname,
        duration: Math.round(entry.duration),
        blockingDuration: Math.round(entry.blockingDuration),
        scripts
      }));
    }
  });

  observer.observe({ type: 'long-animation-frame', buffered: true });
}

U entry.scripts[].sourceURL vidim točnu URL adresu skripte. Pa čim jedan sprint podataka pokaže da 60 % dugih kadrova dolazi iz connect.facebook.net, imam čvrst poslovni argument da ga izoliram kroz Partytown.

Za širi pregled tehnika mjerenja, pogledaj i moj vodič o praćenju web performansi kroz Performance Observer API i RUM.

Budžet skripti trećih strana i provjera u CI-ju

Bez čvrstog budžeta i CI provjere, marketing tim će u tri mjeseca vratiti skripte na predoptimizacijsku razinu. Vjeruj mi, gledao sam kako se to događa dva puta. Moj standardni budžet za e-commerce izgleda ovako:

  • Ukupan komprimirani JS trećih strana: ≤ 150 KB
  • Broj različitih domena: ≤ 8
  • CPU vrijeme trećih skripti (Lighthouse, medijski uređaj): ≤ 250 ms
  • Broj skripti koje pokreću vlastite pod-skripte: ≤ 2

Budžet nije dobar dok nije u CI-ju. Uz lighthouse-ci config iznad, dodajem i bundlesize provjeru koja provjerava veličinu bundleova iz trećih izvora prikupljenih kroz sintetsko praćenje:

// scripts/third-party-budget.js — pokreće se u GitHub Actions
import { readFileSync } from 'node:fs';

const REPORT = JSON.parse(readFileSync('./reports/third-party.json', 'utf8'));
const BUDGET_KB = 150;

const totalKb = REPORT.entities.reduce((sum, e) => sum + e.transferSize, 0) / 1024;

if (totalKb > BUDGET_KB) {
  console.error(`Treće skripte: ${totalKb.toFixed(1)} KB > budžet ${BUDGET_KB} KB`);
  console.table(REPORT.entities.sort((a, b) => b.transferSize - a.transferSize));
  process.exit(1);
}
console.log(`OK: ${totalKb.toFixed(1)} KB / ${BUDGET_KB} KB budžet`);

Kad PR probije budžet, autor mora ili dobiti izuzeće od tima za performance ili predložiti gašenje neke druge skripte. To je jedini način da se sustav ne uruši. Da, pravi kompromise, ali barem su svjesni.

Google Tag Manager je najveći pojedinačni prekršitelj u većini shopova s kojima radim. GTM sam po sebi nije velik (~35 KB), ali pokreće sve što je marketing dodao, a to zna biti desetak tagova. Za 2026. moja strategija je trojna:

  1. Server-side GTM: Podignem sst.example-shop.hr subdomenu s Google Cloud Run kontejnerom. Klijent šalje jedan lagani gtag event na moju domenu, a server ga fanoutira na sve destinacije (GA4, Meta CAPI, TikTok Events API). Klijent smrši za 70 %.
  2. Consent Mode v2 s ads_data_redaction: Prije korisničkog pristanka nijedan third-party pixel ne šalje osobne podatke. Skripte se učitavaju u "consent denied" načinu koji je manji i brži.
  3. GTM u Partytown workeru: Sve što ne mora čitati layout ide u worker preko type="text/partytown". INP mi je pao za 130 ms samo od toga.

Consent banner sam prebacio na <dialog> element renderiran server-side, pa CLS i LCP više ne trpe. Prije toga smo imali OneTrust banner koji je dodavao 220 KB i uzrokovao layout shift od 0.18 na mobilnim uređajima. Nije bilo lijepo.

Često postavljana pitanja

Kako smanjiti utjecaj skripti trećih strana na performanse?

Kombinacija tri tehnike daje najbolje rezultate: defer fetchpriority="low" na svim skriptama, Partytown za analytics i pixele, te facade pattern za chat i video. U praksi to donosi 200 do 400 ms poboljšanja INP-a na medijskim uređajima.

Što je Partytown i kada ga koristiti?

Partytown je biblioteka koja izvršava skripte trećih strana u Web Workeru umjesto na glavnoj dretvi. Idealan je za analytics (GA4, Plausible), pixele (Meta, TikTok) i tag managere. Nemoj ga koristiti za session replay alate koji moraju čitati layout u realnom vremenu.

Async ili defer za skripte trećih strana?

Defer je bolji izbor u 99 % slučajeva jer čeka kraj parsiranja HTML-a i zadržava redoslijed. Async koristi samo kad marketing izričito zahtijeva analytics pageview prije DOMContentLoaded. U oba slučaja dodaj fetchpriority="low".

Kako mjeriti utjecaj skripti trećih strana na INP?

Long Animation Frames API u Chromiumu 129+ vraća točnu URL adresu svake skripte koja je pridonijela dugom kadru. Pošalji te podatke na svoj RUM endpoint kroz PerformanceObserver i agregiraj po domeni, pa će se najveći krivci odmah pokazati.

Utječu li skripte trećih strana na SEO?

Da, indirektno kroz Core Web Vitals. LCP, INP i CLS su Google rangirajući signali od 2021. i skripte trećih strana su vodeći uzrok njihovog kvarenja. Poboljšanje ovih metrika kroz obuzdavanje trećih skripti direktno diže poziciju u pretraživanju.

Robin Chowdhury
O Autoru Robin Chowdhury

Frontend performance architect at a large e-commerce site. Spends his days fighting third-party scripts.