Lazy loading: how it decreases load time and increases engagement

Как включить отложенную загрузку в wordpress 6.4.3 (изображения, фреймы и видео)

Why Should You Care About Lazy Loading Images?

There are at least a couple of excellent reasons why you should consider lazy loading images for your website:

  • If your website uses JavaScript to display content or provide some kind of functionality to users, loading the DOM quickly becomes critical. It’s common for scripts to wait until the DOM has completely loaded before they start running. On a site with a significant number of images, lazy loading — or loading images asynchronously — could make the difference between users staying or leaving your website.
  • Since most lazy loading solutions work by loading images only if the user has scrolled to the location where images would be visible inside the viewport, those images will never be loaded if users never get to that point. This means considerable savings in bandwidth, for which most users, especially those accessing the Web on mobile devices and slow-connections, will be thanking you.

Well, lazy loading images helps with website performance, but what’s the best way to go about it?

There’s no perfect way.

If you live and breathe JavaScript, implementing your own lazy loading solution shouldn’t be an issue. Nothing gives you more control than coding something yourself.

Alternatively, you can browse the Web for viable approaches and start experimenting with them. I did just that and came across these five interesting techniques.

Which Images can be Lazy Loaded?

The basic idea of lazy loading is simple — defer loading anything that is not needed right now. For images it usually translates to any image that is not visible to the user up front can be lazy loaded.

As the user scrolls down the page, the image placeholders start coming into viewport (visible part of the webpage). We trigger the load for these images when they become visible.

You can find out which images are a candidate for lazy loading and how many bytes you can save on the initial page load by using Google Lighthouse audit tool. The audit performed by this tool has a section dedicated for offscreen images. You can also use ImageKit’s website analyzer to identify if your website uses lazy loading or not, in addition other critical image-related optimizations on your page.

Lazy loading is critical not only for good performance, but also to deliver a good user experience.

Лучшие практики

Разработчикам следует придерживаться лучших практик, чтобы в полной мере использовать потенциал ленивой загрузки в JavaScript

Прежде чем применить ленивую загрузку на сайте, определите важное содержимое, которое должно загружаться немедленно для создания хорошего пользовательского опыта. Рассмотрим некоторые из лучших практик реализации ленивой загрузки:

  • Оптимизируйте изображений и мультимедийных файлов: Для оптимизации ленивой загрузки изображений используйте соответствующие форматы и сжимайте их без потери качества. Реализуйте отзывчивые изображения с атрибутами и , чтобы предоставлять изображения разных размеров в зависимости от области просмотра пользователя, что позволит сэкономить полосу пропускания.
  • Используйте элементы-заместители: Для предотвращения смещения содержимого и нестабильности макета следует использовать элементы-заместители, резервирующие место для ленивого содержимого. Для поддержания макета до загрузки реального содержимого следует использовать изображения-заместители или простые элементы-заместители, например с заданными размерами и цветом фона.
  • Реализуйте API Intersection Observer: Intersection Observer API — это функция JavaScript, которая упрощает реализацию ленивой загрузки. Она позволяет разработчикам эффективно отслеживать появление элементов во вьюпорте, что инициирует загрузку лениво загружаемого содержимого.
  • Обеспечьте поддержку для пользователей, не поддерживающих JavaScript: Не у всех пользователей в браузере включён JavaScript. Для таких пользователей следует предусмотреть запасные варианты для лениво загружаемого содержимого. Например, используйте тег для включения статических версий загружаемых изображений и мультимедиа. Это гарантирует, что пользователи с отключённым JavaScript смогут получить доступ к основному контенту и сохранить положительный пользовательский опыт.
  • Обрабатывайте ошибки: Ленивая загрузка иногда может приводить к ошибкам, таким как неработающие URL-адреса изображений или неудачная загрузка ресурсов. Реализуйте обработку ошибок, чтобы изящно разрешать такие ситуации. Замените неработающие или отсутствующие изображения подходящими заменителями, а для отладки ведите журнал ошибок в консоли. Обработка ошибок позволяет поддерживать бесперебойную работу пользователей и помогает разработчикам выявлять и устранять проблемы.
  • Поддерживайте лёгкую ленивую загрузку: Избегайте перегрузки веб-страницы чрезмерной ленивой загрузкой. Ограничьте количество элементов, подлежащих ленивой загрузке, только теми, которые существенно влияют на время загрузки страницы.
  • Тщательное протестируйте на различных устройствах и браузерах: Прежде чем внедрять ленивую загрузку на реальном сайте, тщательно протестируйте её реализацию на различных устройствах, в различных браузерах и при различных скоростях сети. Проведите тестирование на настольных компьютерах, ноутбуках, планшетах и смартфонах, чтобы убедиться в согласованном поведении и отзывчивости.
  • Асинхронное декодирование изображений перед их вставкой в DOM позволит избежать зависания браузера во время загрузки изображения.

