Last active
June 11, 2024 04:33
-
-
Save aktaumag/1f221ff4774ffb81ad0a7bf97fab46bd to your computer and use it in GitHub Desktop.
Как внедрять картинки и ускорять их.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Всё о важности картинок и их ускорении |
Сейчас нативный loading="lazy"
работает плохо, в том плане, что загружает картинки на 7 экранов вниз, а при плохом 3G соединении вообще на все 14... таких длинных сайтов то редко встретишь.
Поэтому ещё актуально использовать костыли
https://apoorv.pro/lozad.js/
<img style="width:100%; max-width:300px;"
class="demilazyload"
alt="Demimurych Lazy Tester"
src="itak.png"
data-srcset="itak2.webp 100w"
srcset="image.svg 100w"
sizes="100vw"
/>
<script type="text/javascript" src="lozad.js"></script>
<script>
lozad('.demilazyload').observe();
</script>
При таком подходе надо создать пустой SVG как заглушку и указывать у каждой картинки параметры ширины и высоты, чтобы не прыгал дизайн сайта при загрузке.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"></svg>
<style>
img{
max-width: 100%;
width: auto;
height: auto;
}
img.wsbgll {
background-color: #3333331a;
}
</style>
<img src="/img/picture.png"
width="350"
height="170"
class="wslazy wsbgll"
data-srcset="/img/picture.webp 100w"
srcset="/img/empty.svg 100w"
sizes="100vw"
decoding="async"
loading="lazy"
alt="">
<script src="/js/lozad.js"></script>
<script>
lozad('.wslazy').observe();
</script>
WordPress
<?php
function ws_lazy_load($content){
$include_noscript = false;
// Normal image
$matches = array();
preg_match_all( '/<img[\s\r\n]+.*?>/is', $content, $matches );
$search = array();
$replace = array();
$i = 0;
foreach ( $matches[0] as $imgHTML ) {
if (strpos($imgHTML, 'wsnolazy') === false && strpos($imgHTML, 'data-src') === false && ! preg_match( "/src=['\"]data:image/is", $imgHTML )) {
$i++;
$replaceHTML = $imgHTML;
if ( preg_match( '/class=["\']/i', $replaceHTML ) ) {
$replaceHTML = preg_replace( '/class=(["\'])(.*?)["\']/is', 'class=$1wslazy $2$1', $replaceHTML );
} else {
$replaceHTML = preg_replace( '/<img/is', '<img class="wslazy"', $replaceHTML );
}
if ( !preg_match( '/sizes=["\']/i', $replaceHTML ) ) {
$replaceHTML = preg_replace( '/ src=["\'](.*?)["\']/is', ' src="$1" srcset="/wp-content/themes/newTheme/assets/js/empty.svg 100w" data-srcset="$1 100w" sizes="100vw"', $replaceHTML );
} else {
$replaceHTML = preg_replace( '/<img(.*?) srcset=/is', '<img$1 srcset="/wp-content/themes/newTheme/assets/js/empty.svg 100w" data-srcset=', $replaceHTML );
}
if ( !preg_match( '/decoding=["\']/i', $replaceHTML ) ) {
$replaceHTML = preg_replace( '/<img/is', '<img decoding="async"', $replaceHTML );
}
if ( !preg_match( '/loading=["\']/i', $replaceHTML ) ) {
$replaceHTML = preg_replace( '/<img/is', '<img loading="lazy"', $replaceHTML );
}
if ( !preg_match( '/width=["\']/i', $replaceHTML ) && !preg_match( '/height=["\']/i', $replaceHTML ) ) {
// получаем размеры ширины и высоты картинки
if (preg_match( '/ src=["\'](.*?)["\']/is', $replaceHTML, $wssrc )){
$wssrcpath = $wssrc[1];
if(substr($wssrcpath, 0, 1) == '/') {
$wssrcpath = '.'.$wssrc[1];
}
elseif(substr($wssrcpath, 0, 4) == 'www.') {
$wssrcpath = '//'.$wssrc[1];
}
$imageparam = getimagesize(htmlspecialchars($wssrcpath));
if($imageparam){
$wswidth = $imageparam[0];
$wsheight = $imageparam[1];
$replaceHTML = preg_replace( '/<img/is', '<img width="'.$wswidth.'" height="'.$wsheight.'"', $replaceHTML );
}
}
}
if ( $include_noscript ) {
$replaceHTML .= '<noscript>' . $imgHTML . '</noscript>';
}
array_push( $search, $imgHTML );
array_push( $replace, $replaceHTML );
}
}
$search = array_unique( $search );
$replace = array_unique( $replace );
$content = str_replace( $search, $replace, $content );
return $content;
}
add_filter( 'the_content', 'ws_lazy_load' );
?>
Отложенная загрузка для Яндекс Карты.
Появляется если доскролить до нужного места, но на всякий случай есть ещё и триггеры на наведение мышкой, клик и пр.
<!-- размер контейнера под размер карты и цвет окраски в стиле сайта -->
<div id="wsmainmap" style="display: block; width: 100%; height: 680px;background-color: #0078881a;">
<!-- скрипт карты, которой даём нужное ID и переделываем SRC в DATA-SRC -->
<script type="text/javascript" charset="utf-8" async id="map_wslazy" data-src="https://api-maps.yandex.ru/services/constructor/1.0/js/?um=constructor%3A982500c531973a06e0aa07174eafc6dbaabfdf0cf8785f8e326da852e1963c32&width=100%25&height=680&lang=ru_RU&scroll=true"></script>
</div>
<script>
let map_container = document.getElementById('wsmainmap');
let options_map = {
once: true,
passive: true,
capture: true
};
map_container.addEventListener('click', start_lazy_map, options_map);
map_container.addEventListener('mouseover', start_lazy_map, options_map);
map_container.addEventListener('touchstart', start_lazy_map, options_map);
map_container.addEventListener('touchmove', start_lazy_map, options_map);
var iObserver = new IntersectionObserver(function(entries) {
if (entries[0].isIntersecting === true) {
start_lazy_map();
}
}, {threshold: [0]}); // от 0 до 1, % видимой части элемента на экране
iObserver.observe(map_container);
let map_loaded = false;
function start_lazy_map() {
if (!map_loaded) {
let map_block = document.getElementById('map_wslazy');
map_loaded = true;
map_block.setAttribute('src', map_block.getAttribute('data-src'));
map_block.removeAttribute('data-src');
console.log('YMAP LOADED');
}
}
</script>
Источник: https://codepen.io/fe-nix/pen/PoQvxQa
let observer = new IntersectionObserver(
function (entries) {
for (let i in entries) {
let el = entries[i].target;
if (entries[i].isIntersecting === true) {
if (el.dataset.srcset) {
el.setAttribute("srcset", el.dataset.srcset);
} else {
el.removeAttribute("srcset");
}
el.addEventListener(
"load",
function () {
el.classList.add("loaded");
},
{ passive: true }
);
}
}
},
{ threshold: [0], rootMargin: "100px 0px 100px 0px" } // Здесь вы выбираете на сколько пикселей вверх право низ и лево будут элементы будут считаться внутри вьюпорта и начинут загружаться в текущем примере 100 пикселей сверху и снизу.
);
document.addEventListener(
"DOMContentLoaded",
function () {
let mas = document.querySelectorAll(".lazy"); // Слектор для изображений, здесь используется .lazy
for (let i = 0; i < mas.length; i++) {
observer.observe(mas[i]);
}
},
{ passive: true }
);
Пример вставки:
<img src="https://perfscan.ru/static/gallery/img/320/002.jpg" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt="" width="320" height="180" decoding="async" class="lazy">
<img src="https://perfscan.ru/static/gallery/img/320/003.jpg" srcset="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" data-srcset="https://perfscan.ru/static/gallery/img/640/003.jpg 2x" alt="" width="320" height="180" decoding="async" class="lazy">
LazyLoad для загрузки картинок при помощи CSS background
<style>
.wsBgLazy{background-image: none !important;}
</style>
<div class="wsbglazy" data-bgimgurl="image.jpg"></div>
<div class="wsbglazy" data-bgurl="image.jpg"></div>
<div class="wsbglazy"></div> <!-- картинка прописана где-то в CSS файлах стилей -->
<script>
const wsBgObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let wsEl = entry.target;
if (wsEl.dataset.bgurl) {
wsEl.style.background = "url('"+wsEl.dataset.bgurl+"') 0 0 no-repeat";
}
else if(wsEl.dataset.bgimgurl) {
wsEl.style.backgroundImage = "url('"+wsEl.dataset.bgimgurl+"')";
}
wsEl.classList.remove("wsBgLazy");
wsEl.classList.add("wsBgLoaded");
wsBgObserver.unobserve(wsEl);
}
});
});
document.addEventListener(
"DOMContentLoaded",
function () {
const wsBgMass = document.querySelectorAll(".wsBgLazy");
wsBgMass.forEach((el) => {
wsBgObserver.observe(el);
});
},
{ passive: true }
);
</script>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://www.youtube.com/watch?v=F6KGcb6trXc
Самый важный атрибут картинки —
ALT
, должен вписываться в содержание страницы.alt
не должен равняться заголовку страницы или раздела/блока/секции, в которой находится картинка. Вообще не должен быть дублем другого текста страницы.alt=""
— если это alt пустой, то по сути картинка должна считаться системной (картинка для дизайна), но на самом деле так не происходит, поэтому все системные картинки лучше использовать в стилях как фон, но не через тегimg
.Чем лучше качество картинки, тем больше вероятность попадания в топ. Хоть до 20.000px в ширину и высоту, но хватает того, чтобы картинки были лучше, чем у конкурентов.
Минимум: 1920 × 1080 пикселей
URL адрес картинки повторяет структуру самой страницы
Например, картинка для страницы https://wseo.kz/redirect/service/https должна лежать по адресу https://wseo.kz/redirect/service/https/pereadresaciya-na-https-protokol.jpg
пример:
Картинка с тегом src не оптимизируется и содержит максимальное качество. Именно она и индексируется.
Оптимизируются картинки в атрибуте srcset, одна из них и будет отображаться.
Даже если картинки нет (не загрузится), то по дизайну блок под картинку должен сразу иметь нужную ширину и высоту!!!
При последующей загрузке картинки блоки не должны прыгать в размерах.
Картинка должна сочетаться с текстом и должна содержать образы того, о чём написано на странице.
Проверить можно здесь: https://cloud.google.com/vision
Картинка должна быть без водяного знака.
На картинке не должно быть текста.
Картинки должны содержать метатеги в формате IPTC для указания вашего авторства. (Byline/Author/Creator + Copyright Notice + Source)
Тег
<picture>
удобный, но в плане технической оптимизации он сильно увеличивает структуру DOM. Минимум в 3 раза для каждого изображения. Верхняя граница DOM дерева страницы = 1500 узлов... мак. глубина = 32 узла... ЧЕМ МЕНЬШЕ, ТЕМ ЛУЧШЕ.Тег
<figure>
вообще не подходит для указания картинок, так как гласит о том, что это отдельный объект страницы, который следует понимать в отрыве от всего остального контента. Иными словами - не SEO картинка и не относится к содержанию страницы.Картинки, указанные через стили, НЕ ИНДЕКСИРУЮТСЯ:
background: url("/path/img.jpg");
Влияние на SEO оказывают только картинки в теге IMG, указанные в атрибуте SRC.
Поэтому, все дизайнерские элементы и иконки (рейтинг, корзина, телефоны, соцсети) должны быть через стили
::after
,::before
илиbackground:
Желательно важные картинки сайта внедрять сразу с разметкой
Если картинка в SVG, то её указываем именно в
srcset
в единичном варианте для всех размеров, а для атрибутаsrc
создаём растровый вариант из этой картинки:Особенно для логотипа компании на брендовых страницах.
https://responsivebreakpoints.com/
Пример нарезки картинок
ВИДЕО
Вместо iframe ставится картинка (превьюшка) и вешается обработчик по клику, который меняет эту картинку на iframe.
При этом всю нужную для SEO информацию мы передаём через микроразметку Shema.org для разметки видео.