0

I'm wanting to hook IIFE functions:

(function(p) {
   // stuff
})();

I ask this in general sense, though the specific reason is that WordPress plugins often drop inline scripts right into the body output. If you want to defer (async) load dependencies for SEO reasons, it naturally fails.

In an effort to fix endless poor coding practices by plugin providers, and plugins that simply aren't designed with asynchronous loading in mind, I want to do such a thing.

I'm trying to avoid:

  1. Modifying vendor code directly.
  2. Parsing raw content using PHP.
  3. Blocking existing server-side systems of loading JavaScript resources, in order to appropriately load them later.

I'm wondering if there is some extremely low level prototype in the browser dom that can be used to intercept functions of that nature?

Dylan Wheeler
  • 6,928
  • 14
  • 56
  • 80
Barry
  • 362
  • 3
  • 14
  • 3
    FYI, this is called an [IIFE](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) (immediately invoked function expression) – James Monger Aug 17 '16 at 16:00
  • thanks! Updated tags and title – Barry Aug 17 '16 at 16:02
  • 1
    Unfortunately, the answer is a simple "no," there are no low-level hooks in the browser for that. What exactly would you do if you had that ability? It'd be more productive if you specified exactly what you're trying to do, and there may be a better approach to the problem. – Jacob Aug 17 '16 at 16:08
  • Specific example is a Wordpress plugin called Video Background. It drops an IIFE function into the body after a – Barry Aug 17 '16 at 16:14
  • Do they all occur on one spot or on random places in the DOM? If they are all on one spot, you could simply put a function statement around it calllater = function() { ... all the IIFEs ... } – Michael Scheffenacker Aug 17 '16 at 16:14
  • Can you force the plugins into an iframe, something like this: http://www.phpied.com/non-onload-blocking-async-js/ – Ian Gilroy Aug 17 '16 at 16:16
  • What about window.onerror stack trace. Can that be used to "retry" the original execution at some future time? If so, the solution should be to use wp_deregister_script , and use something like RequireJS or ded/script to properly execute failed scripts once loaded asynchronously. – Barry Aug 17 '16 at 16:17
  • 1
    If you wrote a hook that modifies external script tags dropped by plugins, you will want to write a hook that also modifies inline script tags. – Bergi Aug 17 '16 at 16:19
  • Hmmm, great ideas! Thank you michael, Ian, & Bergi. It sounds like I will need to process the raw content, to detect – Barry Aug 17 '16 at 16:19
  • 2
    "*fix plugins that simply aren't designed with asynchronous loading in mind*" - that'll be very hard. They might use `document.write` or whatnot. – Bergi Aug 17 '16 at 16:20

1 Answers1

0

So I ended up doing what I wanted to avoid. It's slightly dirty, but it works very well. I would share, but NDA. If possible I'll try to submit it as a pull request on one of the larger SEO/Caching plugins (likely Better Wordpress minify).

It scans the output buffer for problem scripts and styles, and adjusts them to be Google SEO compliant (non-blocking). I imagine this could never work for gen-pop, as the amount of poor coding in this world is endless, and I think the regex would become painfully bloated by the time all the use-cases were handled.

It relies on loadCSS and some form of native DocumentContentLoaded to be defined inline in the head, starts by forcing all sourced scripts to be deferred, cleans up javascript designed to be executed in it's own script tag, and moves the body scripts into a single function that can be called when the time is right. All with regex.

Here's some pointers for anyone interested in doing similar:

Shout out to all the comments and assistance provided here, wouldn't have even tried without speaking to you guys first. Appreciate the pointers and advice, see you next time!

Community
  • 1
  • 1
Barry
  • 362
  • 3
  • 14