Настройки плагина ленивой загрузки a3 Lazy Load

Как уже было сказано, a3 Lazy Load работает сразу после активации, и большинство вебмастеров удовлетворится этим. Но если при работе с плагином возникают какие-либо неполадки или просто из любопытства, чтобы узнать, какие опции у него есть, можно изучить его настройки. Настройки плагина находятся в разделе «Настройки», в подразделе «a3 Lazy Load». Они разделены на несколько групп.

Глобальные настройки плагина

Здесь только две опции, которые не влияют на работу плагина, а нужны только для удобства вебмастера:

  • Отображать открытые блоки — если включена, то плагин будет автоматически сохранять изменения при сворачивании блока настроек. В ином случае сохранять надо с помощью кнопки внизу страницы настроек.
  • Прибраться за собой при удалении — если включена, после удаления плагина, будут удалены и все его остатки в базе данных.

По умолчанию здесь всё включено, это значит, что эффект ленивой загрузки применён ко всем изображениям сайта.

Ленивая загрузки изображений

В данной секции опций выбирается, к каким изображениям будет применяться эффект ленивой загрузки: к картинкам контента, сайдбара, изображениям записи, граватара и других. По умолчанию включены все. Также здесь можно задать исключения — CSS-классы изображений, к которым эффект отложенной загрузки не будет применяться.

Ленивая загрузки видео и iframe

Здесь включается и отключается эффект ленивой загрузки в блоке iframe или встроенных видео. Можно управлять эффектом в контенте и в сайдбаре, а также задать CSS классы элементов, к которым эффект не будет применён.

Исключить URL по типу страниц

В этой секции настроек задаётся, на каких страницах эффект ленивой загрузки не будет работать. Можно исключить страницы, записи, страницы рубрик, тегов, главную и другие. Также можно задать непосредственно список URL адресов, на которых отложенной загрузки не будет.

Оптимизация скрипта загрузки

По умолчанию скрипт ленивой загрузки размещается плагином в подвал сайта. Это положительно для скорости загрузки страницы. Но если что-то работает не так, можно в этой опции поместить скрипт плагина в шапку сайта.

Плагины мобильных шаблонов WordPress

Если для мобильной версии используются шаблоны WPTouch или MobilePress, то здесь можно отключить отложенную загрузку картинок и видео для них.

Эффекты и стили

Есть два вида эффектов для отложенной загрузки изображений — спиннер и плавное появление. И здесь они меняются. Также есть возможность задать цвет фона ленивой загрузки.

Порог старта загрузки изображений

Задаётся через сколько пикселей после появления области изображения на экране начинает загружаться картинка. По умолчанию — 0. Значит, что картинка начинает загружаться сразу же, как только её область появится на экране.

Совместимость с Jetpack Site Accelerator (Photon)

Если на сайте используется плагин Jetpack, то здесь можно включить совместимость a3 Lazy Load с ним.

Если вы изменили настройки плагина, и что-то начало работать не так, как нужно, то верните настройки к состоянию по умолчанию. Для этого внизу страницы опций есть кнопка «Сбросить настройки».

What is lazy loading?

Lazy loading is a technique used by web pages to optimize load time. With lazy loading, a web page loads only required content at first, and waits to load any remaining page content until the user needs it. Lazy loading reduces the time it takes for a web page to open because the browser only loads a fraction of the content on the page at a time.

The process is called «lazy» because it delays loading until needed — the same way someone might put off a task. But in this case, laziness is a great thing. 

You’ve encountered lazy loading before, even if you don’t think you have. Let’s go to Google Images for an example. If I search for photos of dachshunds (as I do regularly), Google will load hundreds of images for me on a single results page.

