]*?(' . implode('|', $parent_selectors) . ').*?)>.*?<(link|img|script).*?<\/\g1>#is', $html, $parents, PREG_SET_ORDER); if(!empty($parents)) { foreach($parents as $parent) { //match all tags preg_match_all('#<(?>link|img|script)(\s[^>]*?)>#is', $parent[0], $tags, PREG_SET_ORDER); if(!empty($tags)) { //loop through images foreach($tags as $tag) { $tag_atts = Utilities::get_atts_array($tag[1]); $key = array_search($parent[2], array_column(self::$fetch_priority, 'selector')); $tag_atts['fetchpriority'] = self::$fetch_priority[$key]['priority'];; //replace video attributes string $new_tag = str_replace($tag[1], ' ' . Utilities::get_atts_string($tag_atts), $tag[0]); //replace video with placeholder $html = str_replace($tag[0], $new_tag, $html); unset($new_tag); } } } } } //selectors if(!empty($selectors)) { preg_match_all('#<(?>link|img|script)(\s[^>]*?(' . implode('|', $selectors) . ').*?)>#is', $html, $matches, PREG_SET_ORDER); if(!empty($matches)) { foreach($matches as $tag) { $atts = Utilities::get_atts_array($tag[1]); $key = array_search($tag[2], array_column(self::$fetch_priority, 'selector')); $atts['fetchpriority'] = self::$fetch_priority[$key]['priority'];; //replace video attributes string $new_tag = str_replace($tag[1], ' ' . Utilities::get_atts_string($atts), $tag[0]); //replace video with placeholder $html = str_replace($tag[0], $new_tag, $html); } } } return $html; } //add preloads to html public static function add_preloads($html) { if(!empty(self::$critical_images)) { self::add_critical_image_preloads($html, Utilities::clean_html($html)); } if(!empty(self::$preloads)) { $mime_types = array( 'svg' => 'image/svg+xml', 'ttf' => 'font/ttf', 'otf' => 'font/otf', 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'eot' => 'application/vnd.ms-fontobject', 'sfnt' => 'font/sfnt' ); foreach(self::$preloads as $line) { //device type check if(!empty($line['device'])) { $device_type = wp_is_mobile() ? 'mobile' : 'desktop'; if($line['device'] != $device_type) { continue; } } //location check if(!empty($line['locations'])) { if(!self::location_check($line['locations'])) { continue; } } $mime_type = ""; if(!empty($line['as']) && $line['as'] == 'font') { $path_info = pathinfo($line['url']); $mime_type = !empty($path_info['extension']) && isset($mime_types[$path_info['extension']]) ? $mime_types[$path_info['extension']] : ""; } //print script/style handle as preload if(!empty($line['as']) && in_array($line['as'], array('script', 'style'))) { if(strpos($line['url'], '.') === false) { global $wp_scripts; global $wp_styles; $scripts_arr = $line['as'] == 'script' ? $wp_scripts : $wp_styles; if(!empty($scripts_arr)) { $scripts_arr = $scripts_arr->registered; if(array_key_exists($line['url'], $scripts_arr)) { $url = $scripts_arr[$line['url']]->src; $parsed_url = parse_url($scripts_arr[$line['url']]->src); if(empty($parsed_url['host'])) { $url = site_url($url); } if(strpos($url, '?') === false) { $ver = $scripts_arr[$line['url']]->ver; if(empty($ver)) { $ver = get_bloginfo('version'); } } $line['url'] = $url . (!empty($ver) ? '?ver=' . $ver : ''); } else { continue; } } else { continue; } } } $preload = ""; if($line['as'] == 'image') { array_unshift(self::$preloads_ready, $preload); } else { self::$preloads_ready[] = $preload; } } } if(!empty(self::$preloads_ready)) { $preloads_string = ""; foreach(apply_filters('perfmatters_preloads_ready', self::$preloads_ready) as $preload) { $preloads_string.= $preload; } $pos = strpos($html, ''); if($pos !== false) { $html = substr_replace($html, '' . $preloads_string, $pos, 8); } } return $html; } //add critical image preloads public static function add_critical_image_preloads(&$html, $clean_html) { //match all image formats preg_match_all('#(]+?)\/?>(?><\/picture>)?#is', $clean_html, $matches, PREG_SET_ORDER); if(!empty($matches)) { $exclusions = apply_filters('perfmatters_critical_image_exclusions', array( ';base64', 'w3.org' )); $count = 0; foreach($matches as $match) { if($count >= self::$critical_images) { break; } if(strpos($match[0], 'secure.gravatar.com') !== false) { continue; } if(!empty($exclusions) && is_array($exclusions)) { foreach($exclusions as $exclusion) { if(strpos($match[0], $exclusion) !== false) { continue 2; } } } //picture tag if(!empty($match[1])) { preg_match('#]+?image\/(webp|avif)[^>]+?)\/?>#is', $match[0], $source); if(!empty($source)) { if(self::generate_critical_image_preload($source[1])) { $new_picture = str_replace(''; //mark src used and return if(!empty($src)) { self::$used_srcs[] = $src; } return true; } } private static function location_check($locations) { $location_match = false; $exploded_locations = explode(',', $locations); $trimmed_locations = array_map('trim', $exploded_locations); //single post exclusion if(is_singular()) { global $post; if(in_array($post->ID, $trimmed_locations)) { $location_match = true; } } //posts page exclusion elseif(is_home() && in_array('blog', $trimmed_locations)) { $location_match = true; } elseif(is_archive()) { //woocommerce shop check if(function_exists('is_shop') && is_shop()) { if(in_array(wc_get_page_id('shop'), $trimmed_locations)) { $location_match = true; } } } return $location_match; } }