. Доклад Яндекса / Блог компании Яндекс / Хабр
«Просто добавь картинку на сайт», — говорили они. А оказалось, что «просто» не значит «правильно». В докладе я постарался разобраться, как эффективно добавлять изображения на страницу, какие форматы графики для каких случаев полезны и как автоматизировать автоматизируемое.
— Всем привет. У меня доклад с интригующим названием в виде одного тега.
Коротко представлюсь. Возможно, вы слышали о подкасте
— иногда там можно услышать мой голос. И если новости в пабликах «Веб-стандартов» выходят с опечатками — скорее всего, это я. Работаю я в Яндекс.Поиске, разработчиком интерфейсов.
Сегодняшний доклад — по мотивам другого доклада. В 2019 году я успел вскочить в последний вагон и на последнем Web Standards Days прочитал доклад про ссылку.
Интригующее название было. Тогда из зала прозвучал вопрос: «Когда будет про следующие теги?» Сегодня вы смотрите доклад именно про следующий тег, о котором мне хотелось рассказать.
1995
Начнем с истории. Шёл 1995 год. Тогда впервые появился тег img в стандарте HTML 2.0. Вы можете найти
— в то время они писались гораздо более сухо, чем сейчас. Но там есть интересные моменты.
<IMG SRC="https://habr.com/ru/post/559442/triangle.xbm" ALIGN="TOP" ALT="Warning"><a href="http://machine/htbin/imagemap/sample">
<IMG SRC="https://habr.com/ru/post/559442/sample.xbm" ISMAP>
</a>
В стандарте HTML 2.0 можно найти, что атрибутов у img тогда было не то чтобы много.
Был атрибут SRC
, который дошёл до нас. Вы, кстати, можете увидеть тут у файла расширение xbm
— X BitMap. Вы такой формат, возможно, и не застали. Я не застал. Был атрибут ALIGN
, который позволял добавлять выравнивание этой картинке. Был ALT
, он уже тогда был важен. Были всякие прикольные штуки вроде карт ISMAP
, я про них ещё расскажу.
Кстати, интересный факт: в стандарте 1995 года есть пометка, что можно, а что не надо передавать в атрибут SRC
, и там не рекомендуется указывать HTML-файлы. Видимо, кто-то пытался.
До стандарта HTML 2.0 были альтернативы того, каким образом выводить картинку, но победил именно тег IMG
. И мы сейчас с ним живём.
2020
В 2020 году стандарт немножко поразноцветнее, и в нём гораздо больше подробностей.
<img>
Давайте поговорим про тег
<img>
, и начнём с простой конструкции, которую вы, скорее всего, когда-нибудь писали:
<img>
Этого достаточно, чтобы начать работать с картинкой. JavaScript, например, может взять этот код и дополнить. Возможностей много.
Но по-хорошему нужно добавить хотя бы атрибут src
. Он про то, что нужно куда-то сходить, что-то скачать, а то, что скачается, каким-то образом отобразить.
<img src="https://habr.com/ru/post/559442/cats.png">
Когда вы так пишете, то даёте инструкцию браузеру сходить за ресурсом по относительному адресу
cats.png
. Браузер отправляет запрос с HTTP-заголовками, эти заголовки можно на сервере обрабатывать и принимать какие-то решения.
GET /img/cats.png HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) ...
Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: http://127.0.0.1:8080/img/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,ru-RU;q=0.8,ru;q=0.7
Например, мы получили заголовок
Accept
. Он про то, с какими форматами изображений браузер умеет работать. Вы можете увидеть: браузер отправил информацию, что он умеет работать с WebP. Даже если запрошен был файл в формате PNG, можно всё-таки в качестве ответа подсунуть WebP, сэкономив трафик. Раз браузер говорит, что умеет, — пусть работает.
Есть и другие сущности, которые можно получить из HTTP-заголовков. Их удобно использовать, чтобы экономить трафик, принимать другие решения.
Атрибут src
— мощная и сложная штука, потому что это один из немногих способов внутри HTML дернуть какой-нибудь URL. Ссылка — первый способ, но ссылка — это когда ты кликаешь сам, осознанно. А здесь пользователь ничего не нажимает, но куда-то идет запрос. Здесь речь и про безопасность тоже. Та ещё задача.
Форматы графики могут быть разные: gif, jpeg, ico, png, apng, tiff, svg, webp, avif и так далее. Это самые популярные из них. TIFF, кстати, до сих поддерживается в Safari. Другие браузеры я не проверял. Но официально поддержки вроде как нет.
Мы уже доросли до того, что AVIF — это поддерживаемый браузерами формат графики.
Про форматы изображений я в 2018 году читал отдельный доклад.
Он был про то, как любым способом доставлять картинки (в том числе через
background
), как и что сжимать.
Вот еще один способ дёрнуть какой-нибудь URL без HTML:
const img = new Image();
img.onload = function() { /* ... */ };
img.onerror = function() { /* ... */ };
img.src="https://habr.com/ru/post/559442/path/to/image.png";
Вы можете создать в JavaScript объект
Image
. Как только вы ему зададите
src
, браузер попытается этот
src
скачать. И по-хорошему вы должны добавить обработчик ошибок и обработчик загрузки. Получается, XHR не нужен! 🙂
Картинка — отличный способ дёрнуть URL, если вам не нужно обрабатывать нечто сложное. Всякие fetch
, разные счётчики, метрики или что там у вас на страницах — всё это вы можете отправлять, дёргая картинку. Возможно, кто-то из вас разбирался, как работают Facebook-пиксели и прочие счётчики. Там применяется как раз такой способ: если скрипт выключен — дёрни картинку. По этой картинке можно из HTTP-заголовков получить много полезной информации.
Нужно понимать, когда у картинки при загрузке вызывается обработчик onerror
в коде выше. Это произойдет в нескольких случаях:
- Когда
src
вы задали пустой:<img src="">
. Тогда дёрнетсяonerror
, потому что браузер не знает, что показывать. - Если вы укажете путь к текущей странице. Получается рекурсивный вызов:
<img src="https://habr.com/ru/post/559442/path/to/current-page">
. В браузерах есть механизм защиты: не будет никакой рекурсии, он просто сразу бросит ошибку и не станет издеваться над собой. - Если формат не поддерживается. Например, если вы из Internet Explorer решили загрузить формат WebP.
- Если вообще нет никаких данных о размерах картинки, браузер тоже не знает, как ему эту картинку нарисовать. Размеры могут прийти либо в метаданных, про них расскажу чуть позже, либо вы их задаёте атрибутами. Если в метаданных нет размеров и в атрибутах вы их тоже не задали, то браузер не знает, как и сколько резервировать места на странице, и бросает ошибку.
- Последнее — поломанное изображение, что-то с сетью или с самой картинкой. В целом, если что-то с сетью, скорее всего, какие-нибудь пакеты не дойдут и будет беда.
Окей, допустим, что картинка загрузилась. Это такой счастливый пример для разработчика — всё хорошо выглядит, нормально загрузилось.
А вот такой пример мы же тоже в жизни видели, да?
Почему-то ресурсы не доходят, и браузер рисует какую-то странную иконку. Что нужно делать?
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка.">
Атрибут
ALT
был ещё в первой версии спецификации
IMG
. Это замещение картинки для невизуальных браузеров или на случай, если картинка сломалась.
Если вы просто зададите alt
, это уже не будет какая-то иконка в вакууме. Это будет текст. И если вы копируете фрагмент страницы и внутри находится картинка с alt
, этот текст попадает в буфер обмена. Делать так даже в какой-то мере удобно, если там что-то информативное. Когда картинку нельзя скопировать, то можно скопировать хотя бы текст, описывающий эту картинку.
Есть важный нюанс: IMG
— заменяемый элемент. Это значит, если картинка загрузилась, то всякие псевдоэлементы вы ему задать не можете — потому что IMG так себя ведет. Но если картинка не загрузилась, там появляется целый shadow-root, который вы можете посмотреть в Chrome DevTools, если поставите галочку «Show user agent shadow DOM» в настройках. Так можно увидеть, что вместо картинки показывается полноценный новый HTML. Вы можете добавлять туда псевдоэлементы before и after. И это можно использовать.
Например, Ире Адеринокун предлагает интересный способ.
img {
font-family: 'Helvetica';
color: darkred;
text-align: center;
min-height: 3em;
display: block;
position: relative;
}
img::before {
content: "Картинка поломалась :(";
display: block;
}
img::after {
content: "(url: " attr(src) ")";
display: block;
}
Когда вы указываете картинке, например, стили про текст, шрифты, цвета, то вы на самом деле можете таким образом, во-первых, стилизовать этот текст в alt
. Во-вторых, добавить сюда ::before
и ::after
. И дать пользователю или разработчику понять, что картинка не загрузилась.
Например, для разработчика — возможно, для дебага — будет полезно добавить, как здесь в примере, img∷after
. И вы можете при помощи CSS-функции attr()
достать src
из картинки и показать сообщение: вот эта картинка сломалась, почини, пожалуйста.
Кажется, это даже можно автоматизировать. Например, парсить страницу через Puppeteer или еще чем-нибудь. Если какие-то картинки сломались, находите, какие именно, даже таким визуальным способом, и где-то их собираете. Хотя, конечно, профилировать запросы в сеть в этом смысле гораздо удобнее. Но есть и такой способ.
Но всё равно такой плейсхолдер выглядит не очень, да? А что, если мы его стилизуем?
img::after {
content: "эмодзи" " " attr(alt);
z-index: 1;
line-height: 3em;
color: rgb(100, 100, 100);
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #ccc;
}
Если у нас есть доступ к before и after, там же можно много чего натворить. Например, добавить after, приподнять его z-индексом над картинкой, чтобы не было видно стандартной иконки. И стилизуйте как хотите. Я эмодзи вставил — работает.
Главное — фантазия. У Лин Фишер, например, фантазии много, и есть сайт a.singlediv.com, где она на одном div
делает целые анимированные произведения искусства. У вас есть before и after, целых два псевдоэлемента, которые можно стилизовать. Задумайтесь.
Но, допустим, мы вообще не хотим сломанных картинок. Можно ведь использовать сервис-воркер! Как с ними быть?
Еще один пример от Ире Адеринокун.
self.addEventListener('fetch', (e) => {
e.respondWith(
fetch(e.request)
.then((response) => {
if (response.ok) return response;
// обработка ответа
})
.catch((err) => {
// обработка ошибки
})
)
});
В сервис-воркере есть возможность, если мы вешаем обработчик на событие
fetch
и видим, что запрос сработал хорошо, просто вернуть его результат браузеру. Сходили за ресурсом — он есть — вернули.
Но есть два случая: либо мы сходили за ресурсом и ответ — не ок, либо на каком-то из этапов выбросилась ошибка. Это, скорее всего, значит, что пользователь в этот момент находится офлайн. Что можно сделать?
Можно определить, был ли это вообще поход за картинкой или не за картинкой, сделать вспомогательную функцию для этого.
function isImage(fetchRequest) {
return fetchRequest.method === "GET"
&& fetchRequest.destination === "https://habr.com/ru/post/559442/image";
}
Можно добавить на установку сервис-воркера поход за картинкой
broken.png
, которая, например, будет плейсхолдером для всех сломанных картинок. Положить её в кэш, когда интернет ещё есть.
self.addEventListener('install', (e) => {
self.skipWaiting();
e.waitUntil(
caches.open("precache").then((cache) => {
cache.add("/broken.png");
})
);
});
Затем мы просто берем непонятные нам случаи — когда либо что-то с запросом, либо выбрасывается ошибка — и возвращаем из кэша уже то, что лежит на локальном устройстве пользователя.
self.addEventListener('fetch', (e) => {
e.respondWith(
fetch(e.request)
.then((response) => {
if (response.ok) return response;
if (isImage(e.request)) {
return caches.match("/broken.png");
}
})
.catch((err) => {
if (isImage(e.request)) {
return caches.match("/broken.png");
}
})
)
});
Вместо непонятной дефолтной иконки мы можем вернуть стильный плейсхолдер. Не стесняйтесь призвать дизайнера в помощь, чтобы сделать это красиво, а не своими силами рисовать плейсхолдеры при помощи CSS.
Конечно, можно пойти дальше и вообще все картинки закэшировать, чтобы они всегда возвращались. Но это не так интересно.
Хорошо. У нас есть атрибут alt
. Мы его заполнили, подписали картинку.
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка.">
Что будет, если мы атрибуту
alt
зададим пустое значение?
Во-первых, браузер не будет показывать эту сломанную иконку, когда картинка не загрузится. Вы даже не увидите, что у вас что-то не так. Не загрузилось, размеров нет, будет пусто. Во-вторых, для невизуальных браузеров это ещё и призыв не озвучивать картинку.
Таким образом, если у вас декоративное изображение, вы можете его спрятать.
Доступность
Картинки — визуальная штука. Людям с хорошим зрением, конечно, хорошо в интернетах сидеть и всё видеть, но я рекомендую вам сходить на
, — отличный ресурс, где собраны рекомендации, как минимальными усилиями сделать ваши сайты чуть более доступными.
Короткая выдержка оттуда. Есть изображения информативные и декоративные. Информативные — это которые про контент, когда пишется текст, следом идёт картинка, которая дополняет этот текст, и вы в alt
можете описать, что на этой картинке. Описывайте так, что если бы вы читали этот текст-описание, то как будто картинки даже не и было, можно её себе представить.
Декоративные — не несут особого смысла и, скорее всего, сделаны для красоты. Их можно спокойно выбросить, и ничего с текстом не случится.
У сайта «Веб-стандартов» есть CONTRIBUTING.md для тех, кто пишет статьи, переводы и так далее. У нас есть рекомендации, как всё это делать лучше. Совместно с Татьяной Фокиной сделали классные советы, которыми я хочу с вами поделиться.
- Если картинка декоративная — ставится пустой
alt
, но ставится обязательно. - Если картинка со смыслом, то в
alt
вы пишете ёмкое описание изображения. Не надо коротко — «картинка», «город». Опишите, что там находится. Избегайте повторения предложений, которые уже есть на странице, потому что скринридеры читают текст, а потом вы точно такой же вставляете вalt
, зачем? Он прочитается два раза. - Совет, который иногда даже вызывает холивары, хотя я не понимаю почему. В конце описания в
alt
ставьте точку. Когда скринридер читает и видит точку, он делает паузу перед тем, как читать что-то дальше. Так вот,alt
— это предложение. Не стесняйтесь ставить там точку, если это реально что-то контентное.
Про декоративные изображения. Как их ещё можно скрывать от скринридеров?
Можно унести их в background-image
. Это тот случай, когда можно сделать какой-нибудь div
вместе img
, тогда он спрячется, и всё.
Про пустой alt
мы уже поговорили.
Можно добавить атрибут role="presentation"
, всё это присыпать aria-hidden="true"
, чтобы наверняка.
Это хорошие практики. Если действительно что-то мешает чтению картинки на слух, используйте их.
Можно ещё вашу картинку обернуть в figure
.
<figure>
<img src="https://habr.com/ru/post/559442/picture.png" alt="Ёмкое описание картинки.">
<figcaption>
Информация об изображении
(например, фото: автор).
</figcaption>
</figure>
Так вы можете ёмкое описание картинки вставить в
alt
. А в
figcaption
описать сам файл. Например, указать фотографа или источник фотографии.
figcaption
— он скорее не про описание картинки, а про описание файла.
Если вы хотите запихнуть в картинку нечто сложное, например график, то я рекомендую посмотреть в сторону SVG и выставить для него правильную роль.
<svg role="img"
aria-label="Описание графика"
aria-described-by="chart-desc">
<desc id="chart-desc">
Подробное описание графика
</desc>
</svg>
Не забывайте про
role="img
, это важно.
Можно добавить aria-label
, aria-described-by
и полностью описать всё, что у вас на графике есть, полезно и подробно, при помощи desc
, который есть у SVG.
Здесь я рекомендую посмотреть замечательный доклад Сергея Кригера о том, как делать доступные графики, — на случай, если вам действительно нужно сделать график и описать его, чтобы все могли им пользоваться.
Вернёмся к котятам.
Я иногда видел советы — а зачем alt
, давайте писать всё в атрибут title
. Что такое title
? Это когда вы наводите на картинку, проходит сколько-то секунд в зависимости от браузера, и появляется маленький тултипчик.
<img src="https://habr.com/ru/post/559442/cats.png"
title="Три котёнка.">
Рекомендация: не делайте так. Это
. Во-первых, как часто вы ловили себя на том, что специально наводите курсор на картинку, чтобы прочитать, что на ней? Я себя только во время подготовки к докладу попросил так сделать. Во-вторых,
title
не участвует в построении дерева доступности. Многие скринридеры его банально не читают. Да, есть нюансы, но в целом эта штука кажется немного бесполезной, если есть
alt
. Есть атрибут, который помогает, используйте его.
Размеры
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка."
width="500">
Мы уже немного говорили о размерах. В браузере мы каким-то образом задаём ширину:
width=500
. Обратите внимание, что мы указываем не «500px». Не нужно задавать единицы измерения.
Итак, вы указываете это значение ширины. Тогда возникает вопрос: откуда браузер берёт второй размер, высоту?
А если задать только высоту, как браузер рассчитывает ширину? Откуда он её берет?
Здесь можно копнуть глубже. Например, вы можете расковырять ваши картинки как бинарные файлы и посмотреть в спецификации.
В спецификации PNG первые восемь байт вообще прибиты гвоздями, эти байты и говорят, что это PNG-файл. Дальше всякая служебная информация, и есть кусочек, я его подсветил выше, который говорит: ширина и высота вот такие. Прямо в первых, буквально заголовочных кусках файла есть размеры.
С GIF всё ещё проще, потому что сам формат проще.
Тут можно сходу сказать, что у этой гифки размеры 500×275. Можно прямо в текстовом редакторе посмотреть.
С JPEG — сложнее. Cходу такой же красивый и наглядный пример вам собрать не смог, потому что там много интересного, но не очень очевидного. С WebP даже не пытался.
Но для любых графических форматов есть правило: в самом верху файла, буквально с первыми пакетами при скачивании приходит размер. Как только браузер делает запрос за картинкой, и картинка начинает приходить, браузер тут же выцепливает эти размеры и резервирует с их учётом под картинку место.
Очень рекомендую доклад Полины Гуртовой «Картинки как коробки. Что же там внутри?». Полина классно рассказала, как вообще всё внутри устроено, про разные форматы, в том числе про PNG, о котором я только что говорил. Есть видео и расшифровка на Хабре, обязательно почитайте.
Если в метаданных картинки нет этих самых размеров, то мы можем их задать сами: width
, height
выставили, и счастье.
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка."
width="500" height="275">
Тут важно задавать правильные размеры. Я думаю, все вы видели эти ужасные случаи, когда прямоугольная картинка из-за криво заданных размеров зачем-то вписывается в квадрат, и получается нечто непропорциональное. Поэтому здесь хорошо бы, конечно, прикрутить какую-то автоматику. Но если вы делаете это руками, скорее всего в бизнес-процессах есть этап добавления картинки где-нибудь в вашей админке, если контентом занимается контент-менеджер. Там вы можете получить размеры, сохранить их в базу и потом подставлять эти размеры в клиентский код. Например, подставлять физические размеры картинки, как есть. А уже дальше в CSS вычислить, что с ними делать.
Есть ещё интересный атрибут intrinsicsize
, он про пропорции. Если мы не хотим задавать четкие значения width
, height
, а хотим делать картинки 16×9 или 400×300, то можем задать это таким атрибутом.
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка."
intrinsicsize="400x300">
Но на самом деле нет, уже не можем. Авторы спецификаций обсуждали-обсуждали и пришли к тому, что, кажется, можно сделать
.
<style>
img {
width: 100%;
height: auto;
aspect-ratio: attr(width) / attr(height);
}
</style>
<img src="https://habr.com/ru/post/559442/image.jpg" width="500" height="500">
Подход такой. Раз есть атрибуты
width
и
height
, которые вроде как рекомендуется указывать всегда, в CSS можно использовать свойство
aspect-ratio
, которое их получает функцией
attr()
, или прибивает гвоздями, что у этой картинки пропорции должны быть 16×9 или 500×500.
Поддержка у этого свойства достаточно хорошая, на мое удивление. Уже можно, даже нужно, 66% пользователей будут счастливы.
Есть нюанс: вы можете задавать не конкретные пропорции, а только маппинги на width
и height
. И так умеют уже 89% браузеров. Поэтому вперёд!
Загрузка
Дальше можно поиграться с тем, как вообще эту картинку получить.
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка."
width="500" height="275"
referrerpolicy="origin">
Для начала можем задать, какую информацию мы отправляем на сервер. Вы же иногда подключаете картинки из каких-нибудь CDN или с внешних ресурсов, не только у себя их держите.
Так вот, referrerpolicy
— это атрибут, который говорит, например: тут отправляй домен, а тут вообще не отправляй заголовок referrer
.
res.cloudinary.com
:method: GET
:path: /.../picture.png
:scheme: https
accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,ru-RU;q=0.8,ru;q=0.7
cache-control: no-cache
pragma: no-cache
referer: http://example.com/
sec-fetch-dest: image
sec-fetch-mode: no-cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) …
В данном случае я чётко говорю браузеру: отправляй, пожалуйста, только домен и все. Больше ничего не надо, полный URL отправлять не надо. В конце концов это тоже информация, которую тот, кто хранит картинку, может использовать.
Если вы доверяете своему CDN, отправляйте всё что угодно, конечно. Но лучше аккуратно. По умолчанию стоит такое значение referrerpolicy
, которое говорит, что с http-сайта сходить за https-картинкой можно. А вот наоборот не отправляются заголовки, когда это не безопасно.
Ещё один вариант — это когда вы ходите за картинкой на другой домен.
<img src="https://another.com/cats.png"
alt="Три котёнка."
width="500" height="275"
crossorigin>
Если просто рисовать картинку через тег — да, всё нарисуется. Но если вы хотите, например, получить и нарисовать эту картинку где-нибудь в
canvas
, то вы таким образом получаете доступ чуть ли к этим бинарным данным, к исходнику картинки.
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const image = document.getElementById('source');
ctx.drawImage(image, 0, 0);
// DOMException: Failed to execute 'getImageData'
// on 'CanvasRenderingContext2D':
// The canvas has been tainted by cross-origin data.
Понятно, что мы, разработчики, можем эту картинку скачать себе любым другим способом и расковырять её у себя локально. Но если вы не настроили cross-origin запрос, то от браузера получите ошибку DOMException. Она будет говорить: простите, данные с другого домена — нельзя. И в этом случае нужно добавить атрибут
crossorigin
картинке, чтобы всё заработало.
У него есть в том числе и значение. По умолчанию это анонимный CORS-запрос. Он такой идёт на сервер: «Ну, пожалуйста, можно я поковыряюсь в байтиках?» И если сервер в ответ: «А, давай! Пожалуйста, на тебе Accept, бери всё и ковыряй», — то в canvas вы сможете поиграться с данными.
На самом деле это история не только про canvas. Например, вы хотите бинарные данные в LocalStorage положить. Подходов и применений много, но вам нужно получить доступ к бинарникам.
Яркий пример — CodePen. Если вы там когда-нибудь рисовали на canvas что-то из внешних изображений, то, возможно, сталкивались с ошибкой доступа к данным. Я сталкивался. Приходилось хранить картинки в base64, потому что у меня бесплатный аккаунт.
Ещё есть атрибут loading
.
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка."
width="500" height="275"
loading="lazy">
И он вроде как классный, но есть нюансы. У него три значения:
auto
— значение по умолчанию, браузер сам решает, когда загружать картинку.eager
— значит, загружать сразу. Когда HTML-парсер находит картинку, он сиюминутно отправляет за ней запрос.lazy
— это когда мы говорим браузеру: «Мне когда-нибудь эта картинка понадобится, но давай ты сам определишь, когда именно, и тогда за ней и сходишь». Полезно для экономии трафика.
На самом деле атрибут обалденный. Если по умолчанию он включается и ставится
lazy
везде, кроме, конечно, первого viewport, то вы сходу получаете экономию трафика и пользователю, и себе. Вам же, наверное, нужно оплачивать инфраструктуру. Это бесплатная польза минимальными усилиями.
Но, например, в исходном коде Chromium можно найти такие интересные настройки.
Offline — 8000
Slow 2G — 8000
2G — 6000
3G — 2500
4G — 1250
Когда соединение офлайн или очень медленное, то браузер загружает все картинки в пределах 8000 пикселей от текущего вьюпорта. При этом на самом быстром соединении — в пределах 1250 пикселей.
Причем значения постоянно меняются. Я так понимаю, разработчики браузеров проводят замеры, эксперименты, в интернете идут холивары, какие числа более правильные, потому что каждый браузер немножко по-своему их подбирает.
Чем хуже соединение, тем больше картинок качается. Это не очень очевидно, и вам нужно понимать, что это не про экономию трафика, а именно про скорость соединения.
Зачем так сделано — объяснение простое. Пользователь обычно страницы скроллит. И на медленном соединении, пока он доскроллит, уже всё должно быть хорошо, хорошо видны картинки. У пользователя должен быть потрясающий опыт пользования вашей страницей.
Чем медленнее соединение, тем раньше за картинкой нужно сходить. На быстром соединении оно вроде как быстро загрузится, зачем париться?
Но эти значения — 1250 — достаточно большие. Используйте на свой страх и риск, если вы в первую очередь задумывались про экономию трафика, а не про скорость.
В официальной статье про lazy loading на web.dev описан способ, как это сделать с поддержкой браузеров, которые не умеют в нативную ленивую загрузку.
<img src="https://habr.com/ru/post/559442/hero.jpg" alt="…">
<img data-src="https://habr.com/ru/post/559442/unicorn.jpg" alt="…" loading="lazy" class="lazyload">
<script>
if ('loading' in HTMLImageElement.prototype) {
const images = document.querySelectorAll('img[loading="lazy"]');
images.forEach(img => {
img.src = img.dataset.src;
});
} else {
const script = document.createElement('script');
script.src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.1.2/lazysizes.min.js";
document.body.appendChild(script);
}
</script>
Если умеют — вы сможете в прототипе
HTMLImageElement
найти свойство
loading
. Тогда, например, в атрибут
data-src
можно положить URL картинки, как мы делали еще до появления этого свойства, а потом его перекинуть в
src
.
Если нет, то взять библиотечку, которая сделает то же самое, но уже без браузерных механизмов. Если вновь поковыряться в коде того же Chromium, там точно так же создается Intersection Observer, как если бы вы это делали руками. И точно так же, но с более внутренними механизмами, делается всякая магия: «Ага, здесь мы определяем, сколько до вьюпорта, дальше качаем».
Если у пользователя JS выключен, loading
ставьте сколько хотите и какой хотите — всё равно будет применено значение auto
. Это сделано для приватности данных, потому что если JS выключен, картинкой вы всё ещё можете по скорости соединения и порядку скачивания при ленивой загрузке вычислить, что это за пользователь. Фингерпринтинг. А если пользователь выключает JS, то он, может быть, не хочет фингерпринтинг.
Есть ещё одна интересная штука — атрибут decoding
.
<img src="https://habr.com/ru/post/559442/cats.png"
alt="Три котёнка."
width="500" height="275"
decoding="async">
Это когда вы уже прямо тюните сайт под перформанс.
- Вы можете выставить значение
sync
. Это когда у вас рисуется что угодно, например текст. И картинка тут же декодируется, чтобы нарисоваться рядом. async
— это сказать браузеру: «Когда будут ресурсы, тогда и декодируй».- И
auto
— это, опять же, пусть решает браузер, значение по умолчанию.
У Эдди Османи есть отличное объяснение в твиттере, почему этот атрибут в целом важен:
В голове у нас процесс такой: картинка загрузилась, потом нарисовалась. На самом деле в серединке, между «загрузилось» и «нарисовалось», есть декодинг и ресайз картинки, не нулевые по времени процессы.
Декодинг картинки на среднестатистическом устройстве Moto G — это 300 миллисекунд в примере Эдди, заметно даже глазом. Стоит задуматься, что большие картинки декодируются дольше и, может, их надо позже декодировать, если не хотим зря тратить ресурсы. Важно: желательно не давать браузеру и ресайзить тоже. Пускай сразу приходит только самое нужное.
Помните: когда у вас выполняется JS, он блокирует основной поток. Будем считать, что браузер однопоточный, и вы блокируете рендеринг. Если вы выполняете долгий JS, то и картинка не нарисуется. Потому что браузер в этот момент занят, он ваш while (true)
обрабатывает.
Штука, которая вызывает много вопросов по первости: как работают srcset
и sizes
? Я в несколько подходов разбирался и думаю, что наконец разобрался.
Есть такая запись.
<img srcset="https://habr.com/cats-320.jpg 320w,
https://habr.com/cats-480.jpg 480w,
https://habr.com/cats-800.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
100vw"
src="https://habr.com/ru/post/559442/cats-800.jpg">
- В
srcset
вы задаете картинки, а рядом — маппинг на физический размер этих изображений. Что, значит физический? Это значит, что вы нажимаете в контекстном меню в системе «Информация о файле» и сколько пикселей лежит в этом файле, столько и нужно указывать.srcset
— про физическую ширину. - Дальше в
sizes
вы указываете размер области под картинку, которая должна загрузиться. Берете медиавыражения и указываете, что, например, если у viewport ширина 320 пикселей, значит, мне нужно выделить область под картинку в 280 пикселей. Вы одновременно таким образом задаетеwidth
у картинки.
Что дальше сделает браузер? Он из
srcset
постарается выбрать самое подходящее по размеру изображение.
Здесь самое интересное. Спеки четко не прописаны, инструкция — грузить изображение, которое явно больше. То есть браузеры решают сами, как это оптимально сделать. И в разных браузерах поведение разное.
Chrome, например, выбирает картинку больше. То есть ближайшую не меньшую, так будет правильнее. Вот вы указали sizes
. Например, у вас сработало: «Бери 280 пикселей» и Chrome постарается найти ближайшую картинку: 320. Если выбор пал на размер 440, какую картинку выбрать по ширине: 320 или 480? Он выберет 480, потому что ближайшая не меньшая.
В srcset
ещё можно указывать плотность пикселей.
<img src="https://habr.com/ru/post/559442/picture.png"
srcset="https://habr.com/picture@2x.png 2x">
«2x» — это Retina, сюда мы можем засунуть наши изображения повышенной чёткости и отдельно их загружать. Прелесть подхода: если HTML-парсер не понимает инструкцию
srcset
, но умеет в
src
, то он загрузит
src
. Это как fallback, будет работать во всех браузерах, даже самых старых.
Важно: чтобы с такой адаптивностью работать, не забывайте использовать метатег viewport
, где вы будете чётко задавать, как соотносится физическая и логическая ширина на устройстве.
<meta name="viewport"
content="width=device-width">
Иначе вы будете очень долго дебажить, почему вы просите одну картинку загрузить, а она вообще не та.
Вы можете позамерять, насколько эффективно вы используете картинки на странице. Например, я зашел на сайт GDG Russia при помощи пакета imaging-heap от Filament Group.
Там есть очень интересный логотип — всегда приходит размером 1706 пикселей. При этом этот логотип всегда занимает не больше 20 пикселей. В целом там трафика немного, картинка достаточно оптимизирована, проглядывается конструктор сайтов Tilda. Но imaging-heap позволяет посмотреть, насколько эффективно картинки используются на странице. Я им часто пользуюсь. Он умеет не только смотреть в теги img
, но ещё и в background-image
умеет залазить. Обязательно воспользуйтесь, поинспектируйте хотя бы свой сайт.
Давайте расширим img
. Уже давно есть тег picture
, обёртка над img
, своего рода прокси, который в себя принимает кучу всяких штук и по факту потом всё равно прокидывает все это в img
.
<picture>
<source type="image/avif"
srcset="https://habr.com/cats.avif">
<source type="image/webp"
srcset="https://habr.com/cats.webp">
<img src="https://habr.com/ru/post/559442/cats.jpg"
width="20" height="20">
</picture>
Вы можете добавить разные
source
. Кстати, вопрос: почему
source
обрабатываются сверху вниз? Применяется первый срабатывающий
source
, дальше не применяется. Почему не последний?
Объяснение тоже простое. Как работает HTML-парсер в браузере? Просто идёт по коду слева направо и парсит его. Когда ваши страницы приходят чанками, то браузер получит кусочек, в нём найдёт picture
, и если по source
сразу понятно, что он подходит, браузер сразу сможет отправить запрос за подошедшей картинкой, не дожидаясь следующего HTML-чанка. Клёво. Поэтому source
работает сверху вниз: что первое пришло, то и применится.
Прелесть в том, что мы можем поддерживать разные форматы. Не так уж давно зарелизился формат AVIF, в Chrome он уже поддерживается.
У Джейка Арчибальда есть потрясающая статья, которая объясняет, почему этот формат клёвый, в каких случаях он работает хорошо. Вы можете увидеть, что для некоторых картинок AVIF сжимает лучше, чем SVG. У меня в голове это по первости не укладывалось — это же векторный формат, а нас учили, что векторный формат занимает мало. Ничего подобного.
AVIF — это видеокодек AV1, который оптимизирован и адаптирован под изображения. Внезапно видеокодек позволяет сжимать картинки лучше, чем специальные картиночные форматы.
Обязательно посмотрите в статье Джейка, что это за формат такой. Кажется, его уже пора использовать.
Ингвар Степанян в твиттере поделился отличным способом, как вообще при помощи JavaScript минимальным кодом определять, поддерживает ли браузер тот или иной формат.
async function supportsImgType(type) {
let img = document.createElement('img');
document.createElement('picture').append(
Object.assign(document.createElement('source'), {
srcset: 'data:,x', // валидный URL, который не дёргает сеть
type
}),
img
);
await 0; // даём примениться currentSrc
return !!img.currentSrc; // если браузер умеет, он заполнит значение currentSrc
}
for (let type of ['image/png', 'image/jpeg', 'image/webp', 'image/avif']) {
supportsImgType(type).then(supported => console.log(`${type}: ${supported}`));
}
Прикольно: вы просто создаете фиктивный
picture
. В этот
picture
вы кладете
source
, для которого в
srcset
кладете минимально валидный URL
data:,x
. Это валидный URL, но он не дёргает сеть, то есть даже не нужно ходить ни на какой сервер. Если браузер умеет в такой тип, он просто заполнит у картинки
currentSrc
. Очень простой сниппет, и вы можете проверить поддержку почти любого формата.
Давайте расширять наш picture
.
<picture>
<source type="image/avif"
srcset="https://habr.com/cats@1x.avif 1x, https://habr.com/cats@2x.avif 2x">
<source type="image/webp"
srcset="https://habr.com/cats@1x.webp 1x, https://habr.com/cats@2x.webp 2x">
<img src="https://habr.com/ru/post/559442/cats@1x.jpg"
srcset="https://habr.com/cats@2x.jpg 2x"
width="20" height="20">
</picture>
Мы знаем, что есть
srcset
. Сюда также можно положить картинки для ретины.
Ещё у нас есть медиавыражения. Мы можем точно так же под разные медиавыражения получать разные картинки. Например, смотрим на высоту изображения, ширину вьюпорта и берем более широкую, десктопную картинку. А для маленьких экранов — мобильную.
<picture>
<source type="image/avif"
media="(min-width: 1150px)"
srcset="https://habr.com/cats-desktop@1x.avif 1x, https://habr.com/cats-desktop@2x.avif 2x">
<source type="image/avif"
srcset="https://habr.com/cats-mobile@1x.avif 1x, https://habr.com/cats-mobile@2x.avif 2x">
<source type="image/webp"
media="(min-width: 1150px)"
srcset="https://habr.com/cats-desktop@1x.webp 1x, https://habr.com/cats-desktop@2x.webp 2x">
<source type="image/webp"
srcset="https://habr.com/cats-mobile@1x.webp 1x, https://habr.com/cats-mobile@2x.webp 2x">
<source media="(min-width: 1150px)"
srcset="https://habr.com/cats-desktop@1x.jpg 1x, https://habr.com/cats-desktop@2x.jpg 2x">
<img src="https://habr.com/ru/post/559442/cats-mobile@1x.jpg"
srcset="https://habr.com/cats-mobile@2x.jpg 2x"
width="20" height="20">
</picture>
Звучит страшно: WebP, AVIF, JPG, PNG, все эти retina, да еще и под разные размеры! Как с этим работать?
Можно, конечно, попробовать руками.
Я обожаю инструмент Squoosh, там уже поддерживается AVIF. Так вот, Squoosh позволяет сжимать картинки, менять их размеры и не только. Но руками это долго.
Ещё пользуюсь ImageOptim. Например, некоторые картинки для этого доклада сжаты там. Тоже потрясающий инструмент. Но это всё — не автоматизация.
Для доклада собрал свой подход. Я фанат Gulp. Можете посмотреть у меня в репозитории: mefody/image-processor.
Использую простые пакеты: gulp-imagemin, gulp-responsive, imagemin-guetzli, imagemin-pngquant, imagemin-svgo, imagemin-webp. Думаю, у вас может быть похоже.
Я просто из этого стартера собираю себе почти под любой проект оптимизатор картинок, который распиливает их по разным размерам. gulp-imagemin внутри себя содержит imagemin.
gulp.task('convert', gulp.series(
'clean',
'convert:retina',
'convert:webp',
'convert:avif',
gulp.parallel(
'optimize:guetzli',
'optimize:png',
'optimize:svg'
),
));
Чем этот пакет хорош? Тем, что туда можно подключать новые плагины. Но там пока нет поддержки AVIF (
на момент подготовки доклада — прим. автора
).
Зато там есть поддержка Guetzli. Этот алгоритм тоже разработан в Google. В чем его суть?
Что обычно делают оптимизаторы? Они снижают качество у JPG, не меняя информацию о цвете. А Guetzli ещё и меняет цвета картинок, но так, чтобы визуально для глаза это почти не чувствовалось. Ключевое слово — «почти». И оказывается, за счёт такого незаметного изменения цветов можно сделать сжатие значительно круче.
Но происходит страшное. Даже на картинке 1000×1000 у вас начинает жужжать ноутбук, всё это обрабатывается очень долго. Алгоритм банально делает очень много разных переборов и сравнений. При этом сжимает настолько потрясающе, что у меня JPG обычно весят меньше, чем WebP. Поэтому я могу из своих source
в принципе выкидывать ненужный мне WebP. Но, кстати, объём у сжатых через Guetzli картинок всё равно больше, чем у AVIF. Я попробовал.
Кстати, «guetzli» — это, я так понимаю, сладость, скандинавская выпечка. Как-то в подкасте мы пытались выяснить, что такое guetzli, brotli, zopfli. Оказалось, всё это — выпечка.
AVIF уже, на самом деле, в gulp засунуть можно, но через костыли.
const gulp = require('gulp');
const exec = require('gulp-exec');
const config = require('./config');
gulp.task('convert:avif', () => {
let src = `${config.base.dist}/**/*.{jpg,png}`;
return gulp.src(src)
.pipe(exec((file) =>
`avifenc -c aom --min 20 --max 50
${file.path}
${file.path.replace(/(png|jpg)$/ig, 'avif')}`
));
});
Потому что под imagemin пакета нет (
уже есть — прим. автора
), но у вас есть возможность вызвать
gulp-exec
, который дёргает какую-нибудь команду прямо у вас на локальной машинке. Я так и сделал, и оно работает. Достаточно просто, но при этом меньше контроля из Node.js: вы не можете количество файлов отслеживать в прогрессе, но, наверное, в будущем это будет возможно.
Для этого ещё нужно дополнительное шевеление бубном на Mac.
brew install joedrago/repo/avifenc
Я устанавливаю пакеты через brew.
avifenc
— это C++-пакет, который умеет работать с AVIF.
Словом, работу с AVIF уже можно автоматизировать. Не ленитесь.
Что ещё можно делать? Например, дёргать всего одну картинку, которую положить на CDN, который будет сам решать, что отдавать.
https://imgproxy.evilmartians.com/PzslbQaEHzr9AEfdvP0UCF49tg0S1PoQiGsHrNyf11s/rs:fill:960:540/dpr:2/g:ce/wm:0.5:soea:0:0:0.2/wmu:aHR0cHM6Ly9pbWdwcm94eS5uZXQvd2F0ZXJtYXJrLnN2Zw/plain/https:%2F%2Fwww.nasa.gov%2Fsites%2Fdefault%2Ffiles%2Fthumbnails%2Fimage%2Fpia22228.jpg
Например, у «Злых Марсиан» есть проект
. Очень рекомендую вам на него посмотреть. С ним можно всевозможными настройками задать размер, retina/не retina. Даже водяные знаки можно рисовать. Подобные CDN позволяют вам не думать про сборку. У вас есть только исходник, а уже CDN берет на себя часть работы, чтобы этот исходник, например, при первом обращении обработать, закэшировать и отдать.
Это один из подходов. Почему бы и нет? Каждый из нас живет в эпоху, когда всё рассчитывается на клиенте. Если у вас какой-нибудь React, который на ходу всё равно всё знает про браузер, — можете попробовать использовать походы в CDN вместо picture
и source
.
Ещё одна важная штука. В media
вы можете задавать любые медиазапросы, не только про ширину и высоту. Например, можно подсмотреть, что у пользователя установлена настройка, что он любит тёмную тему.
<picture>
<source srcset="https://habr.com/picture-dark.png"
media="(prefers-color-scheme: dark)">
<img src="https://habr.com/ru/post/559442/picture-light.png">
</picture>
Раз он выставил её у себя в системе, так дайте ему отдельную картинку для тёмной темы. Потому что если вы на черной странице нарисуете яркую белую гифку, пользователь чуть-чуть ослепнет и будет ваш сайт чуть-чуть не любить.
Когда пользователь будет между разными темами переключаться, это, кстати, может произвести вау-эффект.
Ещё важно помнить про пользователей, которые не любят движение на сайтах.
<picture>
<source srcset="https://habr.com/no-motion.jpg"
media="(prefers-reduced-motion: reduce)">
<img srcset="https://habr.com/animated.gif">
</picture>
Например, у человека может быть эпилепсия. Уважайте убеждение таких пользователей о том, что они не хотят смотреть ваши гифки. И, например, когда стоит настройка
prefers-reduced-motion
, то просто отдавайте статический кадр.
А вот если пользователь нормально относится к гифкам, рисуйте ему эти гифки. Хотя есть отдельный доклад Вадима Макеева pepelsbey «Делайте из слона муху», где он говорит, что не надо. Лучше подключайте видео, потому что GIF безумно много весит.
Пятиминутка ностальгии
И другие атрибуты, из прошлого.
Я вам показывал, что можно было делать карты. Теперь поговорим про картинки. Вы можете задать картинке атрибут usemap
, который позволял кликать на картинки, на кусочки картинок.
<p>
Please select a shape:
<img src="https://habr.com/ru/post/559442/shapes.png" usemap="#shapes">
<map name="shapes">
<area shape=rect coords="50,50,100,100"> <!-- the hole in the red box -->
<area shape=rect coords="25,25,125,125" href="https://habr.com/ru/post/559442/red.html" alt="Red box.">
<area shape=circle coords="200,75,50" href="https://habr.com/ru/post/559442/green.html" alt="Green circle.">
<area shape=poly coords="325,25,262,125,388,125" href="https://habr.com/ru/post/559442/blue.html" alt="Blue triangle.">
<area shape=poly coords="450,25,435,60,400,75,435,90,450,125,465,90,500,75,465,60"
href="https://habr.com/ru/post/559442/yellow.html" alt="Yellow star.">
</map>
</p>
Вы рисовали нечто похожее на SVG, но это не SVG. И вы, задав область, в которую пользователь кликает, могли указать ссылку, которой нужно обрабатывать этот клик. Из картинки можно было сделать ссылку, без тега <a>
.
Это прикольно, и, кстати, оно до сих пор работает в браузерах. Кажется, в Safari есть нюансы, но в целом вроде как работает. Сейчас непонятно, зачем, но поиграться можно.
Еще был атрибут ismap
.
<a href="https://habr.com/imagemapper">
<img src="https://habr.com/ru/post/559442/image.png" ismap />
</a>
Кстати, он и сейчас работает, я проверил. Но для него нужна серверная поддержка. Если вы пишете
ismap
, это говорит о том, что ссылки, которые оборачивают картинку, когда я кликаю, дополнительно задаются как CGI параметры — через координаты точки, по которой вы в этой картинке кликнули. X и Y относительно левого верхнего угла. Например,
/imagemapper?3,9
. Здесь 3 — смещение по горизонтали, 9 — смещение по вертикали.
Таким образом можно одну картинку-меню сделать, обработать на сервере, узнать, куда пользователь кликнул. И, например, нарисовать иконки, в которые надо кликать.
Так делали раньше. Сейчас я таких обработчиков уже не встречал, но если хотите поприкалываться, почему бы и нет.
И есть deprecated-атрибуты, такие как align, border, hspace, vspace, name, onerror. Они браузерами всё ещё поддерживаются. Работает обратная совместимость веба: нельзя просто сломать половину сайтов.
Но считается, что вместо них уже нужен CSS. Причем атрибут align
работает интересно, позволяет внутри блоков всякое выравнивать. Вроде как можно через float
это всё сделать, но align
более гибкий, что ли. Мне он в своё время нравился, а сейчас он уже deprecated.
Рамки
Есть задача, которая часто встаёт перед разработчиками, — поместить картинку в какие-то рамки.
Если просто выровнять по ширине — пожалуйста.
img {
max-width: 100%;
height: auto;
}
Максимальную ширину ставим 100%, высоту — auto, и браузер масштабирует как надо. Всё будет хорошо для горизонтальных картинок.
А что если нам нужны заданные пропорции? Например, часто есть такой заказ: «Давай вставим превьюшку с YouTube, которая обязательно должна быть 16×9».
Есть старый-добрый padding-хак.
.img-container {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
height: 0;
overflow: hidden;
}
.img-container img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Вы создаёте контейнер нулевой высоты, ставите у него
padding-bottom
. Напоминаю,
padding-bottom
рассчитывается от ширины. Внезапное поведение.
Так вы чётко задаете пропорции 16×9. Кстати, сюда можно вставить calc()
, например, чтобы было совсем понятно. И внутри просто через absolute
эту картинку выравниваете. В итоге у вас есть контейнер, который переполняется, обрезается, и внутри как-то рисуется картинка.
Можно проще.
.img-container img {
object-fit: cover;
}
Для всего этого уже можно использовать
object-fit
, не надо настолько упарываться. Он более гибкий, более удобный. При помощи
object-position
вы можете дотюнить поведение, если что-то приклеилось к низу или к верху.
Поддержка уже хорошая, но если вам нужно поддерживать много всякого, то, опять же, у Вадима Макеева на его канале есть подробный разбор.
Кадрирование
Когда вы используете
object-fit: cover
, может произойти кадрирование. Предположим, разработчик вставил картинку с неожиданными пропорциями, и котёнка немножечко покоцало.
Как это делать правильно? Если вам обязательно нужен object-fit: cover
, — идея! Давайте попробуем Machine Learning, так делают крупные корпорации, я видел, Twitter так делает.
Но будьте аккуратны, потому что Twitter с таким угодил в скандал. Оказалось, что алгоритм, который определял, как правильней кадрировать, был расистским. Публично извинялись. Машинное обучение — вроде крутая штука, но там ещё очень много проблем в том, как определить, что показывать.
Мне нравится подход, который случайно нашел на CodePen.
<div class="img-container">
<img src="https://habr.com/ru/post/559442/picture.png"
alt=""
class="img-blur"
aria-hidden="true">
<img src="https://habr.com/ru/post/559442/picture.png" alt="Picture">
</div>
Вы можете использовать две картинки, тогда у вас не будет пустого пространства. Точнее, URL у картинок одинаковый. Но подключаете вы их в контейнере друг за дружкой. Первую прячете, чтобы ее не было слышно, например, на скринридере.
.img-container > * {
position: absolute;
top: var(--offset, 0);
left: var(--offset, 0);
width: calc(100% - 2 * var(--offset, 0px));
height: calc(100% - 2 * var(--offset, 0px));
object-fit: contain;
}
.img-blur {
--blur: 20px;
--offset: calc(-1 * var(--blur));
object-fit: cover;
filter: blur(var(--blur));
}
Затем при помощи хитрых хаков вторая картинка вся целиком помещается в контейнер. А вторая —
object-fit: cover
, растягивается на весь контейнер. И вы ее блюрите.
В итоге у вас получается вот такой эффект:
Красиво. На YouTube некоторые блогеры вертикальные видео похоже обрабатывают.
По ссылочке есть полный код, как это сделать. Мне такой подход больше нравится, потому что мы хотели заполнить всё, — заполнили, при этом картинку видно всю, а мы ничего лишнего не обрезали.
Знаете, что у картинок есть в CSS особенность — там можно задавать способ, как их рендерить?
.pixelated {
width: 512px;
height: 512px;
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-crisp-edges;
image-rendering: pixelated;
image-rendering: crisp-edges;
}
По умолчанию браузер, увеличивая вашу картинку, как-то её смазывает. Есть алгоритм, который делает это сглаживание. Вы можете сказать: «Нет, браузер, я хочу pixelated». И, увеличивая картинку, он будет реально рисовать чёткие границы пикселей.
Это полезно, если у вас, например, сайт про пиксельную графику, Lego, что-то с этим связанное. Я на некоторых сайтах видел — обалденный эффект. Выставляете маленькую иконку, скажем, 12×12, растягиваете ее, и такой пиксельный эффект сохраняется. Это ещё и обалденная экономия трафика.
Быстрее
Как можно еще быстрее грузить картинки?
<link rel="preload"
as="https://habr.com/ru/post/559442/image"
href="https://habr.com/ru/post/559442/important-image.jpg">
Вы можете заранее сказать браузеру при помощи тега
link
: «Браузер, вот эта картинка мне точно понадобится». Дело в том, что по умолчанию картинки грузятся с приоритетом Low — низким. Но предположим, вы скажете: «Браузер, вот
preload
, это очень важная картинка, она у меня обязательно рисуется». Тогде браузер будет её качать, во-первых, с более высоким приоритетом, а во-вторых, ещё до того, как вы обратитесь к этой картинке в HTML или CSS.
Есть подробный разбор от Эдди Османи, как эта штука работает. Можете посмотреть, как preload
помогает ресурсы больше скомпоновать и загрузиться быстрее.
Итоги
- Выбирайте правильный формат изображений.
Есть куча материалов о том, как и что выбирать. Мой выбор простой. Если есть возможность использовать AVIF — так и делайте. Если есть поддержка WebP — используйте его. Дальше оптимизируйте JPG, оптимизируйте PNG. Последний, кстати, тоже хорошо сжимается, если правильно настройки покрутить.
- Выбирайте правильный размер.
Не заставляйте браузер зачем-то рисовать огромную картинку, если она лежит в окошке 20×20 пикселей. Вы и трафик экономите таким образом, и не даете CPU тратить время на ресайз.
- Всё автоматизируйте.
Надеюсь, image-processor, который я для вас собрал, будет вам полезен. Я, по крайней мере, им пользуюсь. Может, и вам пригодится.
Есть еще классные материалы, которые я могу посоветовать:
- Images done right: Web graphics, good to the last byte. Классная статья от «Злых марсиан», прямо внутренности того, как это всё устроено. Один из авторов — Полина Гуртовая. Обалденная статья, обязательно посмотрите.
- A Guide to the Responsive Images Syntax in HTML. Классный гайд о том, как делать адаптивно любыми способами.
- Essential image optimization. Обалденная интернет-книга от Эдди Османи о том, что с картинками можно делать. Сначала она была первой в списке, но там сломались картинки. Вот такая ирония. Остался только текст. (Теперь срабатывает редирект на отдельный сайт — прим. автора.)
Все ссылки —
.
Cruz, 48, remained in custody for the fatal stabbing of a fellow tenant
last weekend, only a few days before the victim’s planned wedding day.
The slaying came as no surprise inside the Sand Castle apartment complex, where shaken residents recounted tales from the accused killer’s alleged years-long reign of terror.
pubg mobile free account
Özellikle aktarlarda satılan bir çok gıda takviyesi bulunmaktadır.
Bunlardan biri olan fx15 içeriği de oldukça merak uyandırmaktadır.
Web de yer alan bilgilere baktığınız zaman içeriğinde Çinko (4 mg), C vitamini (30 mg), Üzüm Çekirdeği
Eksresi (10 mg), ikro Kristalin Selüloz (98 mg) bulunduğu bilgisini görebilmektesiniz.
Ürün doğal bir gıda takviyesi olarak geçse de yine de kullanmadan önce hekiminizden bilgi almanız gerekmektedir.
fx15 içeriği
For a few people who have more sustenance, it is sort of straightforward
to reach some portions of the sport that may only be accessed with
dollars. But obviously, everyone likes free things,
appropriate.
Free Roblox Accounts With Robux 2022 | Account And
Passwords
free roblox accounts
Özellikle pandemi döneminde e-ticaretin hızla gelişmesiyle online platformlarda
bir çok satıcı satış yapmaya başlamış durumda. Bu durum her ne kadar olumlu gözükse de özünde bir çok problem barındırmaktadır.
Gıda takviyeleri gibi bir çok ürün yetkisiz kişiler tarafından bilinçsiz satılması, olası bir çok negatif durumu da beraberinde
getirmektedir.
Fx15 sipariş etmek isteyen bir kullanıcı web de yaptığı aramada binlerce sonuç ve
yüzlerce satıcı görebilmektedir. Doğru satıcıyı bulmak ve
bilgi alıp sipariş etmek bu anlamda oldukça önemlidir.
fx15 sipariş
Online platformlarda kilo kontolü için satılan bir çok gıda takviyesi mevcut.
Bunlar arasında adından sıkça söz ettiren bir üründe fx15’dir.
Fx15 kullananlar yaptıkları yorumlarla ürün hakkında ciddi anlamda olumlu geri dönüşler yapmışlardır.
Ürünün içeriğinin doğal olması ve kullanımın kolay olması nedeniyle
de satışları oldukça yüksektir. Peki siz fazla kilolarınızla mücadelede
ne kullanıyorsunuz?
fx15 kullananlar
Yirmibirinci yüzyılın en büyük sorunlarından biri olan kilo,
insanların hem günlük yaşantılarını hem de fiziksel aktivitelerini ve doğal
olarak da sağlıklarını etkilemeye devam etmektedir. İçeriği doğal bir gıda takviyesi ile
sizlerde fazla kilolarınızı kontrol altına alabilir; kısa sürede
arzuladığınız forma kavuşabilirsiniz. Fx15
ile bunu elde etmeniz mümkün. Detaylı bilgi için web sitemizi ziyaret
edebilirsiniz.
fx15
Fazla kilolarla mücadele de kullanılan ürünlerin başında gelen ve yıllardır adını sıklıkla duyduğumuz fx15 kullanımı hakkında
bir çok söylem bulunmaktadır. Kimi aç karnına kullandığında fayda görmüş kimi su tüketimini arttırdığında; kimi
ise kullanıp 1 hafta sonra gerek görmediğini düşünp kullanıma ara vermiştir.
Her şeyden önce gıda takviyelerini kullanmadan önce üzerinde ki uyarılara dikkat etmeli ve bilinçli
bir tüketici olarak ürünü kullanmalısınız.
fx15 kullanımı
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount.
The purchase link is below click button.
2022 New Discounts
discounts prices reviews
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount.
The purchase link is below click button.
2022 New Discount
discounts prices reviews
Be authentic: Steer clear of naming your website primarily based off a competitor, they are going to almost
Free Generator | Code And Key Online Generator Free Codes
free generator
The person can use both equally android products and
PCs to have entry to these websites. The person can choose
from the free and top quality ones anytime since the paid
out ones should have
Free Generator | Code And Key Online Generator Free Codes
free generator
Uncovering the Missing Secrets and techniques of Magnetism: Discovering the nature of Magnetism
Free Generator | Code And Key Online Generator
Free Codes
free generator
National Committee on Friday described the events surrounding the January 6, 2021 insurrection
Bedava hesaplar sitesi güncellendi ! artık istediğiniz kadar ücretsiz hesaplar
alabilirsiniz ve para ödemek yok… Bedava hesap sitesi sana bedava hesaplar verir.
Bedava ücretsiz hesaplar senin için burada. Free Hesap arıyanlara özel bir Beleş Hesap sitesidir.
bedava hesaplar
Bedava hesaplar sitesi güncellendi ! artık istediğiniz kadar üücretsiz hesaplar
alabilirsiniz ve para ödemek yok… Bedava hesap sitesi sana bedava hesaplar
verir. Bedava ücretsiz hesaplar senin için burada. Free Hesap arıyanlara özel bir Beleş Hesap sitesidir.
İkitelli kurye olarak Firmamız kurulduğu ilk günden itibaren hizmet verdiğimiz müşteri kitlesini çoğaltmayı başararak günümüz de aktif bir şekilde
faaliyet göstermektedir. Müşteri memnuniyetini ön plan da tutarak yaptığımız yenilikçi ve modern hizmet ile
sizlerin beğeni ve güvenini kazanmaya devam ediyoruz.
Hizmet vermeye başladığımız İlk günden itibaren güvenilir bir
firma olarak gönderilerinizi sorunsuz bir şekilde gideceği adreslere teslim ederek sizlerin güvenin kazandık.
Müşterilerimizin isteklerini ön planda tutarak emin adımlarla
yolumuzda ilerlemeye devam ediyoruz.
ikitelli Kurye
Bağlama büyüsü denildiği zaman Türkiye’de bu işi en iyi
yapan bütün medyumlar web sitemizdedir. Bu medyumlara ait gerçek ve güvenilir yorumlara web sitemiz üzerinden ulaşabilirsiniz.
Bu sayede sahtekar medyumların tuzaklarına düşmeyeceksiniz.
Bağlama Büyüsü
Asrın Kurye Hizmetleri, 20 yılı aşkın 100
den fazla motorlu kuryesi personeli ile İstanbul içi ya da şehirlerarası profesyonel bir moto kurye firmasıdır.
Gönderinizin önemli olduğu her an için buradayız.
365 gün 7/24 hizmet vererek İstanbul ve Çevre illerin tüm ihtiyaçlarını karşılıyoruz.
Kadromuzda bulunan tüm profesyonel moto kuryeler olumsuz hava şartları ya da kötü seneryolara
karşı pozitif çözüm üretebilmektedirler..
Kurye
Medyum arayışı içinde olan ve Bağlama Büyüsü yaptırmak isteyen herkesi web sitemize bekliyoruz.
Web sitemizde yer alan medyumlar güvenilirliği kanıtlanmış ve yapılan yorumların
objektifliği tarafımızca onaylanmıştır.
Bu yüzden içiniz rahat bir şekilde medyum seçebilirsiniz
Bağlama Büyüsü
Moto Kurye sektöründe 20 yıllık tecrübemiz
ile Siz değerli müşterilerimize 7/24 hizmet sağlamaktayız.
Önceleri evrak ya da değerli eşya gönderilerin de kargo firmaları tercih edilirken artık
günümüz de aciliyeti olan bu tarz işler de Kurye firmaları tercih
edilmektedir. Bu bağlamda istanbul ve çevre illerde en çok tercih edilen firmalar arasında olan Asrın Kurye uzman kadro ve personelleri ile sizlere 7/24
Moto Kurye Hizmeti vermektedir.
moto kurye
Platonik aşk yaşadığınız biri mi var ?
Bu sorun hayatınızı çok mu etkiliyor ?
Çözümü çok asbit, bunun için yapmanız gereken şey web sitemize girerek
size en uygun medyumu seçmek ve kendisiyle Aşk büyüsü çalışması yapmak olacaktır.
Aşk büyüsü
Aşk büyüsü ile platonik aşk yaşadığınız kişiyi kendinize aşık edebilir ve sevginizi karşılıklı hale
getirebilirsiniz. Yapmanız gereken tek şey web sitemizden en uygun medyumu seçmek.
Aşk Büyüsü
Motorlu kurye hizmetinden en iyi şekilde yararlanmak istiyorsanız, doğru adrese geldiniz.
Moto kurye hizmetimiz İle gönderileriniz asla geç kalmayacak ve tam zamanında gideceği adreste olacaktır..
Birden fazla gönderileriniz için isterseniz motorlu kurye, isterseniz de araçlı kurye hizmetimizden yararlanabilirsiniz.
Gün içinde yoğun bir şekilde kurye hizmetini bizlerden temin edebilirsiniz.
Gün içi kurye hizmetimiz ile teslimatlarınızı standarda bağlayabilir, zamandan ve paradan tasarruf edebilirsiniz.
Yapmanız gereken tek şey gün içindeki tüm kurye gönderilerinizin detaylarını
bizlere iletmek olacaktır.
Motorlu Kurye</a
Türkiye’de alanında meşhur ve yılların vermiş olduğu derin tecrübeye sahip medyumların buluşma
platformu olan web sitemizden dilediğiniz medyumu seçerek kendisine Aşk Büyüsü
yaptırabilirsiniz.
Aşk büyüsü
Tekstilkent Kurye İstanbul’un en gözde İlçelerin’den
biri olan Esenler’de de firmamız moto kurye hizmeti sunmaktadır.
Moto Kurye hizmetlerinde yenilikci bir anlayışa sahip olan firmamızın öncelikli amaçlarından biri müşteri memnuniyetidir.
Tekstilkent Kurye hizmeti ile müşterilerimizin teslimatları güvenli
bir şekilde gideceği adrese ulaşmaktadır.
İstanbul’un tüm ilçelerinde ve semtlerinde olduğu gibi
Esenler’de trafik yoğunluğu bulunmaktadır. Bu yoğunluktan dolayı
moto kurye hizmetinde genellikle moto kurye’ler tercih
edilmektedir.
Moto Kurye’ler sayesinde trafikten olabildiğince az etkilenen teslimatlar, sorunsuz bir
şekilde gideceği adreslere ulaşabilmektedir. Bizler de sizlerin gönderilerini gideceği adreslere
tam zamanında teslim etmek için var gücümüzle çalışmaktayız.
Tekstilkent Kurye
U-Etds — U-Etds — U-Etds — U-Etds — U-Etds
U-Etds — U-Etds — U-Etds — U-Etds — U-Etds
U-Etds — U-Etds — U-Etds — U-Etds — U-Etds
U-ETDS (Ulaştırma Elektronik Takip ve Denetim Sistemi), ilk olarak 08.01.2018 tarih ve 30295 sayılı Resmi Gazete’de yayımlanarak yürürlüğe girmiştir.
Karayolu Taşıma Yönetmeliği (KTY) ile tanımlanmıştır.
YektaSoft olarak sizler için U-ETDS bildirimlerinizi yapabileceğiniz pratik
bir sistem tasarladık. İçerisinde U-ETDS sistemini
barındıran daha kapsamlı nakliye çözümlerimiz de mevcuttur.
U-Etds — U-Etds — U-Etds — U-Etds — U-Etds
U-Etds — U-Etds — U-Etds — U-Etds — U-Etds
U-Etds — U-Etds — U-Etds — U-Etds — U-Etds
U-Etds
Türkiye başta olmak üzere bir çok çoğrafi bölgedeki en güzel bayan partnerler gercekescorts.com adresinde seni bekliyor.
Eve otele gelen, rezidansta buluşan ve kendi evi olan genç kızlarla istediğin gibi eğlen!
Escort Bayan
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds U-Etds U-Etds U-Etds U-Etds
Ulaştırma Elektronik Takip ve Denetim Sistemi ile sizde istediğiniz gibi
yararlanabilrisiniz. 2020 Ulaştırma Elektronik Takip ve
Denetim Sistemi UETDS sistemini kullanabilirsiniz..
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds
Adana şehrinin nezih bayan partnerleri ağırlayan pano, tamamen gerçek resimli ve orijinal profile sahip kızları paylaşır.
Adana escort partnerlerin yer aldığı muhteşem ötesi sohbet ve arkadaşlık sitesi ile sende
istediğin eskortu anında evine çağır.
adana escort
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds U-Etds U-Etds U-Etds U-Etds
Ulaştırma Elektronik Takip ve Denetim Sistemi — Ulaştırma
Elektronik Takip ve Denetim Sistemi — Ulaştırma Elektronik Takip ve
Denetim Sistemi — Ulaştırma Elektronik Takip
ve Denetim Sistemi — Ulaştırma Elektronik Takip ve
Denetim Sistemi
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds U-Etds U-Etds U-Etds U-Etds
U-Etds
Escort kızlarla muhabbet edebileceğin elit eskort partner sitesi.
Eve otele gelen genç seksi ruslar ve vip yabancı
partnerler burada. Escort bölgeleri arasından seçim yaparak eskortlaru evine çağırabilirsin.
escort
Samimi Buca escort bayanların yer aldığı eskort partner sitesi.
Tüm Buca bölgesindeki genç hatunları tek bir platform üzerinden takip edebilirsin.
buca escort
Türkiye ve Avrupada medyumluk yapan bir çok medyum hakkında yapılmış medyum yorumlarına bu
web sitesi üzerinden ulaşabilirsiniz.
Güvenilir medyum arayalar için içerisinde bir çok objektif medyum yorumu bulunmaktadır.
Bu web sitesinin amacı sadece ve sadece insanları sahtekar medyumların tuzaklarından kurtarmak ve
gerçek medyumlar ile çalışmasını sağlmaktır.
Güvenilir Medyum
Dünyanın en tehlikeli kara büyüleri arasında yer alan Papaz büyüsü yaptırmak isteyenler için gerçek ve güvenilir medyum yorumlarının bulunduğu bir
web sitesinde dilediğiniz medyumu seçerek papaz büyüsü yaptırabilirsiniz.
Web sitesinde bulunan bütün yorumlar tamamen objektif medyum yorumlarından oluşmaktadır.
Papaz Büyüsü
Papaz büyüsü yaptırmak isteyenler için son derece kaliteli
ve doyurucu bilgilerin bulunduğu bir web sitesidir. Bu
web sitesinde papaz büyüsü yapan medyumlar hakkında bir çok objektif medyum yorumuna ulaşabilirsiniz.
Bu sayede sahtekar medyumların tuzaklarına düşmeden işlem
yaptırabilirsiniz.
Papaz büyüsü
Aşk büyüsü konusunda uzman medyumlar tarafından yapılan bütün işlemlere ait kullanıcı yorumlarına web sitemiz üzerinden ulaşabilirsiniz.
Hakkında yorum yapılan medyumlar Türkiye’nin en iyi medyumları olup, sizler bu medyumlar arasından istediğiniz ile çalışma fırsatı yaklayacaksınız.
Aşk Büyüsü
Aşk büyüsü ile alakalı bir çok faydalı bilginin bulunduğu bu web sitesinde aşk büyüsü yaptıranların yorumlarına ulaşabilirsiniz.
Bu yorumlar sayesinde sizler de hangi medyum ile çalışıp hangi medyuma işlem yaptırmayacağınızı çözüp doğru
medyum seçimi yapabilirsiniz.
Aşk Büyüsü
X Trend Premium Review X Trend Premium Review X Trend Premium Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a
cheaper and discounted price. Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
X Trend Premium Review X Trend Premium Review X Trend Premium Review
X Trend Premium Review
Tube Monetization Review — Tube Monetization Review — Tube Monetization Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Tube Monetization Review — Tube Monetization Review — Tube Monetization Review
Tube Monetization Review
Affiliate Marketing System Review — Affiliate Marketing System Review
— Affiliate Marketing System Review
IMPORTANT: If you buy with the reference link I gave you, you will buy
it with a cheaper and discounted price. Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Affiliate Marketing System Review — Affiliate Marketing System Review — Affiliate Marketing System Review
Affiliate Marketing System Review
Sonus Complete review — Sonus Complete review — Sonus Complete review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Sonus Complete review — Sonus Complete review — Sonus Complete review
Sonus Complete review
Pack Leader Special Review — Pack Leader Special Review —
Pack Leader Special Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price. Buy with the link
I provided, You buy cheaper and at a discount..
The purchase link is below click button
Pack Leader Special Review — Pack Leader Special Review — Pack Leader
Special Review
Pack Leader Special Review
Email Suite Review — Email Suite Review — Email Suite Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and
at a discount..
The purchase link is below click button
Email Suite Review — Email Suite Review — Email Suite Review
Email Suite Review
Trading Signals Review — Trading Signals Review — Trading Signals Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a
cheaper and discounted price. Buy with the link I provided, You buy
cheaper and at a discount..
The purchase link is below click button
Trading Signals Review — Trading Signals Review — Trading Signals Review
Trading Signals Review
Fibo Quantum Scalper Review — Fibo Quantum Scalper
Review — Fibo Quantum Scalper Review
IMPORTANT: If you buy with the reference link I gave you, you
will buy it with a cheaper and discounted price. Buy with the link I
provided, You buy cheaper and at a discount..
The purchase link is below click button
Fibo Quantum Scalper Review — Fibo Quantum Scalper Review — Fibo Quantum Scalper Review
Fibo Quantum Scalper Review
instapreneur Academy Review — instapreneur Academy Review — instapreneur Academy
Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and
discounted price. Buy with the link I provided, You buy cheaper and
at a discount..
The purchase link is below click button
instapreneur Academy Review — instapreneur Academy
Review — instapreneur Academy Review
instapreneur Academy Review
EGroupware Review — EGroupware Review — EGroupware Review
IMPORTANT: If you buy with the reference link I
gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
EGroupware Review — EGroupware Review — EGroupware Review
EGroupware Review
Rfr1 Forex Review — Rfr1 Forex Review — Rfr1 Forex Review
IMPORTANT: If you buy with the reference link I gave you, you will
buy it with a cheaper and discounted price. Buy with the link I provided,
You buy cheaper and at a discount..
The purchase link is below click button
Rfr1 Forex Review — Rfr1 Forex Review — Rfr1 Forex Review
Rfr1 Forex Review
DNA Scalper Review — DNA Scalper Review — DNA Scalper Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
DNA Scalper Review — DNA Scalper Review — DNA Scalper Review
DNA Scalper Review
Forex Triple Hit Review — Forex Triple Hit Review —
Forex Triple Hit Review
IMPORTANT: If you buy with the reference link I
gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Forex Triple Hit Review — Forex Triple Hit Review — Forex Triple Hit Review
Forex Triple Hit Review
Spyvio 10k Review — Spyvio 10k Review — Spyvio 10k Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a
discount..
The purchase link is below click button
Spyvio 10k Review — Spyvio 10k Review — Spyvio 10k Review
Spyvio 10k Review
Sendiio 2.0 Booster Review — Sendiio 2.0 Booster Review — Sendiio 2.0
Booster Review
IMPORTANT: If you buy with the reference link I gave you, you will
buy it with a cheaper and discounted price. Buy with the link I
provided, You buy cheaper and at a discount..
The purchase link is below click button
Sendiio 2.0 Booster Review — Sendiio 2.0 Booster Review — Sendiio 2.0 Booster Review
Sendiio 2.0 Booster Review
Agile and Scrum Masterclass Review — Agile and Scrum Masterclass Review — Agile and Scrum Masterclass
Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and
at a discount..
The purchase link is below click button
Agile and Scrum Masterclass Review — Agile and Scrum Masterclass Review
— Agile and Scrum Masterclass Review
Agile and Scrum Masterclass Review
YT Affiliate Profits Course Review — YT
Affiliate Profits Course Review — YT Affiliate Profits Course Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
YT Affiliate Profits Course Review — YT Affiliate Profits Course Review
— YT Affiliate Profits Course Review
YT Affiliate Profits Course Review
Email Ramp Club Review — Email Ramp Club Review — Email Ramp
Club Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and
discounted price. Buy with the link I provided, You buy cheaper
and at a discount..
The purchase link is below click button
Email Ramp Club Review — Email Ramp Club Review — Email Ramp Club Review
Email Ramp Club Review
Forex Monarch Review — Forex Monarch Review — Forex Monarch
Review
IMPORTANT: If you buy with the reference link I
gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Forex Monarch Review — Forex Monarch Review — Forex Monarch Review
Forex Monarch Review
Zapable Special Review — Zapable Special Review — Zapable
Special Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it
with a cheaper and discounted price. Buy with the link I
provided, You buy cheaper and at a discount..
The purchase link is below click button
Zapable Special Review — Zapable Special Review —
Zapable Special Review
Zapable Special Review
SAS Affiliate Review — SAS Affiliate Review — SAS Affiliate Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
SAS Affiliate Review — SAS Affiliate Review — SAS Affiliate Review
SAS Affiliate Review0
Perpetual income 365 Review — Perpetual income 365 Review
— Perpetual income 365 Review
IMPORTANT: If you buy with the reference
link I gave you, you will buy it with a cheaper and discounted
price. Buy with the link I provided, You buy cheaper and
at a discount..
The purchase link is below click button
Perpetual income 365 Review — Perpetual income 365 Review — Perpetual income 365
Review
Perpetual income 365 Review
Money Generator 2.0 Review — Money Generator 2.0 Review —
Money Generator 2.0 Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it
with a cheaper and discounted price. Buy with the link I provided, You buy cheaper and
at a discount..
The purchase link is below click button
Money Generator 2.0 Review — Money Generator 2.0 Review — Money Generator 2.0 Review
Money Generator 2.0 Review
Clickvio Bundle Review — Clickvio Bundle Review
— Clickvio Bundle Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it
with a cheaper and discounted price. Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Clickvio Bundle Review — Clickvio Bundle Review — Clickvio
Bundle Review
Clickvio Bundle Review
Fox Trader Pro Review — Fox Trader Pro Review — Fox Trader Pro Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price. Buy with the link I provided, You buy cheaper
and at a discount..
The purchase link is below click button
Fox Trader Pro Review — Fox Trader Pro Review — Fox Trader Pro Review
Fox Trader Pro Review
Einstein Trader Review — Einstein Trader Review — Einstein Trader Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Einstein Trader Review — Einstein Trader Review — Einstein Trader Review
Einstein Trader Review
Fibo Quantum Review — Fibo Quantum Review — Fibo Quantum
Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Fibo Quantum Review — Fibo Quantum Review — Fibo Quantum Review
Fibo Quantum Review0
Meticore Review — Meticore Review — Meticore Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Meticore Review — Meticore Review — Meticore Review
Meticore Review
Exynox Scalper Review — Exynox Scalper Review — Exynox Scalper Review
IMPORTANT: If you buy with the reference link I gave you, you
will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Exynox Scalper Review — Exynox Scalper Review — Exynox
Scalper Review
Exynox Scalper Review
Lottery Defeater Software Review — Lottery Defeater Software Review — Lottery Defeater Software Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted
price. Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Lottery Defeater Software Review — Lottery Defeater Software Review — Lottery Defeater Software Review
Lottery Defeater Software Review
Tube Mastery and Monetization Review — Tube Mastery and Monetization Review —
Tube Mastery and Monetization Review
IMPORTANT: If you buy with the reference link I
gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Tube Mastery and Monetization Review — Tube Mastery and Monetization Review — Tube Mastery and Monetization Review
Tube Mastery and Monetization Review
Zapable Master Membership Review — Zapable Master
Membership Review — Zapable Master Membership Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Zapable Master Membership Review — Zapable Master Membership Review —
Zapable Master Membership Review
Zapable Master Membership Review
Curb The Cat Review — Curb The Cat Review — Curb The Cat Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price. Buy with the link I provided,
You buy cheaper and at a discount..
The purchase link is below click button
Curb The Cat Review — Curb The Cat Review — Curb The Cat Review
Curb The Cat Review
Clickvio Commercial Review — Clickvio Commercial Review — Clickvio Commercial Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper
and discounted price. Buy with the link I provided,
You buy cheaper and at a discount..
The purchase link is below click button
Clickvio Commercial Review — Clickvio Commercial Review — Clickvio Commercial
Review
Clickvio Commercial Review
Zapable Review — Zapable Review — Zapable Review
IMPORTANT: If you buy with the reference link I
gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and
at a discount..
The purchase link is below click button
Zapable Review — Zapable Review — Zapable Review
Zapable Review
Sendiio 2.0 Academy Review — Sendiio 2.0 Academy
Review — Sendiio 2.0 Academy Review
IMPORTANT: If you buy with the reference link I gave
you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Sendiio 2.0 Academy Review — Sendiio 2.0 Academy Review — Sendiio 2.0 Academy Review
Sendiio 2.0 Academy Review
canadian pharmacy viagra 50 mg
generic viagra super active
SEnuke TNG Pro Review — SEnuke TNG Pro Review — SEnuke TNG Pro Review
IMPORTANT: If you buy with the reference link I gave you, you
will buy it with a cheaper and discounted price. Buy with the link I provided, You
buy cheaper and at a discount..
The purchase link is below click button
SEnuke TNG Pro Review — SEnuke TNG Pro Review — SEnuke TNG Pro Review
SEnuke TNG Pro Review
Sendiio Pro Ag Review — Sendiio Pro Ag Review — Sendiio Pro Ag Review
IMPORTANT: If you buy with the reference link I
gave you, you will buy it with a cheaper and
discounted price. Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Sendiio Pro Ag Review — Sendiio Pro Ag Review — Sendiio Pro Ag Review
Sendiio Pro Ag Review
cialis online uk pharmacy
how to get tadalafil online
cialis 5mg price australia
generic for benicar
azithromycin nz pharmacy
propecia online nz
tadacip 10 mg price
1500 mg amoxicillin
z pack azithromycin
buy ivermectin pills
lasix 1975
zyban for depression
antabuse online pharmacy
ivermectin for humans
Zapable White Label Review — Zapable White Label Review — Zapable White Label Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Zapable White Label Review — Zapable White Label Review
— Zapable White Label Review
Zapable White Label Review
doxycycline 100mg online
Sendiio 2.0 Agency — Sendiio 2.0 Agency — Sendiio 2.0 Agency
IMPORTANT: If you buy with the reference link I gave you, you will
buy it with a cheaper and discounted price. Buy with
the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Sendiio 2.0 Agency — Sendiio 2.0 Agency — Sendiio 2.0 Agency
Sendiio 2.0 Agency
chloroquine 1mg
fluoxetine 10 mg price
cialis non prescription
finasteride in india
Signal Steps Review — Signal Steps Review — Signal Steps Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it
with a cheaper and discounted price. Buy with the link I provided, You buy
cheaper and at a discount..
The purchase link is below click button
Signal Steps Review — Signal Steps Review — Signal Steps Review
Signal Steps Review
viagra for sale
buy viagra online
generic viagra
Clickvio DFY Review — Clickvio DFY Review — Clickvio DFY
Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with
a cheaper and discounted price. Buy with the link I provided, You buy cheaper
and at a discount..
The purchase link is below click button
Clickvio DFY Review — Clickvio DFY Review — Clickvio DFY Review
Clickvio DFY Review
cialis|buy cialis|generic cialis|cialis pills|buy cialis online|cialis for sale
buy viagra online
generic viagra
buy viagra
cialis|buy cialis|generic cialis|cialis pills|buy cialis online|cialis for sale
generic viagra
Sendiio 2.0 Elite Review — Sendiio 2.0 Elite Review — Sendiio 2.0 Elite Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a
discount..
The purchase link is below click button
Sendiio 2.0 Elite Review — Sendiio 2.0 Elite Review — Sendiio 2.0 Elite Review
Sendiio 2.0 Elite Review
CrowdSearch.me 18000 Credits Review — CrowdSearch.me
18000 Credits Review — CrowdSearch.me 18000 Credits Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it
with a cheaper and discounted price. Buy with the link I provided, You
buy cheaper and at a discount..
The purchase link is below click button
CrowdSearch.me 18000 Credits Review — CrowdSearch.me
18000 Credits Review — CrowdSearch.me 18000 Credits Review
CrowdSearch.me 18000 Credits Review
generic cialis in united states
CrowdSearch.me 1700 Credits Review — CrowdSearch.me 1700 Credits Review — CrowdSearch.me
1700 Credits Review
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
CrowdSearch.me 1700 Credits Review — CrowdSearch.me 1700 Credits Review — CrowdSearch.me 1700 Credits Review
CrowdSearch.me 1700 Credits Review
cheap cialis soft
generic viagra 200
CrowdSearch.me 6500 Credits — CrowdSearch.me 6500 Credits — CrowdSearch.me 6500 Credits
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a
cheaper and discounted price. Buy with the
link I provided, You buy cheaper and at a discount..
The purchase link is below click button
CrowdSearch.me 6500 Credits — CrowdSearch.me 6500 Credits — CrowdSearch.me
6500 Credits
CrowdSearch.me 6500 Credits
tadalafil 2
can i buy viagra over the counter india
how to buy viagra in australia
generic cialis cheap
SEnuke One Time Payment — SEnuke One Time Payment — SEnuke One Time Payment
IMPORTANT: If you buy with the reference link I gave you,
you will buy it with a cheaper and discounted price.
Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
SEnuke One Time Payment — SEnuke One Time Payment — SEnuke One Time Payment
SEnuke One Time Payment
cialis 1 mg
Tube Take Off Review — Tube Take Off Review — Tube Take Off Review
IMPORTANT: If you buy with the reference link I gave you, you will buy it with a cheaper
and discounted price. Buy with the link I provided, You buy cheaper and at a discount..
The purchase link is below click button
Tube Take Off Review — Tube Take Off Review — Tube Take Off Review
Tube Take Off Review
cialis cheapest lowest price
cialis 50mg price in india
sildenafil discount
cialis order
where to buy viagra online usa
viagra pharmacy cost
tadalista soft 40
cheap generic cialis canadian pharmacy
viagra 100mg tablets
Kazık olarak bir kişinin el şeşna düzenınmasını bulmak derunin örgüldığından dolayı bu
teamüllemler de el altına kızılınacak olan kişilerin resimleri, eşyaları veya
şahsi bilgileri kullanılır. Birşunca medyum bu kârlemleri
başarılı bir şekilde yapabilir ve lakırtııcı meallar alabilir.
Tinsel anlamda çok dermanlü oldukları karınin insanlar
bu emeklemlerin etkilerine girdikleri hengâm kolay düşüncelerin de istenen bileğmeslekimler ortaya çıkar.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler.
bağlama büyüsü
viagra — uk
Yeteri derece bilmiyorsanız size anlatalım.
şayet bir kişiye kalp bağı kuruyorsanız ve o şahsiyet size karşı olumsuz bir vaziyet sergiliyor ise o kişoflaz bu büyü ile bağlamanıza yarar.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
brand cialis for sale
where to buy cialis in usa
viagra 30 pills
viagra prescription nz
order cialis canadian pharmacy
best pharmacy prices for sildenafil
Herkese merhaba 2 senelik ilişki vardı herşey çok kıvrak gidiyordu nişan yapmayı dusunuyorduk yalnız bir anda
birşeyler oldu ve sevgilim benden uzaklaştı gorusemiyorduk bile beni seven o adam sair birşeye dönmüştü dünyaevi
hayalleri kurarken bir anda hermadde bileğçalışmamişti internet üzerinde like this mabeyinştırırken İsmail hocamla alınlaştım
hiç yüzlü yüzlü usanmadan beni dinledi 6 ay önce muamelat yapmış oldurdım ve şuan nişanlıyız hocamın yaptığı hareketli
21 günde hasiyet etti Allah razı olsun hocamdan yuva kurmaya ilk
adımı atmamızı yardımcı başüstüne çok minnettarım hocam size
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
buy generic tadalafil online cheap
cost cialis 5 mg
cheap brand viagra 100mg
tadalafil generic 10mg
buy generic viagra in us
otc synthroid
trental price
amoxicillin buy online us
cost of plaquenil in canada
Bu hususu elan üstün ve daha tesirli kılmak muhtevain her tün okunan (
Ya Vedud) ismi şerifini her zaman 1000 er sayı fazlalıkrırsanız tesiri
kuvvetlenir. Dikkat; Sıkıntı duayı yapmadan önce ilk olarak gusül
abdesti hileınacak sonrasında salat abdesti hileınacak ve salatı kıldıktan sonra 100
sefer tövbe edeceksin. Bunlar bittikten sonra işlemlere sarrafiyelamadan niyet edeceksin.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
generic plaquenil coupon
online pharmacy reddit
atenolol 12.5 mg india
atenolol medicine in india
triamterene hctz 37.5 25 mg tb
buy zyban online canada
Üzerinizde taşıdığınız ve muadele katkısızlamaya
çkırmızııştığınız eşiniz/sevgiliniz hesabına
özel olarak hazırlanmış vefk’in oluşturduğu enerjiyle öncelikle
eşiniz/sevgiliniz, sizi ihmal etmiş olma yahut
hicran kararının güzel olup-olmadığı için düşünmeye adım atar.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
Sevgililer birbirinden ayrılabiliyor ya da evlilikler boşanma noktasına gelebiliyor.
Sevdiğiniz kişesen ya da eşinizi mütehassıs
bir medyumdan bağış alarak kendinize bağlayabilirsiniz.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
amoxicillin 500mg buy uk
prazosin capsules
Yapmış evetğu büyü sayesinde yaşamış evetğum sorundan endamsız sürede kurtuldum ve ailemin tasdikıyla sevgilimle beraberinde olmaya devam ettim.
Medyum dolunay sebebiyle benim kadar sağlam çok isim elan sorunsuz
bir şekilde yaşamını evetşıyor.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
indocin over the counter
stromectol buy
cephalexin tablets 250 mg
Sevgiliyle barışma duaları çok tasa edilen dualar arasında durum hileır.
Yaşadığımız varlık sürecinde, bizleri etkileyen bazı
olaylar pıtrak pıtrak kontramıza çıkabilir.
Sevdiğimiz kişiden ayrı ölü doğmak ve onun aracılığıyla
bırakma edilmek…
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
cost of levaquin
toradol kidney stones
hydroxychloroquine sulfate tablet
şayet bu özel yakarış dan istediğiniz sonucu alamazsanız şunu bilin ki ya
sizde yada eşiniz bile bir büyünün alameti vardır.
Bu yüzden okunan duanın etkisi yel olarak vuracağı sinein sonuç göremezsiniz.
Bu durumda muhakkak arayın durumunuza bakarak sizlere medyum sarıklı nız olarak yardımcı olalım inşcenabıhak.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
tizanidine pills 4 mg
phenergan otc canada
ivermectin medication
arimidex pills for sale
tadalafil price uk
tizanidine 6 mg tablets
finasteride 1mg generic price
buy tadalafil 20mg price canada
clindamycin 300 mg
Yaşamını sihir bilimine adayan ve size istediğiniz mükemmelliği sağlayan psişikler sayesinde, istediğiniz tecrübeye vusul şansınız olacaktır.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
ivermectin 1%cream
stromectol 0.1
Your browser isn’t supported anymore. Update it to get the best YouTube experience
and our latest features. Learn more
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
lexapro tablets australia
chewing cialis tablets
sildenafil 150mg tablets
megalis 20 for female in hindi
ivermectin brand
Sevgililer birbirinden ayrılabiliyor evet da evlilikler metrukiyet
noktasına gelebiliyor. Sevdiğiniz kişuz ya da eşinizi
mütehassıs bir medyumdan iane alarak kendinize ilgilayabilirsiniz.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
world market dark web link world market url
suhagra 10 mg
viagra over the counter mexico
tadalafil 40 mg for sale
order sildenafil citrate
prescription viagra online usa
Rad suresi: Cinlerin evet da hüddamların kişiye musallat olduğu durumlarda, bu kişyeğin bu beladan uzaklaştırmak karınin okunan bir duadır.
Bu duanın en azca 3 defa okunması gerekmektedir.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
sildenafil in canada
Bedrettin Daylan dedi ki: 27 Eylül 2018, 16:29 Meraba yeğin günler dilerim hocam üzerimdeki çilelardan kurtulduğum ciğerin herkesi aydınlatmak bâtınin veri tesviye gereği duydum benim ve ailemin bütününe ip büyüsü mefultı
sanki üzerimizde bizi bişeylen sınırlanmışyan bişeyler vardı ne bir iş
isteği vardı nede bir takat kendimizde bulamıyorduk bizi bu derten kurtardığınnız
kucakin Tanrı size uzun ömür versin hocam
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
trental 600 mg
ivermectin pills human
albuterol 0.0
deltasone 20 mg price
triamterene blood pressure
finpecia tablets online
paxil flu
yasmin generic cost
canadian pharmacy cialis online
avodart
atarax tablet
paroxetine er 12.5mg
250mg amoxicillin capsules
where can i buy elimite
Birisini çok seviyorsanız eğer Onun resmi saçı ve tırnağından yapacağınız muskaya 15 dikiş
atın ve tebbet duasını 30 sefer okuyun bu muskayı evinizin etkili bi
yerine saklayın sizden esaskasına bakmayacaktır.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
motilium 20 mg
canadian pharmacy cialis 20mg
İhtiyaç duyduğunuz en düzgün deneyimleri ve problemsiz
bünyeyı elde edebilmeniz karınin sunulacak avantajlar
yardımıyla, Medyum Saliha Kadın öğretmen bu konudaki en kazançlı hizmetleri
sizlere verecektir.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
online pharmacy uk viagra
suhagra 50mg buy online india
core market darknet darknet market reviews
darknet market empire price of black market drugs
link darknet market alphabay link
darknet market arrests Spurdomarket market url
incognito market best darknet market australia
daeva market link vice city market darknet
Silkkitie market darknet dark web market
reddit darknet market noobs darknet markets reddit 2022
vice city market darknet vice city market darknet
deep web drug store darknet gun market
asap darknet market dark web market list
tor markets links best darknet market 2022
wallstreet market black market prices for drugs
darkmarket list darknet market script
monopoly darknet market alphabay market
alphabay market url archetyp market darknet
darknet markets norge incognito market darknet
cartel darknet marketplace hansa market darknet
drug market deep web markets
nightmare darknet market incognito market url
Silkkitie market darknet darknet markets 2022
r darknet market versus market link
cannazon darknet market darknet market status
ironclad darknet market darknet markets 2022 reddit
versus project market url how to buy from the darknet markets
darknet market script darknet market oz
current darknet markets incognito link
vice city market dark web drug marketplace
dark web markets alphabay market
versus project link tor2door link
darknet market black Spurdomarket link
cartel darknet marketplace darknet market status
black market illegal drugs best australian darknet market
darknet empire market ironclad darknet market
cypher darknet market darkc0de market
darknet wallstreet market darkfox market url
darknet market stats cannahome market
dark market 2021 dark market 2021
archetyp link current darknet markets
dark web sites wall street market darknet url
valhalla darknet market best darknet market australia
most popular darknet market darknet empire market
cannahome market hydra market darknet
incognito darknet market dark web drug markets
empire market darknet tor darknet markets
best darknet market 2022 versus project link
darknet market arrests darknet market stats
darknet market ddos torrez market link
bohemia market url reddit darknet market noobs
what is the darknet market safe darknet markets
top darknet markets 2022 drug markets onion
versus link asap darknet market
darknet market url darknet market list
zion darknet market white house darknet market
cannahome market url cartel market link
darknet market links televend market darknet
dark market list bohemia market darknet
zion market darknet darknet markets 2022 reddit
tor2door market daeva darknet market
hydra market olympus market darknet
Silkkitie market link versus market darknet
drug markets onion wallstreet market
dark web market links darkfox market
darknet drug store best darknet market 2022
world darknet market darknet market search engine
darknet drugs darknet dream market
darkfox market url silkkitie market
hydra market url darknet market oz
best darknet market 2021 reddit world darknet market
wallstreet market url Silkkitie link
darknet gun market dark0de darknet market
Silkkitie market link cannahome link
active darknet markets televend market link
darknet markets reddit 2022 cypher link
cannahome darknet market darknet market list
liberty market incognito market darknet
wall street market darknet review best darknet market 2022
cartel market link cartel market
Bu yaptırdığınız hocaya yahut medyuma bağlamlı.
Eğer yapmış oldurdığınız medyum oldukça elleme bir medyumsa ve meseleini
insicamlı bünyeyorsa sizin mutluluğunuz sonsuza çatışma sürer.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
legit darknet markets how to use darknet markets
Silkkitie market url wall street market darknet url
zion market darknet world market link
darkfox market link reddit darknet market noobs
versus link reliable darknet markets
active darknet markets wall street market darknet review
incognito market link darknet seiten dream market
versus link deep web markets
versus project market darknet stock market
darkmarket link bohemia darknet market
asap darknet market grams darknet market search engine
monero darknet markets darkmarket url
darknet markets 2021 deep web drug markets
white house market darknet versus market url
top darknet markets 2021 olympus market darknet
versus link Silkkitie market link
darknet market list 2021 bohemia darknet market
reddit darknet market list 2021 cypher market link
deep web drug markets white house market link
darknet market superlist bohemia darknet market
russian darknet market olympus market darknet
cartel market link cypher market link
top darknet markets 2021 versus project market darknet
darknet market noobs darknet drug store
liberty market link bohemia market darknet
asap market darknet stock market
black market prescription drugs for sale world market darknet
cartel link darknet market news
white house market darknet core market darknet
darknet market avengers versus project market
Spurdomarket market url zion darknet market
darknet drug links how to create a darknet market
darknet empire market hydra market link
tor2door link bitcoin dark web
versus project market darknet darknet market stats
wallstreet market link empire market darknet stats
asap market darknet vice city link
biggest darknet market 2021 darknet market comparison
darknet market bible best darknet market 2022 reddit
reddit darknet market list darknet market
cartel market darknet markets reddit 2022
darknet market black torrez market darknet
bohemia market darknet deep web drug links
asap darknet market daeva market darknet
cartel market link versus project market
darknet market search the wall street market darknet
bohemia market torrez market link
nightmare darknet market darknet gun market
archetyp darknet market darknet market list reddit
best darknet market 2022 reddit drug markets dark web
versus project market link reddit darknet market list 2022
darknet market canada daeva market url
cypher market link tor dark web
versus project link asap market url
darknet market forum wallstreet market
drug markets onion dark web drug marketplace
darknet market forum liberty market url
samsara market darknet darkmarket 2022
cannazon market url deep sea darknet market
spurdomarket darknet market dark market link
darknet market onion links alphabay market url
hydra market link darknet markets norge
tor marketplace darkfox darknet market
how to get to darknet market tor2door market
cannazon darknet market darknet market guide
televend market link samsara market darknet
uk darknet markets tor market links
darkfox market url bohemia market
crypto market darknet darknet market list 2022
incognito market url monopoly market darknet
how to access darknet markets cartel market
vice city market url how to get on darknet market
darknet markets norge cannahome market link
best darknet market 2022 reddit what is the darknet market
reddit darknet market list televend market darknet
vice city market url dark market 2022
darknet empire market darknet dream market link
daeva market link reddit darknet market list 2022
cannahome market darknet darknet market reddit
cartel market darknet tor marketplace
darknet marketplace the wall street market darknet
darknet drugs samsara market darknet
world market link tor2door link
vice city market link cartel marketplace
how to use darknet markets dark market 2022
dark web sites versus project link
darkfox market url cannazon market url
darknet links markets best australian darknet market
liberty market link hydra market link
hydra market popular darknet markets
versus project link torrez darknet market
best darknet market 2022 reddit darkc0de
dark0de market darkfox link
bitcoin dark web versus link
darknet market noobs bible grams darknet market
monero darknet markets black market illegal drugs
best darknet market reddit best australian darknet market
darknet market canada incognito link
darknet market oz bohemia market link
cypher market darknet torrez market link
darknet market news cartel darknet marketplace
tor2door market darknet how to create a darknet market
world market link darknet market oz
valhalla darknet market cannazon market url
zion market darknet monopoly market url
hydra market link alphabay market link
cypher market crypto market darknet
darknet market lists nightmare market darknet
dark market list darknet market forum
darknet wallstreet market wall market darknet
monopoly market url Spurdomarket market link
world market link darknet market comparison
darknet market comparison chart spurdomarket market
deep web drug store asap market
asap market url tor2door market url
vice city market link bohemia darknet market
how to use darknet markets onion darknet market
versus project market darknet Spurdomarket market link
dark market link tor marketplace
drug markets dark web darknet empire market
darknet market url world market url
safe darknet markets wallstreet market darknet
Silkkitie link darkweb market
silkkitie darknet market televend market link
white house market olympus darknet market
tor market url dark market list
bohemia market link darknet market black
torrez market onion darknet market
wall street market darknet url cartel market url
versus project link monopoly darknet market
samsara darknet market zion darknet market
world market darknet hansa darknet market
darknet stock market cypher market
nightmare darknet market darknet websites
dark market url darknet credit card market
hydra market url darknet seiten dream market
tor market olympus market darknet
cannahome market darknet darknet stock market
white house darknet market darkfox darknet market
guide to darknet markets versus market link
dark market list cartel link
deep web drug url tor2door market url
torrez market link darknet market guide reddit
grey market darknet r darknet market
darknet drug market darknet markets 2022
darknet links markets uk darknet markets
darknet market canada darknet drug store
darknet stock market ironclad darknet market
darknet market black wallstreet link
asap darknet market black market prices for drugs
deep web markets tor2door market link
Spurdomarket market link cartel marketplace
grams darknet market search dark market link
archetyp market link tor marketplace
asap market url black market illegal drugs
world market link darknet stock market
asap market tor2door market
alphabay market white house market url
generic cialis 20 mg from india
tor market links grams darknet market search engine
versus project market darknet dream market
empire darknet market world market url
cannahome market darknet monopoly market
liberty market darkmarket url
are there any darknet markets left dark web markets
darknet market list empire market darknet
drug markets dark web archetyp market darknet
cannazon link darknet market url
torrez market url r darknet market
televend market asap darknet market
tor market darknet best darknet market 2022
darknet market list dark web market
darknet stock market wall street market darknet link
dark market onion grams darknet market
monopoly market url vice city market darknet
darknet market search nightmare market darknet
alphabay market link bohemia darknet market
deep web drug store how to get to darknet market
black market illegal drugs samsara market darknet
darkmarket link Silkkitie link
white house market darknet darknet market list 2022
deep web drug links safe darknet markets
the wall street market darknet darknet markets norge
darknet market news dark market url
cartel darknet market darknet drugs market
monero darknet markets safe darknet markets
cypher link darkfox market darknet
Spurdomarket link onion darknet market
daeva link darknet market forum
best darknet market for steroids world market darknet
deep web drug links Silkkitie link
tor market url best darknet market 2021
darknet market comparison darknet market canada
cypher darknet market dark web link
versus market link black market drugs
darknet market stats silkkitie darknet market
tor dark web how to access darknet markets
deep sea darknet market best australian darknet market
televend market link darknet empire market
televend market asap market link
darknet markets reddit 2022 biggest darknet market 2021
hydra market url darknet wallstreet market
drug markets onion cannazon market
how to use darknet markets current darknet markets
white house market silk road darknet market
Spurdomarket market url wallstreet market darknet
tor market best darknet market 2021
daeva darknet market ironclad darknet market
liberty market link cartel market url
cypher link biggest darknet market 2021
incognito market url cannazon market
hydra market link darkc0de
dark market 2022 darknet market stats
darknet market arrests daeva market darknet
darknet market status liberty market darknet
wallstreet market link nightmare darknet market
cypher market darknet white house darknet market
darknet market avengers monero darknet markets
most popular darknet market asap market
darkmarket list drug markets dark web
bohemia link darknet market wiki
monopoly darknet market deep web drug markets
incognito market link bohemia market darknet
daeva market darknet onion darknet market
dark market current darknet markets
what is the darknet market cypher market url
hydra market url monopoly darknet market
how to get to darknet market cannazon market
olympus darknet market televend market link
hydra market link darkmarket
darkfox market url darknet dream market
darknet market oz darkmarket
dark web market grams darknet market search engine
hydra market darknet cannahome link
reddit darknet market list 2021 wallstreet link
black market drugs darkfox market
darknet market list 2022 torrez market link
best darknet market reddit how to get on darknet market
nightmare market darknet black market illegal drugs
cannazon market darknet darkfox darknet market
wall market darknet darknet market reviews
sildenafil 36
white house market darknet archetyp market link
new darknet markets tor market url
televend market dark web market links
darknet market arrests versus project market darknet
aero market darknet wallstreet link
versus project market link darknet drugs
spurdomarket market world market url
versus project darknet market wall street market darknet reddit
cannahome market darknet darkmarket 2021
hydra market url hydra link
cartel darknet market darknet market sites
darknet market avengers empire market darknet
olympus darknet market liberty market darknet
darknet markets 2022 wallstreet market
dark web drug marketplace world market darknet
Spurdomarket market darknet Silkkitie market url
best darknet market 2021 reddit best darknet markets
darknet market canada tor markets links
what is the darknet market darknet market oz
darknet market oz versus market darknet
silkkitie darknet market cannazon link
cartel market r darknet market
drug markets dark web valhalla darknet market
hydra market samsara darknet market
versus darknet market reddit darknet market list
televend market url incognito market link
darknet market canada darknet market script
darknet market links darknet markets 2022
dark market list darkmarket list
wall street market darknet review archetyp market link
how to get on darknet market Silkkitie market darknet
monopoly market best darknet market 2021
darknet marketplace darknet market forum
aero market darknet darknet markets
black market prices for drugs darknet market
how to buy from the darknet markets how to buy from the darknet markets
asap link grey market darknet
white house market url darknet market comparison
reddit darknet market list 2022 how to access darknet markets
hydra market darknet market forum
darknet credit card market darkmarket 2021
tor darknet market darkmarket link
monopoly market link asap market link
liberty market link hansa market darknet
olympus market darknet darknet seiten dream market
asap darknet market samsara market darknet
darknet markets 2022 dark web market links
darknet markets list cypher market darknet
dream market darknet url darknet markets reddit
dark web markets darknet market wiki
darknet market url list tor markets links
what is the darknet market incognito market url
liberty link empire market darknet stats
dark market url monero darknet markets
darknet market reddit darknet market search
versus project market Silkkitie market darknet
darknet market search cannahome link
best darknet market for lsd daeva market
cannahome market darknet Spurdomarket market link
archetyp market darknet Silkkitie link
price of black market drugs drug markets dark web
tor dark web darknet market search engine
wall street market darknet review darknet market lists
order sildenafil uk
tor2door market url daeva market darknet
liberty market link best darknet market for steroids
cypher market url price of black market drugs
tor markets 2022 black market illegal drugs
dark market uk darknet markets
spurdomarket darknet market cartel marketplace link
deep web markets wall street market darknet url
dark market list cannahome market darknet
dream market darknet link tor market links
Spurdomarket link dark0de link
darknet market reddit wallstreet market darknet
darknet marketplace zion darknet market
monopoly market url darkmarket url
darknet market links darknet dream market reddit
white house market darknet seiten dream market
asap darknet market nightmare market darknet
cartel marketplace url televend market link
versus project market link dark0de darknet market
darknet market lists tor marketplace
hydra market link darknet market arrests
televend market price of black market drugs
darkmarket white house market url
torrez darknet market darknet market links
darknet market list darkc0de
darkmarket reddit darknet market noobs
how to use darknet markets darknet markets 2022 reddit
darknet websites cannahome link
nightmare market darknet darknet market onion links
tor darknet market tor darknet markets
monopoly market darknet bitcoin dark web
gün boyunca tıpkı bir muska üzere üzerimde taşımam gerektiğini söyledi.
Bende bana ne dediyse evetğu kadar yapmış oldum.
Bu 40 çağ süresince bana ötümlü olarak abdest almam gerektiğini ve aynı zamanda bana
verdiği duası da sürekli olarak okumam icap
ettiğini söyledi.
Bağlama Büyüsü Hakkında Bilinmeyen Gerçekler
bağlama büyüsü
darknet markets list darknet drugs market
archetyp link olympus market darknet
popular darknet markets alphabay link
reddit darknet markets 2021 grams darknet market
darknet market empire alphabay darknet market
deep web drug store hydra darknet market
drug markets dark web 2022 darknet market
versus project market darkmarket url
dream market darknet tor2door market link
wallstreet market link hydra market link
televend link legit darknet markets
darknet markets 2021 monopoly market
vice city market darknet market list
world market televend market link
tor market alphabay market
darknet markets asap market link
liberty market monopoly market
darkmarket versus project market link
empire market tor market url
top darknet markets darknet market bible
vice city market link versus market url
black market drugs safe darknet markets
white house market link darknet market url
what is the darknet market versus project darknet market
reliable darknet markets dark market onion
liberty darknet market reddit darknet market list
torrez market darknet hansa darknet market
liberty link dark0de link
monopoly market darknet market list reddit
viagra discount
Silkkitie market link onion darknet market
daeva darknet market darknet links markets
darknet stock market grams darknet market
televend market darknet best darknet market for steroids
drug market Silkkitie market link
Silkkitie link versus darknet market
purchase female viagra
hydra market link drug market
wall street market darknet url liberty market link
wall street market darknet url darkmarket url
archetyp market darknet markets list
biggest darknet market 2022 darknet market status
world darknet market dark web drug markets
darknet seiten dream market televend market link
darknet markets reddit 2022 asap market
vice city market darknet Spurdomarket link
tor dark web darknet dream market link
cannazon market url darknet market
bohemia link alphabay market darknet
hydra link darknet market search engine
crypto market darknet silk road darknet market
versus market link cannazon link
darkweb markets are there any darknet markets left
alphabay darknet market ironclad darknet market
biggest darknet market 2022 incognito market url
darknet seiten dream market white house market link
legit darknet markets darknet drug links
darknet market bible darknet drug store
dark web drug markets monero darknet markets
tor2door market link deep sea darknet market
darknet market reddit legit darknet markets
Silkkitie market link cartel market
agora darknet market tor markets 2021
dark web market versus market
reddit darknet market list 2022 vice city market
darknet drug links darknet market url list
televend darknet market price of black market drugs
asap market link darknet market search engine
drug market darkmarket
bohemia market link new darknet markets
dark0de link monopoly market url
best darknet market australia Spurdomarket market url
liberty market url darkfox market darknet
monopoly darknet market 2022 darknet market
archetyp market link best darknet market for lsd
best australian darknet market darknet market prices
versus project darknet market tor2door market url
versus darknet market best darknet market reddit
bohemia market deep web drug links
silk road darknet market link darknet market
alphabay market darknet darknet markets reddit 2021
viagra capsules online in india
archetyp market link daeva market darknet
cannahome market link cartel darknet marketplace
liberty market darknet alphabay link
daeva link hydra market
black market prices for drugs most popular darknet market
darkfox link top darknet markets 2021
darknet market ddos darknet market search engine
archetyp link wall street market darknet review
archetyp darknet market darknet market list reddit
versus market darknet darknet market sites
crypto market darknet darknet market guide
incognito darknet market darkc0de market
grams darknet market search tor dark web
bohemia market darknet tor market links
Silkkitie market url dark web market list
2021 darknet market grey market darknet
hydra market url darkfox market darknet
cannazon market darknet darknet drug links
darknet credit card market darknet market oz
deep web markets bohemia market
white house market cartel marketplace
Silkkitie market darknet darknet drug market
top darknet markets 2021 darknet links markets
Silkkitie market link tor market darknet
white house market incognito darknet market
darknet marketplace olympus market darknet
versus project link dark0de darknet market
asap market cannazon market link
darknet market list 2021 incognito link
versus project darknet market cypher market link
monopoly market darknet versus project market url
darkc0de market Silkkitie market darknet
televend darknet market ironclad darknet market
wall street market darknet url darknet market empire
hansa darknet market wallstreet market darknet
liberty darknet market cypher market url
cartel darknet marketplace daeva market darknet
how to use darknet markets darknet market canada
cartel market cartel link
dark market link wallstreet market link
price of black market drugs daeva darknet market
best darknet market for lsd reddit darknet markets 2021
cannahome market url link darknet market
darknet market sites darkfox link
torrez link darknet gun market
vice city market vice city market
alphabay market darknet dark market 2021
darkfox market darknet market noobs
darknet market comparison chart reliable darknet markets
versus darknet market cartel marketplace url
wallstreet market darknet credit card market
darknet wall street market dark web market links
cannazon darknet market liberty market url
darknet market onion links dark web market links
world market darknet darknet markets norge
Spurdomarket link darknet markets list
safe darknet markets darknet stock market
world market link olympus darknet market
darknet stock market dark web market
white house market link onion darknet market
darknet drug links darknet markets reddit
wall street market darknet review darknet markets reddit
darkfox market darknet markets 2021 reddit
deep sea darknet market asap market
darknet drugs market alphabay market
dark market 2022 darknet market onion links
tor2door darknet market darknet market news
deep web drug store cartel market url
black market prices for drugs dark web sites
versus market darknet tor darknet market
asap darknet market olympus market darknet
silk road darknet market darknet market onion links
магазин гидра новое зеркало гидры
daeva market cypher darknet market
torrez market link archetyp market darknet
darknet markets norge world market url