Loading all of these images on the page at once wouldn’t make sense since I probably won’t scroll too far down before I find what I’m looking for and leave. Why waste precious loading time and data on dachshunds I’ll never see?

Google Images implements lazy loading instead. For hidden content, it loads placeholder images to substitute the actual images. These placeholders take much less time to load than fully rendered content. The real images quickly load when their placeholder comes into view (i.e., when I scroll down).

On-demand loading techniques like this are used all over the web. Visit some of your favorite image-heavy sites – chances are, they use this technique. While lazy loading is most commonly used on images, it can be applied to any page element, including text, videos, or other embedded content.

When working on websites with broad catalogs that need many images displayed, I’ve personally found that lazy loading is often the easiest way that I can decrease page load times. The best combination, in my experience, is maintaining the best image SEO practices, like keeping images and videos under 100 kbs while having lazy loading enabled. This keeps my page load speeds down, and my visitor count up.

Устранение неполадок с ленивой загрузкой

Хотя отложенная загрузка является полезной и важной функцией WordPress, она также может вызвать множество проблем на вашем веб-сайте. В этом разделе мы рассмотрим, что это за проблемы и как их решить

Изображение выше сгиба

В общем, мы советуем не лениво загружать графику в верхней части страницы. Когда мы говорим «в верхней части страницы», мы имеем в виду первоначальную область просмотра, которую видят ваши пользователи при посещении вашего веб-сайта.

Задержка фотографий на сгибе может повлиять на ваш балл FCP. Это также может повлиять на первые мысли пользователей о вашем веб-сайте.

Прямой ответ — остановить отложенную загрузку изображений в заголовках страниц и других основных компонентах. Если мы возьмем эту страницу в качестве примера, мы бы посоветовали отключить ленивую загрузку для логотипа и фона заголовка.

Чтобы отключить реализацию медленной загрузки в WordPress по умолчанию, вы должны добавить код на свой веб-сайт.

Сдвиг макета для ленивой загрузки

Когда вы загружаете страницу, компоненты перемещаются по мере того, как они становятся видимыми, что приводит к смещению макета. Кумулятивное смещение макета (CLS) — это стандартный Web Vital, который количественно определяет сдвиг макета. Плохое выполнение отложенной загрузки может повлиять на рейтинг CLS вашего сайта в нескольких случаях.

Элементы на странице не загружаются одновременно. Вместо этого они проходят один за другим, даже если в браузере процедура кажется почти мгновенной. Когда файлы изображений загружаются после других элементов, они могут перемещать эти активы.

Чтобы обойти эту проблему, избегайте использования полноразмерных фотографий в WordPress. Когда вы загружаете изображения в WordPress, CMS изменит их размер до стандартных разрешений.

Даже при отложенной загрузке использование стандартных разрешений снижает вероятность серьезного изменения макета. Вы также можете вручную определить размеры изображения для каждого файла. Однако это трудоемкая операция. Короче говоря, мы рекомендуем его только для фотографий, которые необходимо отображать в определенном размере.

Проблемы с ленивой загрузкой и кэшированием плагинов

Плагины кэширования часто пересекаются с инструментами отложенной загрузки.

Чтобы избежать проблем с отображением изображений из-за конкурирующих инструментов, мы рекомендуем использовать одно семейство плагинов. Если у вас активированы плагины отложенной загрузки и кэширования, и у вас возникают трудности, мы рекомендуем сначала удалить первый.

Попробуйте проверить, правильно ли загружаются ваши изображения после удаления плагина отложенной загрузки. Если это так, ваше решение для кэширования, скорее всего, включает функцию отложенной загрузки. Это означает, что вам не нужно будет устанавливать какое-либо дополнительное программное обеспечение, чтобы воспользоваться этой функцией.

Why browser-level lazy loading?

According to the HTTP Archive, images are the most requested asset type for most websites and usually take up more bandwidth than any other resource. At the 90th percentile, sites send over 5 MB of images on desktop and mobile. That’s a lot of cat pictures.

Previously, there were two ways to defer the loading of off-screen images:

  • Using the Intersection Observer API
  • Using , , or event handlers

Either option can let developers include lazy loading functionality, and many developers have built third-party libraries to provide abstractions that are even easier to use. With lazy loading supported directly by the browser, however, there’s no need for an external library. Browser-level lazy loading also ensures that deferred loading of images still works even if JavaScript is disabled on the client.

