libreform / wp-libre-form

Easy native HTML5 forms for WordPress. Version 1.5 is unmaintained, but works without issue. 2.0 has been rewritten from the ground, and can be found at https://github.com/libreform/libreform
https://wordpress.org/plugins/wp-libre-form
GNU General Public License v3.0
67 stars 27 forks source link

Cut down on client side script size by conditionally loading polyfills #48

Closed k1sul1 closed 7 years ago

k1sul1 commented 7 years ago

Right now assets/scripts/wplf-form.js is pretty big, taking 11.6 KB of space. There's a lot of unnecessary code for most of todays browsers. By conditionally loading that code, they could load and parse a 1.6 KB script instead of a 11.6 KB script.

Should be rather easy, maybe something like this could work? Don't have my usual "gear" with me so I can't test it right away.

var dependencies = []; 
if (!window.Promise) {
  dependencies.push('promise');
}

if (!window.fetch) {
  dependencies.push('fetch');
}

window.wplf = {
  // Put the same object from wplf-form.js here so that any user created functionality won't break
  // (we're just initializing a bit later
};

var app = function () {
   // Run the actual app code here
   document.addEventListener("DOMContentLoaded", function() {
    [].forEach.call(document.querySelectorAll(".libre-form"), window.wplf.attach);
  });
};

initialize(dependencies, app);

function initialize(dependencies, app) {
  // This should be instant for browsers that have no dependencies required
  var dependency_count = dependencies.length;
  var dependencies_loaded = 0; 
  var is_ready = function() {
    return dependency_count === dependencies_loaded;
  };
  var run_when_ready = function() {
    if (is_ready()) {
      app();
    }
  };
  var get_script = function(script) {
    var url_base = '/wp-content'; // supply in localize_script()
    var elmnt = document.createElement('script');
    elmnt.src = url_base + script;

    return elmnt;
  };

  dependencies.map(function(dependency) {
    return get_script(dependency);
  }).map(function(script) {
    script.addEventListener('load', function() {
      dependencies_loaded++;
      run_when_ready();
    });

    return document.body.appendChild(script);
  });

  run_when_ready();
}

Slightly modified demo. If you visit it from IE11 for example, you should be greeted with an alert in ~2500ms, while latest Chrome should display the alert pretty much immediately.

http://codepen.io/k1sul1/pen/YNWbVQ

anttiviljami commented 7 years ago

👍 I agree. Definitely trying to reduce size is a valid concern