Versnel je Calendly-integratie

Embed Calendly zonder de Core Web Vitals te vertragen

Arjen Karel
Bijgewerkt · 4 min lezen
Delen

Versnel je Calendly-integratie

Calendly is geweldige software voor online afspraken! Calendly integreert met je werkagenda en laat anderen direct afspraken met je inplannen. Veel van mijn klanten gebruiken Calendly en het werkt prima!

Laatst gecontroleerd door Arjen Karel in maart 2026

Calendly integreren op je website

Er zijn grofweg 3 manieren om Calendly op je website te integreren: via een iframe, via een klikbare link of via een knop. Het proces is simpel: klik op de embed-code, kopieer deze en plak de code in je website. Klaar, Calendly staat nu op je pagina. Maar het is niet alleen rozengeur en maneschijn, want je hebt mogelijk ook je website vertraagd.

Hoe vertraagt Calendly je Core Web Vitals?

Bij een inline embed voegt Calendly een iframe toe aan je site. Doe je dit goed, dan worden de paint-metrics (Largest Contentful Paint en First Contentful Paint) nauwelijks beïnvloed door Calendly als iframe te integreren. Het iframe heeft wel wat invloed op de Interaction to Next Paint, maar voor de meeste use cases is dat acceptabel.

Het 'probleem' met de Core Web Vitals ontstaat zodra je Calendly toevoegt via een Popup widget of een Popup text. In de code die je krijgt moet je een stylesheet (https://assets.calendly.com/assets/external/widget.css) en een script (https://assets.calendly.com/assets/external/widget.js) aan je site toevoegen.

<!-- Calendly badge widget begin -->
<link
 href="https://assets.calendly.com/assets/external/widget.css"
 rel="stylesheet">
<script
  src="https://assets.calendly.com/assets/external/widget.js"
  type="text/javascript"
  async>
</script>
<a href="#"
   onclick="Calendly.initPopupWidget(
      {url: 'https://calendly.com/corewebvitals/pre-audit-meet'});
   return false;">
   Schedule time with me
</a>
<!-- Calendly badge widget end -->

Het resultaat: een flinke vertraging van 370 ms door de Calendly-stylesheet. Uit de Calendly-audit van DebugBear blijkt dat de widget-CSS 464 KB groot is, grotendeels door embedded Base64-fonts. Dit gebeurt omdat stylesheets in de head van de pagina standaard render-blocking zijn. Dat is logisch: zonder de styles weet de browser niet hoe de uiteindelijke HTML eruit moet zien. Daarom zijn geoptimaliseerde stylesheets zo belangrijk als je aan de Core Web Vitals werkt.

Het async script concurreert ook om vroege resources. Maar omdat dat script asynchroon is, is de vertraging die het veroorzaakt veel kleiner dan die van de stylesheet.

De oplossing

De oplossing zit in 'Calendly non-render-blocking maken' en als bonus 'de timing verbeteren'. Dit kan op een makkelijke en op een iets lastigere (en betere) manier. Aan de slag!

De makkelijke fix

De makkelijkste manier is om de stylesheet non-render-blocking te maken met de 'preload-truc'. Kijk maar naar de wijzigingen in de code in het vet. De stylesheet wordt nu gepreload (en gepreloade resources worden parallel gedownload). Is de stylesheet eenmaal geladen, dan verandert de preload-link in een stylesheet-link. Zo injecteer je effectief een stylesheet die niet render-blocking is!

<!-- Calendly badge widget begin -->
<link
 href="https://assets.calendly.com/assets/external/widget.css"
 rel="preload"
 as="style"
 onload="this.rel='stylesheet';this.onload=null;"
>
<script
  src="https://assets.calendly.com/assets/external/widget.js"
  type="text/javascript"
  async>
</script>
<a href="#"
   onclick="Calendly.initPopupWidget(
      {url: 'https://calendly.com/corewebvitals/pre-audit-meet'});
   return false;">
   Schedule time with me
</a>
<!-- Calendly badge widget end -->

De betere fix

De makkelijke fix verbetert je paint-metrics zeker, maar ik ben nog steeds niet blij met de timing van Calendly. Niemand in de geschiedenis van het internet heeft zich er ooit aan gestoord dat je binnen de eerste 100 ms van de pageload geen afspraak kon inplannen. Ik geef liever prioriteit aan belangrijkere onderdelen van de pagina, zoals het LCP-element en kritieke scripts die bijvoorbeeld het menu aansturen. Dit is hetzelfde facade pattern dat ik gebruik voor chat widgets.

Met die kennis gaan we zowel het script als de style pas laden zodra de HTML van de pagina is geparsed. Dit event heet DOMContentLoaded. Zodra dit event afgaat, gebruiken we die tijd om de style en het script asynchroon te laden. Zijn zowel de style als het script geladen, dan maken we (in de callback-functie) een klikbare link die de popup toont zodra je erop klikt. Mooi toch? Voor meer van dit soort technieken, zie 16 methoden om JavaScript uit te stellen.

De code gebruikt ook scheduler.yield() om te yielden naar de main thread voordat de popup opent. Dit houdt de interactie responsief en voorkomt dat de browser blokkeert terwijl Calendly initialiseert.

document.addEventListener('DOMContentLoaded', function () {

    var stylesheetPromise = new Promise(function (resolve, reject) {
        var stylesheet = document.createElement('link');
        stylesheet.rel = 'stylesheet';
        stylesheet.href = 'https://assets.calendly.com/assets/external/widget.css';
        stylesheet.onload = resolve;
        stylesheet.onerror = reject;
        document.head.appendChild(stylesheet);
    });

    var scriptPromise = new Promise(function (resolve, reject) {
        var script = document.createElement('script');
        script.src = 'https://assets.calendly.com/assets/external/widget.js';
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
    });

    async function yieldToMainThread() {
        if ('scheduler' in window && 'yield' in window.scheduler) {
          return await window.scheduler.yield();
        }
        return new Promise((resolve) => {
          setTimeout(resolve, 0);
        });
      }

    Promise.all([stylesheetPromise, scriptPromise])
        .then(function () {
            const clickEl = document.getElementById('demo');
            clickEl.innerHTML = '<a>Book a Demo</a>';
            document.getElementById('demo').addEventListener('click', async function () {
                this.innerHTML = 'Loading...';
                await yieldToMainThread();
                Calendly.initPopupWidget({ url: 'https://calendly.com/corewebvitals/pre-audit-meet' }); return false;
            });
        })
        .catch(function (error) {
            console.error('Error loading resources:', error);
        });
});

Demo

Bekijk de demo hier door op de onderstaande link te klikken (en heb je een audit nodig, plan dan gerust een afspraak)

Boek een demo

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

Arjen Karel

Een snellere site nodig?

Ik ben Arjen en ik maak al 17 jaar trage sites snel. Loop je tegen iets aan dat je zelf niet opgelost krijgt? Stuur me je URL, dan praten we even.

Stuur me je URL
Arjen Karel
Arjen Karel, Web performance consultant sinds 2009

Waarom werkt onze fix niet?

Soms serveert het CDN nog de oude HTML, of de fix zit in het desktop-template terwijl mobiel een ander template gebruikt. Stuur me je URL en het probleem, dan stuur ik je een paar momenten. Ik bekijk eerst je field data, daarna besteden we een uur aan je site, en binnen een dag heb je mijn notities op schrift. €350 excl. btw.

Stuur me je URL

Geen developer om de fix te bouwen? Ik doe het werk zelf, op een kopie van je site.