Продвинутая отложенная загрузка

Размытые изображения-заполнители отображаются до тех пор, пока не будет загружено полное изображение, и являются первым шагом к созданию этого расширенного эффекта отложенной загрузки.Чтобы создать размытое изображение-заполнитель, вам просто нужно создать версию изображения со сверхнизким разрешением. Есть много способов сделать это, например, использовать такой сервис, как BlurHash, вручную изменить размер изображения в таком инструменте, как Figma, или автоматически с помощью такого инструмента, как ffmpeg. Мы будем использовать ffmpeg для создания изображений-заполнителей для этой статьи, поскольку это наиболее гибкий вариант, который можно легко автоматизировать. Все, что нужно сделать, это запустить приведенный ниже код в командной строке в каталоге, содержащем изображение, для которого требуется сгенерировать изображение-заполнитель.

При этом будет сгенерировано изображение шириной 20 пикселей, а высота будет автоматически рассчитана для сохранения пропорций исходного изображения. Вы можете изменить ширину на любую другую, но по наблюдениям, 20 пикселей хорошо подходят для большинства изображений и достаточно малы, чтобы загружаться почти мгновенно даже при медленном интернет-соединении. Изображения-заполнители будут примерно по 1КБ каждое.Следующим шагом является создание и установка фонового изображения этого на наше супер маленькое изображение. Это будет изображение-заполнитель, которое будет отображаться до тех пор, пока не будет загружено полное изображение. Наш код будет выглядеть примерно так.

Этот с имеет размер в зависимости от размера содержимого в нем. Однако мы можем легко исправить это, добавив в наш и убедившись, что он скрыт по умолчанию, чтобы мы никогда не видели его в наполовину загруженном состоянии.

Это даст нам эффект, который мы ищем. Эффект размытия, который мы получаем автоматически, связан с тем, что сверхмаленькое изображение автоматически увеличивается браузером. Если вы хотите добавить больше размытия, вы всегда можете использовать свойство CSS filter, чтобы добавить фильтр к .

Вы даже можете сделать еще один шаг вперед, добавив пульсирующую анимацию к изображению-заполнителю. Это сделает еще более очевидным, что изображение загружается.

Теперь единственное, что осталось сделать, это показать основное изображение после его загрузки. Это немного сложнее, чем остальная часть кода, который мы написали до сих пор, поскольку требует от нас использования JavaScript, но все же довольно просто. Нам просто нужно добавить прослушиватель событий к изображению, который будет срабатывать после загрузки изображения.

Здесь много кода, поэтому разберем его шаг за шагом. В коде JavaScript мы выбираем а затем выбираем в этом . Затем мы проверяем свойство у , чтобы увидеть, загрузился ли он еще. Если это так, это означает, что изображение уже загружено, поэтому мы можем просто вызвать функцию . Однако, если это условие ложно, нам нужно добавить прослушиватель событий в , который будет срабатывать после загрузки изображения, а затем вызывать . просто добавляет класс в .В CSS у нас есть несколько изменений в коде. Сначала мы удалили / из элемента . Это остановит пульсирующую анимацию после загрузки изображения. Мы также добавили к элементу , чтобы он плавно исчезал при добавлении класса в Наконец, мы изменяем непрозрачность на , чтобы она была видна при загрузке.

Lazy load test

We ran a little test on one of our blog posts so you could see the difference.

Not lazy loaded

Here is before we lazy-loaded the images. As you can see, the are a total of 56 requests, total page size of 852 KB, and load time of 1.2s.


Not lazy-loaded

Lazy loaded

Here is after we enabled lazy-loading. As you can see, the number of requests dropped down to 35, the total page size decreased to 245 KB, and the load time dropped to 0.8s. So in other words, just enabling lazy loading gave us a speed increase of 33% and decreased the page size by 70%.


Lazy-loaded

The post we tested on was fairly optimized already. You’ll see even bigger speed increases if you are lazy loading unoptimized images or have more images on a page.

Какие использовать плейсхолдеры #

