Did you know that Google’s reCaptcha anti-spam system SLOWS DOWN all of your websites?
If you don’t know what Lighthouse is check our brief introduction to Lighthouse project.
Google Invisible reCaptcha + Lighthouse Performance Score
Recently, we were working on speed optimization and come to some very interesting findings during our website performance audit. One thing in particular that came as a real shocker was recaptcha__en.js resource that was listed as NO.1 culprit in our JS performance profiling section under Lighthouse audit session ($300 laptop). Over 2 seconds were spent just to evaluate that huge code base (api.js initiates recaptcha__en.js) and little over 50 ms to run it. The later part is not a big deal, but the former one is. Why? Because it affects Time to Interactive parameter in Lighthouse, apparently, and, that is a big deal.
To further verify these findings, we did a ON/OFF A/B testing with/without reCaptcha plugin enabled in WordPress, and it was clear as black on white that it is a big deal, after all. See screenshots below + summarized table with scores.
|1||Google Chrome Browser
Lighthouse Performance Score
|2||Google PageSpeed Insights
The above results are far from ideal, but can you notice (can you?) that single “thing” in form of a reCaptcha library contributing to a huge score penalty? What alternatives we have at our disposal to improve this awkward situation?
Well, for one, we have absolutely no intentions leaving our property unprotected. No, sir! On the other hand, we don’t wish to penalize every user/visitor of our website, who doesn’t want to leave comments or fill-in contact and registration forms, pushing towards it’s browser’s throat all protection stuff completely unnecessary!
Few things comes to mind:
Get rid of reCaptcha for good! Yeah, easier said than done. Good luck with that approach! :)
IDEA #3 – BINGO!
Forget about Ajax splitting, keep things just as they are, and trigger loading/execution/running of reCaptcha library only when user interacts with the input form(s). This is, actually, quite possible and relatively easy to implement!
Let’s do it!
Google reCaptcha Manual Loading On Custom Trigger Event
Ideally, we should trigger Google reCaptcha loading only when users interacts with our forms – e.g. when the form is in focus, or when user starts typing into the forms. While they are typing their nonsense, reCaptcha will silently load in the background in a split of a second, starting it’s protective role on our form(s), but, not before that event!
PART 1: HTML Input Form
HTML – simplest WordPress comment submit form:
<form id="commentform" action="./wp-comments-post.php" method="post"> <input id="author" name="author" type="text" aria-label="author-name" /> <textarea id="comment" name="comment" aria-label="comment-text"></textarea> <input id="submit" class="invisible-recaptcha" name="submit" type="submit" value="Submit" aria-label="submit-comment" /> </form>
PART 2: reCaptcha div holder
This is usually injected by WP plugins, but here it is for completeness:
PART 3: reCaptcha Explicit Render
Important part here is to remove loading of https://www.google.com/recaptcha/api.js?… script right away in the header – that’s a big no-no now! If you use WordPress or other CMS plugins, you should modify plugin’s enqueue function.
Example universal reCaptcha explicit render implementation for WordPress (note: see invisible-recaptcha plugin > PublicEngine.php file for more details).
Note: We have greatly simplified below code, because in newer plugin versions support was added for Contact Form 7 (CF7) plugin as well, which is not relevant in this case.
PART 4: reCaptcha Load
Bind reCaptcha to form input field focus event listener.
This is the most important part that makes the whole magic fully functional! ;)
Of course, here’s the part where you can get creative. For example, you can initially hide comment input form and place a button named ‘Leave comment’ or similar. When user clicks on that button, it will reveal comment input form, and load reCaptcha library simultaneously. Naturally, code will require some modification e.g. to change event listener from ‘focus’ to ‘click’ event and target elements (tags), but everything else should remain essentially the same.
jQuery solution (partial)
That’s the whole trick, really! We improved our website score by some 20% in Chrome’s v71 Lighthouse, and 55% in Google’s PageSpeed insights online test suite (mobile emulation mode in both cases). Plus, we will not load reCaptcha to visitors who will never interact with our forms in the first place! Ok, score of 38 in PageSpeed still sucks (unusually high interaction time could be a bug on their end or they are using like really slow ancient device), but, hey – it’s still an improvement! :)