Marketo's embed code to load a form is like so:
<script>MktoForms2.loadForm("//app-sj03.marketo.com", "XXX-XXX-XXX", XXXX);</script>
The forms2.min.js file is a massive 164KB and since the script is not asynchronous, the rest of the web page will be blocked while the browser
downloads the 164KB file. This results in the user seeing a blank white page for a few seconds.
Is there an asynchronous script for loading forms or another more performant way to load a form?
It's 56KB on the wire, not 164KB. This would only take a few seconds on a 2G network or specifically spotty connection. Even on 3G it should be < 1s.
But there's no technical reason why you can't load the library asynchronously, as long as you understand that loadForm is dependent on the library. For practical reasons, this isn't typically done: the form is the most important interactive part of a Landing Page, the form descriptor is always loaded asynchronously, and the page will not be useful from a CTA perspective until the form is available.
Thanks for your reply.
On a landing page, where the form is the main CTA and primary content, perhaps a non asynchronous script is acceptable.
But for the case where you have a Marketo form in the footer on a page with a lot of other content before the form and that content is more important, it would be great if Marketo could come up with an asynchronous script.
As you have suggested, we have added our own workaround to load the forms2.min.js script asynchronously, then load the form using the loadForm method when the file has been downloaded. In this way, the only part of the page which is blocked until the script finishes loading is the form element itself.
56K still seems like a lot even when loaded from a CDN, but I get that the script bundles a bunch of other libraries like jQuery, Modernizr, YepNope. That's another pain point since we already load two of those libraries anyway, but I get why you do it.
It would also be good if the script was able to be cached by the browser as Google Page Speed Insights flags the script as not having the appropriate headers so that the script isn't cached by the browser and is downloaded each time a page is requested. Maybe that is a false negative?
https://app-sj03.marketo.com/js/forms2/css/forms2-theme-inset.css (expiration not specified)
https://app-sj03.marketo.com/js/forms2/css/forms2.css (expiration not specified)
https://app-sj03.marketo.com/js/forms2/js/forms2.min.js (expiration not specified)
I guess these suggestions are better placed as a feature request. Where is the best place to do that?
Don't see a need for Marketo to develop anything new. As mentioned, you're free to load the Forms 2.0 library (forms2.min.js) async if you ensure all of your Forms API events depend on the injected <script> element's load event. If you're already using an async/dependency loader and managing scripts/tags tightly it's not difficult.
Realize it would be a catastrophic BC break for the default to simply change to async, since every piece of Forms API code in the wild -- extended email validations, advanced form interactions, and so on -- is based on simply putting that code after the <script> that loads the lib. Hundreds of thousands of pages would stop working! It would even be a disaster, albeit on a smaller scale, if an async embed code were officially presented without a humongous disclaimer. Most people rolling out Marketo forms are copy-and-paste developers (that is, not developers) and users would be unduly attracted to the async option regardless of whether their plugins were async-aware.
If there were a bootstrapper that created the MktoForms2 object and maintained a stack of queued functions -- like the Munchkin bootstrapper -- that could be a path to backward-compatible sanity. But that bootstrapper would still either have to load synchronously or be an inline script, and setting up all the stub functions can be very complex with, I think, a slim payoff.
Re: the size, as you noticed, the library has bundled dependencies. I happen to detest jQuery and am all too happy to have it hidden from view (if it is used at all). But I can see why it's annoying to have it loaded twice in your environment, and a jQuery-dependent version without bundled jQuery would be a help. Bear in mind you can access MktoForms2.$ directly if you wish.
Re: cacheability, yes, it's a false negative as the library will be heuristically cached. You can observe this in your Dev Tools.
An optional async parameter documented deep in the API would perhaps be not so catastrophic, but I get that I am not the target audience of your product so I will just shut up now. Thanks for your help.