На самом деле тут очень много вариантов, поэтому тут лучше исходить от задачи и пожеланий заказчика. На мой вкус есть несколько основных вариантов:

  • Использовать плейсхолдеры одного цвета, например серые заглушки. Эта техника называется content placeholder, и применима не только для картинок, но и для всего контента.
  • Использовать уменьшенные версии изображений или ужатые по качеству. Например, можно использовать библиотеки imagemin (для оптимизации) и lovell/sharp (для ресайза).

Ниже фотография, сделанная на iphone7, размером 1280х1280px, которая весит 710kb. Используя imagemin (вместе с imagemin/imagemin-jpegtran) минимальной конфигурации фотография стала весить в 2.5 раза меньше (250kb), практически не потеряв в качестве!

Сможете догадаться где оригинал, а где оптимизированная версия изображения?

Оригинал находится справа. А что, если изображение на странице будет занимать 400x200px (как на скриншоте выше)? Добавим использовать sharp для ресайза изображения.

Изображение стало весить всего 25kb!

Видна потеря качества, но для превью заглушкиподходит идеально

Для imagemin есть webpack loader, поэтому можно за одно оптимизировать картинки во время фронэнд сборки.

Опция дает еще один классный эффект, jpeg изображения становятся прогрессивными (почитать можно например статью на хабре про прогрессивный jpeg).

Если кратко, браузер может отображать все изображение сразу в плохом качестве и потом подгружать его, а не грузить последовательно блоками (пример ниже):

Два оптимизированных изображений, только слева — прогрессивное, справа нет.Вес у изображений одинаковый, эмуляция fast 3g

И довольно интересный вариант, использовать библиотеку zouhir/lqip (low quality image placeholder). Библиотека генерирует супер маленькие плейсхолдеры в base64 (10x10px).

Как это выглядит?

Прьвью картинка весит меньше одного килобайта!

Подобные плейсхолдеры используются кстати на медиуме. Разве не круто? Если в статье или новости есть 10 картинок, а после новости идет блок еще с 15 картинками, можно сэкономить пару тройку мегабайт.

Как и для imagemin есть свой webpack lqip-loader.

Добавлено 01.03.2019: Так же совсем недавно Google запустили сервис https://squoosh.app/ — удобный инструмент для оптимизации изображений, которое подбирает самый оптимальный алгоритм сжатия. Приложение использует ресурсы компьютера и написано как PWA — т.е. будет работать даже без интернета.

#5 Yall.js

Yall is a feature-packed, lazy-loading script for images, videos, and iframes. More specifically, it uses the Intersection Observer API and smartly falls back on traditional event handler techniques where necessary.

When including Yall in your document, you need to initialize it as follows:

Next, to lazy load a simple element, all you need to do in your markup is:

Note the following:

  • you add the class lazy to the element
  • the value of is a placeholder image
  • the path to the image you want to lazy load is inside the attribute

Among the benefits of Yall are:

  • great performance with the Intersection Observer API
  • fantastic browser support (it goes back to IE11)
  • no other dependencies necessary

To learn more about what Yall can offer and for more complex implementations, feel free to check out the project’s page on GitHub.

Что такое ленивая загрузка изображений?

Полагаю, вам уже известно о том, что быстрый сайт способствует росту посетителей. Скорость загрузки влияет как на хорошее отношение поисковых систем, так и на поведенческие факторы. Мы же не хотим, чтобы читатель, не дождавшись загрузки страниц, закрыл сайт и ушёл?

Что такое ленивая загрузка? Это постепенная загрузка изображений. То есть, когда пользователь откроет страницу, то не сразу все картинки начнут загружаться. А будет происходить постепенная подгрузка по мере пролистывания данной страницы вниз.

И настроить можно будет не только обложки. Но, представьте себе, и картинки баннеров, заставки видеоматериалов, миниатюр и т.д. А в настройках плагина a3 Lazy Load вы сами сможете определить, на какие именно элементы будет распространяться действие. А на какие нет.

Lazy Load Images with the Loading Attribute- The Easy Way

The web pages are growing over time. Developers now know that images have a significant effect on the user and how they perceive the website. As a result, it has become a rare phenomenon to see a web page that does not have a single image. Some web pages are just filled with images raising their count to more than ten or sometimes 15. As good as that is for everyone, Google Chrome developers did start to take the lazy loading seriously.

