Jak u Gravity Forms spojit a přesunout scripty do patičky webu

20. 8. 2015

V minulém článku o slávě formulářových pluginů jsem si postěžoval, jak se Gravity Forms nedají naoptimalizovat tak, aby nebrzdily rychlost načítání frontendu. Asi mě to nějak podvědomě vyhecovalo či co ... uplynulo totiž pár dnů a jednoho rána jsem se se probudil s myšlenkou, jak by to jít mohlo. Sedl jsem za stroj, a za chvíli už mi bylo jasné, kudy se vydat. A do druhého dne jsem měl celé řešení, které zde dokumentuji.

V minulém článku o slávě formulářových pluginů jsem si postěžoval, jak se Gravity Forms nedají naoptimalizovat tak, aby nebrzdily rychlost načítání frontendu. Asi mě to nějak podvědomě vyhecovalo či co … uplynulo totiž pár dnů a jednoho rána jsem se se probudil s myšlenkou, jak by to jít mohlo. Sedl jsem za stroj, a za chvíli už mi bylo jasné, kudy se vydat. A do druhého dne jsem měl celé řešení, které zde dokumentuji.

Základní problém je v tom, že každý formulář si v místě vlastního HTML kódu vypisuje javascript, který přímo volá jQuery. Kvůli tomu je třeba mít před vypsáním prvního formuláře již jQuery (+ ostatní GF scripty) připojené v hlavičce a kvůli tomu je nelze připojoval na konci stránky, natožpak asynchronně.

Někteří optimalizátoři to řeší tak, že detekují první formulář a jQuery knihovnu připojí těsně před ním — tedy v nejpozdějším možné místě. Ale toto řešení je polovičaté, protože v principu neumožní připojit jQuery asynchronně. A navíc ji připojovat v různých místech stránky podle toho, zda a kde je umístěn nějaký formulář, mi přijde poněkud podivné.

Tento javascript tedy z kódy formuláře ještě před samotným vykreslením úplně vyextrahuji a uložím si do globální PHP proměnné. K tomu mi dobře poslouží dva šikovně napsané regulární výrazy ve filtru gform_get_form_filter, který umožňuje modifikovat kód formuláře před vypsáním do stránky:

add_filter('gform_get_form_filter', function($body, $form) {
	global $webmaestro_gforms_scripts_tuning;
	$js = "";
	preg_match_all('#<script[^>]*>(.*?)</script>#is', $body, $matches);
	foreach ($matches[1] as $value) $js .= $value;
	$body = preg_replace('#<script[^>]*>(.*?)</script>#is', '', $body); 
	$webmaestro_gforms_scripts_tuning .= $js;
	return $body;
}, 10, 2);

Všechen nastřádaný javascript si pak vypíši úplně na konci stránky akcí wp_footer. Kód navíc zapouzdřím do funkce webmaestro_gforms_scripts_tuning(), která bude vracet js proměnnou gf_global:

add_action( 'wp_footer', function() {
	global $webmaestro_gforms_scripts_tuning;
	$scripts = trim($webmaestro_gforms_scripts_tuning);
	if (!$scripts) return;
	?>
		<script type='text/javascript'>
			function webmaestro_gforms_scripts_tuning() {
				<?php echo $scripts; ?>	
				return gf_global;
			}
		</script>
	<?php
});

A teď už jde jen o to funkci vyvolat ve svém vlastním skriptu kdykoliv a jakkoliv (třebas asynchronně), kde budu míst jistotu, že je již připojené jQuery (+ GF scripty). Návratovou hodnotu funkce přiřadím do proměnné gf_global, která v tomto kontextu je globální a GF ji jako globální potřebují:

jQuery(document).ready(function($) {
	if (typeof webmaestro_gforms_scripts_tuning === 'function') {
		gf_global = webmaestro_gforms_scripts_tuning();
	}
});

Pokud bych svůj script chtěl zvolit standardní cestup připojení scriptu, použiji akci wp_enqueue_scripts a v ní připojím funkcí wp_enqueue_script soubor s vlastním js souborem. V připojení uvádím, že je závislé na jQuery, WP se tak postará o správné pořadí načítání:

add_action( 'wp_enqueue_scripts', function () {
	$url = plugin_dir_url( __FILE__);
	wp_enqueue_script('webmaestro-gforms-scripts-tuning', $url . 'webmaestro-gforms-scripts-tuning.js', array(), false, true);
}, 11);

A to je celé. Zde je celé řešení ke stažení jako jeden plugin: webmaestro-gforms-scripts-tuning. Stačí nainstalovat a aktivovat + použít některý z pluginů pro spojení a minifikaci scriptů – viz Základní optimalizace rychlosti načítání webu. Otestováno v tandemu s JS & CSS Script Optimizer a minit.

← Zpátky na články