@@ -41,6 +41,14 @@ class Visualizer_Module_Frontend extends Visualizer_Module {
41
41
*/
42
42
private $ _charts = array ();
43
43
44
+ /**
45
+ * Lazy render script.
46
+ *
47
+ * @access private
48
+ * @var bool
49
+ */
50
+ private $ lazy_render_script = false ;
51
+
44
52
/**
45
53
* Constructor.
46
54
*
@@ -53,6 +61,7 @@ class Visualizer_Module_Frontend extends Visualizer_Module {
53
61
public function __construct ( Visualizer_Plugin $ plugin ) {
54
62
parent ::__construct ( $ plugin );
55
63
64
+ $ this ->_addAction ( 'wp_print_footer_scripts ' , 'printFooterScripts ' );
56
65
$ this ->_addAction ( 'wp_enqueue_scripts ' , 'enqueueScripts ' );
57
66
$ this ->_addAction ( 'load-index.php ' , 'enqueueScripts ' );
58
67
$ this ->_addAction ( 'visualizer_enqueue_scripts ' , 'enqueueScripts ' );
@@ -81,14 +90,32 @@ function script_loader_tag( $tag, $handle, $src ) {
81
90
if ( is_admin () ) {
82
91
return $ tag ;
83
92
}
84
-
85
- $ scripts = array ( 'google-jsapi ' , 'visualizer-render-google-lib ' , 'visualizer-render-google ' );
86
-
87
- foreach ( $ scripts as $ async ) {
93
+ // Async scripts.
94
+ $ async_scripts = array ( 'google-jsapi ' , 'chartjs ' , 'visualizer-datatables ' );
95
+ foreach ( $ async_scripts as $ async ) {
88
96
if ( $ async === $ handle ) {
89
- $ tag = str_replace ( ' src ' , ' defer="defer" src ' , $ tag );
97
+ $ tag = str_replace ( ' src ' , ' async src ' , $ tag );
98
+ break ;
99
+ }
100
+ };
101
+
102
+ // Async scripts.
103
+ $ scripts = array ( 'dom-to-image ' );
104
+ foreach ( array ( 'async ' , 'defer ' ) as $ attr ) {
105
+ if ( wp_scripts ()->get_data ( $ handle , $ attr ) ) {
106
+ break ;
107
+ }
108
+ if ( in_array ( $ handle , $ async_scripts , true ) || false === strpos ( $ handle , 'visualizer- ' ) ) {
90
109
break ;
91
110
}
111
+ if ( ! preg_match ( ":\s $ attr(=|>|\s): " , $ tag ) ) {
112
+ $ tag = preg_replace ( ':(?=></script>): ' , " $ attr " , $ tag , 1 );
113
+ if ( $ this ->lazy_render_script ) {
114
+ $ tag = str_replace ( ' src ' , ' data-visualizer-script ' , $ tag );
115
+ }
116
+ }
117
+ // Only allow async or defer, not both.
118
+ break ;
92
119
}
93
120
return $ tag ;
94
121
}
@@ -328,6 +355,14 @@ public function renderChart( $atts ) {
328
355
// handle settings filter hooks
329
356
$ settings = apply_filters ( Visualizer_Plugin::FILTER_GET_CHART_SETTINGS , $ settings , $ chart ->ID , $ type );
330
357
358
+ $ lazy_load = isset ( $ settings ['lazy_load_chart ' ] ) ? $ settings ['lazy_load_chart ' ] : false ;
359
+ $ lazy_load = apply_filters ( 'visualizer_lazy_load_chart ' , $ lazy_load , $ chart ->ID );
360
+ $ container_class = 'visualizer-front-container ' ;
361
+ if ( $ lazy_load ) {
362
+ $ this ->lazy_render_script = true ;
363
+ $ container_class .= ' visualizer-lazy-render ' ;
364
+ }
365
+
331
366
// handle data filter hooks
332
367
$ data = self ::get_chart_data ( $ chart , $ type );
333
368
@@ -436,7 +471,7 @@ public function renderChart( $atts ) {
436
471
}
437
472
438
473
// return placeholder div
439
- return $ actions_div . '<div id=" ' . $ id . '" ' . $ this ->getHtmlAttributes ( $ attributes ) . '></div> ' . $ this ->addSchema ( $ chart ->ID );
474
+ return ' <div class=" ' . $ container_class . ' "> ' . $ actions_div . '<div id=" ' . $ id . '" ' . $ this ->getHtmlAttributes ( $ attributes ) . '></div> ' . $ this ->addSchema ( $ chart ->ID ) . ' </div> ' ;
440
475
}
441
476
442
477
/**
@@ -606,4 +641,42 @@ private function getChartData( $cache_key = '', $chart_id = 0 ) {
606
641
607
642
return false ;
608
643
}
644
+
645
+ /**
646
+ * Print footer script.
647
+ */
648
+ public function printFooterScripts () {
649
+ if ( $ this ->lazy_render_script ) {
650
+ ?>
651
+ <script type="text/javascript">
652
+ var visualizerUserInteractionEvents = [
653
+ "mouseover",
654
+ "keydown",
655
+ "touchmove",
656
+ "touchstart"
657
+ ];
658
+
659
+ visualizerUserInteractionEvents.forEach(function(event) {
660
+ window.addEventListener(event, visualizerTriggerScriptLoader, { passive: true });
661
+ });
662
+
663
+ function visualizerTriggerScriptLoader() {
664
+ visualizerLoadScripts();
665
+ visualizerUserInteractionEvents.forEach(function(event) {
666
+ window.removeEventListener(event, visualizerTriggerScriptLoader, { passive: true });
667
+ });
668
+ }
669
+
670
+ function visualizerLoadScripts() {
671
+ document.querySelectorAll("script[data-visualizer-script]").forEach(function(elem) {
672
+ jQuery.getScript( elem.getAttribute("data-visualizer-script"), function() {
673
+ elem.setAttribute("src", elem.getAttribute("data-visualizer-script"));
674
+ elem.removeAttribute("data-visualizer-script");
675
+ } );
676
+ });
677
+ }
678
+ </script>
679
+ <?php
680
+ }
681
+ }
609
682
}
0 commit comments