settings === null) { $this->settings = berqwp_get_page_params(home_url()); } add_filter('berqwp_photon_before_closing_body', [$this, 'img_lazy_load_js']); add_filter('berqwp_photon_before_closing_body', [$this, 'video_lazy_load_js']); add_filter('berqwp_photon_before_closing_body', [$this, 'iframe_lazy_load_js']); add_filter('berqwp_photon_before_closing_body', [$this, 'dynamic_js_loading_script']); add_filter('berqwp_photon_before_closing_body', [$this, 'dynamic_css_loading_script']); add_filter('berqwp_photon_before_closing_body', [$this, 'prerender_on_hover']); } function start_cache() { add_action('template_redirect', [$this, 'buffer_start'], 2); } function set_slug($slug) { $this->page_slug = $slug; } function set_page($page_url) { $this->page_url = $page_url; } function buffer_start() { ob_start([$this, 'buffer_end']); } function prerender_on_hover($script) { if ($this->settings['prerender_link']) { $script .= " "; } return $script; } function video_lazy_load_js($script) { if ($this->settings['lazy_load_videos']) { $script .= " "; } return $script; } function iframe_lazy_load_js($script) { if ($this->settings['youtube_lazyloading']) { $script .= " "; } return $script; } static function url_to_path($url) { if (strpos($url, '?') !== false) { $url = explode('?', $url)[0]; } if (strpos($url, '#') !== false) { $url = explode('#', $url)[0]; } // Handle relative URLs if (strpos($url, '//') === 0) { return realpath(ABSPATH . ltrim($url, '/')); } $content_url = content_url(); $content_dir = WP_CONTENT_DIR; if (strpos($url, $content_url) === 0) { // var_dump(realpath( // str_replace($content_url, $content_dir, $url) // )); return str_replace($content_url, $content_dir, $url); } // Fallback for site root files $site_url = get_site_url('/'); if (strpos($url, $site_url) === 0) { return realpath( str_replace($site_url, ABSPATH, $url) ); } return false; } function img_lazy_load_js($script) { if ($this->settings['img_lazyloading']) { $script .= " "; } return $script; } function dynamic_css_loading_script($script) { if ($this->settings['css_optimization'] == 'asynchronous' || $this->settings['css_optimization'] == 'delay') { $script .= " "; if ($this->settings['css_optimization'] == 'asynchronous') { $script .= " "; } if ($this->settings['css_optimization'] == 'delay') { $script .= " "; } } return $script; } function dynamic_js_loading_script($script) { if ($this->settings['js_optimization'] == 'asynchronous' || $this->settings['js_optimization'] == 'delay') { $script .= " "; if ($this->settings['js_optimization'] == 'asynchronous') { $script .= " "; } if ($this->settings['js_optimization'] == 'delay') { $script .= " "; } } return $script; } function optimize_js($buffer) { $dom = HtmlDomParser::str_get_html($buffer); $js_excludes = $this->settings['exclude_js']; $js_excludes = array_map(function ($kw) { return sanitize_text_field(trim($kw)); }, $js_excludes); foreach ($dom->find('script') as $element) { $script_src = $element->src; $outerhtml = $element->outertext; if (strpos($outerhtml, 'document.write(') !== false) { continue; } if (strpos($outerhtml, '$zoho.salesiq = ') !== false) { continue; } if (strpos($outerhtml, 'CRLeadStar.init') !== false) { continue; } if (!empty($element->type) && $element->type !== 'text/javascript' && $element->type !== 'application/javascript' && $element->type !== 'module') { continue; } if ($element->hasAttribute('data-berqwp-exclude')) { continue; } // exclude script tags if (!empty($js_excludes)) { foreach ($js_excludes as $exclude_kw) { if (strpos($outerhtml, $exclude_kw) !== false) { if ($this->settings['defer_excluded_js'] && !$element->hasAttribute('async')) { $element->setAttribute('defer', 'defer'); } continue 2; } } } if ($this->settings['js_optimization'] == 'defer') { if (!$element->hasAttribute('async')) { $element->setAttribute('defer', 'defer'); } continue; } if (empty($element->type) || $element->type == 'text/javascript') { $element->setAttribute('data-type', 'text/javascript'); $element->type = 'text/bwp-script'; } else { $element->setAttribute('data-type', esc_attr($element->type)); $element->type = 'text/bwp-script'; } } return (string) $dom; } function lazy_load_videos($buffer) { $dom = HtmlDomParser::str_get_html($buffer); foreach ($dom->find('video') as $element) { $outerhtml = $element->outertext; $parent = $element->parent(); if (strpos($outerhtml, 'video-js') !== false) { continue; } if (strpos($outerhtml, 'mg_self-hosted-video') !== false) { continue; } if (!empty($element->src)) { $original_src = $element->src; // $video->attr['data-berqwpsrc'] = $original_src; $element->setAttribute('data-berqwpsrc', $original_src); $element->removeAttribute('src'); } // Handle each element within the video tag foreach ($element->find('source') as $source) { if (!empty($source->src)) { $original_src = $source->src; // $source->attr['data-berqwpsrc'] = $original_src; $source->setAttribute('data-berqwpsrc', $original_src); $source->removeAttribute('src'); } unset($source); } $class = $element->getAttribute('class'); $class .= ' berqwp-lazy-video'; $element->setAttribute('class', $class); $element->setAttribute('preload', 'none'); // $element->attr[' preload'] = 'none'; } return (string) $dom; } function lazy_load_images($buffer) { $dom = HtmlDomParser::str_get_html($buffer); $image_excludes = $this->settings['exclude_img_lazy_load']; $image_excludes = array_map(function ($kw) { return sanitize_text_field(trim($kw)); }, $image_excludes); foreach ($dom->find('img') as $element) { if (!$element->hasAttribute('src') || empty($element->src)) { continue; } $img_src = $element->src; $outerhtml = $element->outertext; $img_path = self::url_to_path($img_src); // exclude lazy load if (!empty($image_excludes)) { foreach ($image_excludes as $exclude_kw) { if (strpos($outerhtml, $exclude_kw) !== false) { continue 2; } } } if (strpos($img_src, 'data:') === 0) { continue; } if (strpos($img_src, ';base64,') !== false) { continue; } if (strpos($outerhtml, 'rs-lazyload') !== false) { continue; } if (strpos($outerhtml, 'mfn-lazy') !== false) { continue; } if (strpos($outerhtml, 'data-dbsrc=') !== false) { continue; } if (strpos($outerhtml, 'data-orig-src=') !== false) { continue; } if (strpos($outerhtml, 'facebook.com') !== false) { continue; } if (strpos($img_src, '${') !== false) { continue; } // Skip smush lazy loading if (strpos($img_src, '--smush-placeholder-width') !== false) { continue; } // wpbackery background image if (strpos($img_src, 'class="background-image"') !== false) { continue; } // lscache lazy load if (strpos($img_src, 'class="lazyload"') !== false) { continue; } // salient lazy load if (strpos($img_src, 'data-nectar-img-src') !== false) { continue; } $width = $element->width; $height = $element->height; if (!empty($img_path) && file_exists($img_path) && !$element->hasAttribute('width') && !$element->hasAttribute('height')) { list($width, $height) = getimagesize($img_path); } $element->removeAttribute('src'); $element->setAttribute('data-berqwpsrc', $img_src); if ($element->hasAttribute('srcset')) { $srcset = $element->srcset; $element->removeAttribute('srcset'); $element->setAttribute('data-berqwp-srcset', $srcset); } if (!empty($width) && !empty($height)) { $svg = ''; $svg .= ''; $svg .= ''; $base64Svg = base64_encode($svg); // Create data URI $ph_webp_url = 'data:image/svg+xml;base64,' . $base64Svg; } else { $ph_webp_url = 'data:image/gif;placeholder=MjQxOjM1NQ==-1;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAICTAEAOw=='; } $element->setAttribute('src', $ph_webp_url); $element->setAttribute('decoding', 'async'); } return (string) $dom; } private function extract_template_scripts( $buffer ) { $placeholders = []; $pattern = '/]*\btype=["\'](?:text\/template|text\/x-template|text\/x-handlebars-template|text\/x-handlebars|text\/ng-template)["\'])[^>]*>.*?<\/script>/is'; $result = preg_match_all( $pattern, $buffer, $matches ); if ( $result === false || $result === 0 ) { return [ $buffer, $placeholders ]; } foreach ( $matches[0] as $index => $script_block ) { $placeholder = ''; $placeholders[ $placeholder ] = $script_block; $buffer = str_replace( $script_block, $placeholder, $buffer ); } return [ $buffer, $placeholders ]; } private function restore_template_scripts( $buffer, $placeholders ) { if ( empty( $placeholders ) ) { return $buffer; } foreach ( $placeholders as $placeholder => $original_block ) { $buffer = str_replace( $placeholder, $original_block, $buffer ); } return $buffer; } function lazy_load_iframes($buffer) { $dom = HtmlDomParser::str_get_html($buffer); foreach ($dom->find('iframe') as $element) { $outerhtml = $element->outertext; $outerhtml = apply_filters('photon_before_iframe_optimization', $outerhtml); $isyoutube = false; if ($this->settings['preload_yt_poster']) { if (preg_match('/youtube\.com\/embed\/([a-zA-Z0-9_-]+)/', $element->src, $matches)) { $videoId = $matches[1]; $isyoutube = true; // Generate the thumbnail URL $thumbnailUrl = "https://img.youtube.com/vi/{$videoId}/hqdefault.jpg"; $highresthumbnailUrl = "https://img.youtube.com/vi/{$videoId}/maxresdefault.jpg"; if (strpos($element->src, 'autoplay=1') !== false && strpos($element->src, 'mute=') === false) { $element->setAttribute('src', $element->src . "&mute=1"); } // Generate lazy-load HTML content for srcdoc $srcdocContent = << *{padding:0;margin:0;overflow:hidden} .play-button { width: 70px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); cursor: pointer; }
HTML; // Update the iframe attributes $element->setAttribute('srcdoc', $srcdocContent); $element->setAttribute('src', $element->src); // Remove immediate src loading } if ($isyoutube && $element->hasAttribute('data-berqWPexclude')) { continue; } } if (strpos($outerhtml, 'youtube.com') !== false && !$element->hasAttribute('referrerpolicy')) { $element->setAttribute('referrerpolicy', 'strict-origin-when-cross-origin'); } if ($element->hasAttribute('data-berqWPexclude')) { continue; } $class = $element->getAttribute('class'); if (!empty($class)) { $classes = explode(' ', $class ?? ''); $classes = array_filter($classes, fn($c) => $c !== 'lazyload'); $class = trim(implode(' ', $classes)); $element->setAttribute('class', $class); } if ($element->hasAttribute('data-src')) { $element->setAttribute('rm-src', $element->src); $element->removeAttribute('src'); } $outerhtml = esc_attr($element->outertext); $element->outertext = '
'; } return (string) $dom; } function store_cache($buffer) { // Define the cache directory $cache_directory = bwp_get_cache_dir(); $url = bwp_canonicalize_page_url($this->page_url); // Create the cache directory if it doesn't exist if (!file_exists($cache_directory)) { mkdir($cache_directory, 0755, true); } $cache = new Cache(null, bwp_get_cache_dir()); $cache->store_cache($url, $buffer); do_action('berqwp_stored_page_cache', $this->page_slug); global $berq_log; $berq_log->info("Stored cache for $url from PageOptimizer class"); } function preload_images($buffer) { $dom = HtmlDomParser::str_get_html($buffer); $count = 0; $candidates = []; foreach ($dom->find('img') as $element) { if ($count >= 9) { break; } if (!$element->hasAttribute('src') || empty($element->src)) { continue; } $img_src = $element->src; $outerhtml = $element->outertext; $img_path = self::url_to_path($img_src); // exclude lazy load // if (!empty($image_excludes)) { // foreach ($image_excludes as $exclude_kw) { // if (strpos($outerhtml, $exclude_kw) !== false) { // continue 2; // } // } // } if (strpos($img_src, 'data:') === 0) { continue; } if (strpos($img_src, ';base64,') !== false) { continue; } if (strpos($outerhtml, 'rs-lazyload') !== false) { continue; } if (strpos($outerhtml, 'mfn-lazy') !== false) { continue; } if (strpos($outerhtml, 'data-dbsrc=') !== false) { continue; } if (strpos($outerhtml, 'data-orig-src=') !== false) { continue; } if (strpos($outerhtml, 'facebook.com') !== false) { continue; } $width = $element->width; $height = $element->height; if (!empty($img_path) && file_exists($img_path) && !$element->hasAttribute('width') && !$element->hasAttribute('height')) { list($width, $height) = getimagesize($img_path); } $candidate = [ 'width' => $width, 'height' => $height, 'area' => (int) $width * (int) $height, 'src' => $img_src, ]; if ($element->hasAttribute('loading')) { $candidate['loading'] = $element->loading; } if ($element->hasAttribute('srcset')) { $candidate['srcset'] = $element->srcset; } if ($element->hasAttribute('sizes')) { $candidate['sizes'] = $element->sizes; } $candidates[] = $candidate; $count++; } $buffer = (string) $dom; if (!empty($candidates)) { $processed = []; // unique src $candidates = array_filter($candidates, function ($item) use (&$processed) { if (in_array($item['src'], $processed)) { return false; } $processed[] = $item['src']; return true; }); usort($candidates, function ($a, $b) { return $b['area'] <=> $a['area']; // DESC }); $candidates = array_slice($candidates, 0, 2); $prelaod_html = ''; foreach ($candidates as $preload_img) { $prelaod_html .= 'early_head_html .= $preload_html; } return $buffer; } function preload_stylesheet($buffer) { $dom = HtmlDomParser::str_get_html($buffer); foreach ($dom->find('link') as $element) { if ($element->rel == 'stylesheet'){ $element->setAttribute('rel', 'preload'); $element->setAttribute('as', 'style'); $element->removeAttribute('media'); // $element->setAttribute('media', 'print'); // $element->setAttribute('onload', "this.media='all'"); $element->setAttribute('onload', "this.rel='stylesheet'"); } } return (string) $dom; } function delay_styles($buffer) { if ( !empty($this->settings['css_optimization']) && $this->settings['css_optimization'] !== 'delay' && $this->settings['css_optimization'] !== 'asynchronous' ) { return $buffer; } $dom = HtmlDomParser::str_get_html($buffer); $style_excludes = array_map(function ($kw) { return sanitize_text_field(trim($kw)); }, $this->settings['exclude_css']); foreach ($dom->find('link') as $element) { $outerhtml = $element->outertext; if ($element->rel == 'stylesheet' || $element->as == 'style'){ if (!$element->hasAttribute('href')) { continue; } if ($element->hasAttribute('data-berqwp-exclude')) { continue; } // exclude style if (!empty($style_excludes)) { foreach ($style_excludes as $exclude_kw) { if (!empty($exclude_kw) && strpos($outerhtml, $exclude_kw) !== false) { continue; } } } $element->setAttribute('rel', 'stylesheet'); $element->setAttribute('as', 'style'); $element->setAttribute('data-berqwp-style-href', $element->href); $element->removeAttribute('href'); } } foreach ($dom->find('style') as $element) { $outerhtml = $element->outertext; if ($element->hasAttribute('data-berqwp-exclude')) { continue; } // exclude style if (!empty($style_excludes)) { foreach ($style_excludes as $exclude_kw) { if (!empty($exclude_kw) && strpos($outerhtml, $exclude_kw) !== false) { continue; } } } $element->setAttribute('type', 'text/berqwp-style'); } return (string) $dom; } function buffer_end($buffer) { // $buffer = file_get_contents('/Users/hamzamairaj/Local Sites/plugin-berqwp/app/public/wp-content/plugins/searchpro/inc/photon/page.html'); if (empty($buffer)) { return $buffer; } $buffer = $buffer.''; $script = " "; [ $buffer, $template_placeholders ] = $this->extract_template_scripts( $buffer ); $buffer = $this->preload_images($buffer); // $buffer = $this->preload_stylesheet($buffer); if ($this->settings['img_lazyloading']) { $buffer = $this->lazy_load_images($buffer); } if ($this->settings['js_optimization'] == 'auto') { if ($this->settings['opt_mode'] == 'basic') { $this->settings['js_optimization'] = 'defer'; } if ($this->settings['opt_mode'] == 'medium') { $this->settings['js_optimization'] = 'asynchronous'; } if ($this->settings['opt_mode'] == 'blaze') { $this->settings['js_optimization'] = 'delay'; } if ($this->settings['opt_mode'] == 'aggressive') { $this->settings['js_optimization'] = 'delay'; } } if ($this->settings['js_optimization'] !== 'disable') { $buffer = $this->optimize_js($buffer); } if ($this->settings['lazy_load_videos']) { $buffer = $this->lazy_load_videos($buffer); } if ($this->settings['youtube_lazyloading']) { // $buffer = $this->lazy_load_iframes($buffer); } if ($this->settings['css_optimization'] == 'auto') { if ($this->settings['opt_mode'] == 'basic') { $this->settings['css_optimization'] = 'disable'; } if ($this->settings['opt_mode'] == 'medium') { $this->settings['css_optimization'] = 'asynchronous'; } if ($this->settings['opt_mode'] == 'blaze') { $this->settings['css_optimization'] = 'asynchronous'; } if ($this->settings['opt_mode'] == 'aggressive') { $this->settings['css_optimization'] = 'delay'; } } $enable_used_css = (bool) apply_filters( 'berqwp_local_used_css', apply_filters('berqwp_local_critical_css', (bool) get_option('berqwp_enable_used_css')) ); // $enable_used_css = false; // disable if ($enable_used_css && $this->settings['css_optimization'] !== 'disable') { $critical_css = new berqUsedCSS(get_option('home')); $critical_css->forceInclude($this->settings['force_include_critical_css']); $critical_css = $critical_css->process_css($buffer); $critical_css = sprintf('', $critical_css); /* $buffer = berqwp_prependHtmlToHead($buffer, $critical_css); */ $this->early_head_html .= $critical_css; $buffer = $this->delay_styles($buffer); } $buffer = berqwp_earlyHeadHtml($buffer, $this->early_head_html); $buffer = $this->restore_template_scripts( $buffer, $template_placeholders ); $script = apply_filters('berqwp_photon_before_closing_body', $script); $buffer = berqwp_appendHtmlToBody($buffer, $script); $buffer = apply_filters( 'berqwp_cache_buffer', $buffer ); $this->store_cache($buffer); return $buffer; } }