sepiariver / recaptchav2

Google's ReCaptcha V2 + V3 for MODX CMS: https://sepiariver.com/modx/recaptchav2-supports-recaptchav3/
https://sepiariver.com/
GNU General Public License v2.0
21 stars 15 forks source link

Load recaptcha javascript async? #46

Closed sdrenth closed 5 years ago

sdrenth commented 5 years ago

I think it would be better if the recaptcha javascript would be loaded async so it is non blocking.

Also if I have multiple forms using recaptcha on the same page, the javascript is loaded multiple times, which creates overhead.

I think it would be a great enhancement if both issues would be resolved performance-wise.

ghost commented 5 years ago

I don't know if this is a cure all, but I think this might work hypothetically.

<script
    async
    defer
    type="text/javascript"
    src="https://www.google.com/recaptcha/api.js?hl=[[++cultureKey]]"
    onload="function recaptchaV2SubmitForm(response){return new Promise(function(){document.getElementById('[[+form_id]]').submit();})}">
</script>

Using an IIFE and applying it to a tag that downloads async should fix it right? I included async and defer for support for more browsers. IIFE just does an infinite loop. Moving the function into an onload event in the script tag hasn't caused any issues yet, but I'll keep this posted if I run into anything

sdrenth commented 5 years ago

@connorwilsonexceleron In addition to load the JS async, do you also prevent je javascript from loading multiple times now if the page contains multiple forms?

ghost commented 5 years ago

No, I don't believe it will, I'd have to look more into it. You might be able to make an inline script tag that downloads the grecaptcha.js and then sets a flag. Something like

<script>
window.recaptcha;
window.onload = function() {
    if window.recaptcha return;
    load recaptcha js
    window.recaptcha = true
}
function recaptchaV2SubmitForm(response){
    return new Promise(function(){
        document.getElementById('[[+form_id]]').submit();
    })
}
</script>

if you wanna tackle it yourself, this would give you a headstart. If you want even more control, you can try this manual solution I found a while back. Was the double JS download a big drag on performance, or just trying to reduce HTTP requests and download size? I'm gonna have a similar situation on my hands in the coming months so I'm interested.

ghost commented 5 years ago

I did further testing and making the function in the onload event does not work. It is not accessible as a function to the callback function.

sepiariver commented 5 years ago

You can customize your implementation with the template Chunks to fit whatever use case you require. Thanks @excelerondesign for the great examples.