As our web page’s size has increased so significantly, developers have started to use lazy loading on their website to save from the embarrassment of loading their webpage in a lifetime. Google Chrome developers hence thought out to implement this feature into the native browser library so that developers can skip the complex JS code and directly implement lazy loading and the existence of the src attribute. This attribute is called the “loading” attribute.

The “loading” attribute consists of three values:

  • auto: The “auto” value depends on the browser’s in-built capabilities. For example, Google Chrome automatically loads the images located deep down the viewport to save the bandwidth. If any other browser does not have that capability, the image will load immediately with the page.
  • lazy: The “lazy” value tellS the browser that this image needs to be loaded lazily in the browser.
  • eager: The “eager” value is used to tell the browser to load the image immediately as the content is loaded. The “eager” value is opposite to the “lazy” value.

Since we need to load the image lazily, we will use the “lazy” value here. This is a Chromium-based update and, therefore, will be available to all Chromium-based browsers.

There is no need to implement JavaScript, and a small addition to the image tag would work as follows:

<img loading=»lazy» src = “URL” loading = “lazy”>

1 <img =»lazy»src=“URL”=“lazy”>

The above code will bring out the same output as the Intersection Observer API without any extra code. So, why don’t we skip everything and use just the native lazy loading feature?

Browser Support for the Loading Attribute

The browser support for the loading attribute is as follows:

Source: Can I use

The Chrome browser and other Chromium-based browsers show full support. In contrast, Mozilla’s Firefox is currently providing partial support to the attribute. The “loading” attribute is more accessible, but as I mentioned above, if you want to play with the events and want more control over your elements, JavaScript is the best choice.

Эффективность отложенной загрузки

Как я уже сказал, работаю с модулем Lazy Load — проблем пока не возникает, картинки грузятся только при прокрутке, причем достаточно быстро. Лично я никаких специальных замеров не проводил, ориентируюсь исключительно на визуальный эффект, который наблюдаю «до» и «после».

Однако автор статьи, которую упоминал выше, проводил анализ результатов по трем разным плагинам, и вот что получилось:

Можно заметить, как ленивая загрузка изображений и контента с помощью a3 Lazy Load значительно отличается по показателям у других методов. Все дело в обработке картинок:

  • По умолчанию WordPress передает браузеру все доступные значения размеров изображений, которые имеются. Тот в свою очередь загружает наименьшую версию, доступную для текущего размера окна.
  • Модули BJ Lazy Load, Lazy Load XT подменяют базовую функцию системы и атрибуты в коде, что позволяет использовать полноценную версию картинки.
  • Решение a3 Lazy Load полностью копирует логику Вордпресс — то есть считываются минимально возможные по объему файлы.

Не смотря на меньшее число запросов и итоговый вес в последнем варианте, BJ Lazy Load все равно оказывается быстрее. Дело в том, что плагин отправляет в браузер информацию вида data:image/gif, которая вынуждают его создавать gif файлы локально, а не скачивать с сервера (через HTTP запросы).

Однако тут есть один очень важный момент — отложенная загрузка изображений в BJ Lazy Load будет хорошо работать, если сами картинки были оптимизированы ранее. То есть, допустим, пользователь добавляет на сайт 10 фоток 3000х2000 пикселей — в таком случае вы рискуете получить глюк, когда при прокрутке страницы во время загрузки графики будут выводится белые непрозрачные блоки-прелоадеры.

Так не случится, если фон у вас белый изначально. В противном случае нужно будет добавить другой прелоадер (почти все модули позволяют это сделать). В Lazy Load XT даже предусмотрена прозрачная картинка для подобных целей.

Итого

Можно сделать следующие выводы:

  • Если вы используете оптимизированные изображения через программы или Tinypng, то самый быстрый вариант BJ Lazy Load (при сравнении трех модулей).
  • Когда фото вставляются на сайте «как есть» (с большим разрешением), оптимальнее будет решение a3 Lazy Load, которое кроме ленивой загрузки использует встроенную в WP логику работы с графикой.
  • Могу также посоветовать плагин, которым пользуюсь я — Lazy Load. Каких-либо тестов не проводил, но там крутые разработчики и максимум скачиваний.
  • Если будете пробовать другие решение, желательно проверять их эффективность.
Понравилась статья? Поделиться с друзьями:
Бизнес-Триатлон
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: