KonstantinCodes / mautic-recaptcha

This Plugin brings reCAPTCHA integration to mautic.
GNU General Public License v3.0
51 stars 31 forks source link

Pre-loading reCaptcha slows down site performance #22

Open r-martins opened 4 years ago

r-martins commented 4 years ago

Hi Konstantin. First of all thanks for this great work. It saved us from indefatigable spam bots.

I'm wondering if we can find a way to load reCaptcha on demand. I have a site where I have a sign in form in all fages, and now I'm loading reCaptcha. It slowed down the page speed in all page metrics due to multiple requests and recaptcha css.

Do you know if/how we can implement one of these solutions here?

https://stackoverflow.com/questions/35245768/load-recaptcha-dynamically

Thanks in advance.

r-martins commented 4 years ago

Following the example, I did a workaround with your module in the following way...

  1. I inserted the form that contains reCaptcha via Manual way (instead of inserting JS)
  2. Added an id property to <div class="g-recaptcha" id="captcha_container"
  3. Commented the recaptcha/api.js inclusion and added it in the following way:
<!--    <script src="https://www.google.com/recaptcha/api.js"></script>-->
    <script type="text/javascript">
        jQuery(document).ready(function (jQuery) {
                jQuery.getScript("https://www.google.com/recaptcha/api.js?render=6LemGHsUAAAAAITFL13bw0ujJQuIFSpPsEbo3St7")
                    .done(function (script, textStatus) {
                        if (typeof grecaptcha !== "undefined") {
                            grecaptcha.ready(function () {
                                var siteKey = '6LemGHsUAAAAAITFL13bw0ujJQuIFSpPsEbo3St7';
                                jQuery('#mauticform_input_novidadesmagenteirocomlivromagenteirosite_email').click(function() {
                                    jQuery('body').append(jQuery('<div id="captcha_container" class="google-cpatcha"></div>'));
                                    setTimeout(function() {
                                        grecaptcha.render('captcha_container', {
                                            'sitekey': siteKey
                                        });
                                    }, 1000);
                                });
                            });
                        }
                    });
        });
    </script>

I'm not sure if it's the best way, but now:

  1. The reCaptcha is loaded after dom ready
  2. The "I'm not a robot" and all of it's dependencies are only triggered and displayed after clicking in the email field.
  3. Now I have 42 requests in my page, instead of 62 requests I had before, before user clicking in the email field to subscribe.

The thing is how to implement it in the same way inside the module.

r-martins commented 4 years ago

Update: I just improved my method a little bit more. So now everything is loaded only when the input field is focused. So far, it's perfect. I just would like to know better how to customize this in your plugin, so I could make a contribution. So far, here is what I've done:

    <script type="text/javascript">
        jQuery('#mauticform_input_novidadesmagenteirocomlivromagenteirosite_email').focus(function () {
                if(typeof loadedRecaptcha != 'undefined'){
                    return;
                }
                jQuery.getScript("https://www.google.com/recaptcha/api.js?render=6LemGHsUAAAAAITFL13bw0ujJQuIFSpPsEbo3St7")
                    .done(function (script, textStatus) {
                        if (typeof grecaptcha !== "undefined") {
                            grecaptcha.ready(function () {
                            var siteKey = '6LemGHsUAAAAAITFL13bw0ujJQuIFSpPsEbo3St7';
                                jQuery('body').append(jQuery('<div id="captcha_container" class="google-cpatcha"></div>'));
                                setTimeout(function() {
                                    grecaptcha.render('captcha_container', {
                                        'sitekey': siteKey
                                    });
                                }, 1000);
                            });
                        }
                        loadedRecaptcha = true;
                    });
        });
    </script>

Just need to keep in mind everything else I said in the previous comment. And here's the result:

example