Недавно я переместил свой личный веб-сайт на Hugo, и переход с Jekyll был в основном приятным. Я получил массу улучшений во время сборки. Но что мне не понравилось, так это документация Hugo. Все основано на идее, что вы установите Hugo, создадите новый сайт, а затем добавите тему. Вот где начинается проблема. Мне не нужна стандартная тема, в конце концов, это мой личный веб-сайт, так что это должно быть моим выражением, верно? Что ж, мне посчастливилось поймать Хуэй Цзин в доброжелательном, слегка скучающем настроении. Она создала для него весь собственный CSS с фантастическим макетом Masonry.
Но это означало, что с этого момента документы Хьюго были в основном бесполезны. Они предназначены для того, чтобы помочь вам разработать тему или изменить ее, чтобы достичь чего-то нового. Мой веб-сайт Hugo изначально был не очень сложным, поэтому, следуя по стопам Хуэй Цзина, мы заставили его работать без документации. Теперь, когда MVP выпущен в течение нескольких месяцев, я продолжаю находить небольшие вещи, которые можно улучшить. Или, если вы посмотрите на мои оценки web.dev, не так уж и мало. 😏
До
У меня было изображение обложки в передней части публикации под списком images
, потому что это был способ Хьюго автоматически сделать это изображение социальной картой Twitter. Я, будучи ленивым, посчитал это выигрышем. Мои изображения также хранились в папке static/
, потому что это имело смысл? Я имею в виду, что изображения - это не совсем контент или активы, верно? Оказывается, это неправильно, но об этом позже.
Это означало, что использовать изображения в моих статьях было легко. Я пишу их в markdown
, поэтому добавление изображения сводилось лишь к тому, чтобы указать правильный путь:
![I wish all my images had alt text 🤦♂️](/image.png)
С макетами тут возникли сложности. Технически передний план images
- это массив, даже если он когда-либо имел только один элемент. Это означало, что мне приходилось циклически перебирать эти элементы, когда я отображал их на list
макетах. Или получите элемент с индексом 0. Так что в итоге код выглядел немного неаккуратно.
<img class="post-image" src="{{ range .Params.images }}{{ . }}{{ end }}" alt="{{ .Title }}" />
У этого подхода было несколько проблем.
- Я был слишком ленив, чтобы изменить размер всех изображений для макета
list
, поэтому большинство из них были довольно большими и загружались сразу на главную страницу. Медленно было мягко сказано. - Я не мог беспокоиться об изменении размера изображений несколько раз, чтобы сделать изображения адаптивными. В идеале 3–4 раза. Отсюда и ужасный результат на Lighthouse.
Хотя, похоже, в конце туннеля был свет. Просматривая документы, казалось, что в Hugo есть что-то под названием Обработка изображений, и это должно было помочь решить все мои проблемы. Я мог изменять размер своих изображений во время сборки, сжимая их и изменяя качество кодирования. Все это звучало как легкое средство от моей лени. За исключением того, что документы немного тонкие, и они бесполезны для веб-сайта без темы Hugo. Я пробовал это дважды, но безуспешно, но похоже, что третий раз - прелесть.
Как добавить обработку изображений в Hugo
Первое, что я сделал неправильно, это то, что изображения были в папке static
. Обработка изображений в Hugo работает с ресурсами, и для ее работы изображение должно быть либо ресурсом страницы, либо ресурсом. Ресурсы страницы должны находиться в той же папке, что и файл разметки, так что об этом не могло быть и речи. Было слишком много изображений, которые нужно было переместить, и слишком много путей, которые нужно было изменить в каждой статье. Другой вариант, «Ресурс», означал, что изображения должны находиться в папке assets
, так что это было легко перетаскивать. Даже не пришлось менять относительные пути в заголовке статей.
Первым делом я переместил свои изображения в папку assets
вместо static
. Я изменил свои изображения на живые с /static/img
на /assets/img
. Это означало, что мои источники изображений в статьях вообще перестали работать. Активы не создаются во время сборки, если они не обрабатываются. И даже тогда их имя файла динамически генерируется при каждой сборке. Поэтому мне пришлось изменить все вхождения изображений в статьях и шаблонах, чтобы вместо этого использовать ресурс.
Чтобы это работало в моих файлах контента, мне пришлось создать шорткод, это способ Hugo иметь сниппеты внутри Markdown. Вот как выглядит мой. Я взяла шорткод адаптивных изображений, о котором писала в блоге Лаура Калбаг, и изменила его, чтобы он соответствовал моему макету. И поскольку у меня есть анимированные GIF-файлы в моей серии DevTricks, я не изменяю их размер, а просто передаю относительную постоянную ссылку тегу изображения. Я также ничего не делаю с внешними изображениями. Тем не менее, я решил, что если все будет хорошо работать с помощью alt-тегов, я заработаю несколько очков Lighthouse.
{{/* get file that matches the filename as specified as src="" in shortcode */}} {{ $src := resources.GetMatch (.Get "src") }} {{ if in (.Get "src") "http" }} <img src="{{$src}}" {{ with .Get "alt" }}alt="{{.}}"{{ else }}alt=""{{ end }}> {{ else }} {{ if in (.Get "src") ".gif" }} <img src="{{$src.RelPermalink}}" {{ with .Get "alt" }}alt="{{.}}"{{ else }}alt=""{{ end }}> {{ else }} {{/* set image sizes, these are hardcoded for now */}} {{ $tinyw := default "500x" }} {{ $smallw := default "800x" }} {{ $mediumw := default "1200x" }} {{/* resize the src image to the given sizes */}} {{ .Scratch.Set "tiny" ($src.Resize $tinyw) }} {{ .Scratch.Set "small" ($src.Resize $smallw) }} {{ .Scratch.Set "medium" ($src.Resize $mediumw) }} {{/* add the processed images to the scratch */}} {{ $tiny := .Scratch.Get "tiny" }} {{ $small := .Scratch.Get "small" }} {{ $medium := .Scratch.Get "medium" }} {{ $large := .Scratch.Get "large" }} {{/* only use images smaller than or equal to the src (original) image size */}} <img {{ with .Get "sizes" }}sizes='{{.}}' {{ else }} sizes="(min-width: 35em) 720px, 100vw"{{ end }} srcset=' {{ if ge $src.Width "500" }} {{ with $tiny.RelPermalink }}{{.}} 500w{{ end }} {{ end }} {{ if ge $src.Width "800" }} {{ with $small.RelPermalink }}, {{.}} 800w{{ end }} {{ end }} {{ if ge $src.Width "1200" }} {{ with $medium.RelPermalink }}, {{.}} 1200w{{ end }} {{ end }}' {{ if .Get (print $medium) }} src="{{ $medium.RelPermalink }}" {{ else }} src="{{ $src.RelPermalink }}" {{ end }} {{ with .Get "alt" }}alt="{{.}}"{{ else }}alt=""{{ end }}> {{ end }} {{ end }}
Чтобы использовать этот шорткод изображения в моем контенте, мне пришлось изменить способ вызова моих ссылок с синтаксиса уценки по умолчанию на что-то среднее между Hugo и HTML:
{{< img src="img/posts/web/hugo-performance-before.png" alt="Bad Lighthouse Performance" >}}
Вывод шорткода {{< img >}}
выглядит примерно так:
<img sizes = "(min-width: 35em) 720px, 100vw" srcset = " /img/posts/web/hugo-performance-before_hu187b84b0088ba519b328cb2126b97350_79974_500x0_resize_lanczos_2.png 500w, /img/posts/web/hugo-performance-before_hu187b84b0088ba519b328cb2126b97350_79974_800x0_resize_lanczos_2.png 800w, /img/posts/web/hugo-performance-before_hu187b84b0088ba519b328cb2126b97350_79974_1200x0_resize_lanczos_2.png 1200w" src = "/img/posts/web/hugo-performance-before.png" alt = "Bad Lighthouse Performance">
Похоже, я могу изменить размер своих изображений внутри содержимого. Так почему бы мне не сделать то же самое в моих макетах? Потому что где-то мелким шрифтом в документации написано, что я не могу использовать шорткоды вне файлов с контентом. Тем не менее, та же функциональность доступна в шаблонах макета через частичные шаблоны. Как оказалось, мне не нужны адаптивные изображения в моем представлении списка, мне просто нужны изображения намного меньшего размера. Поэтому я не стал воссоздавать всю логику шорткода в частичных шаблонах. Вместо этого у меня был менее сложный, более ленивый подход. Я получаю изображение Resource, я изменяю его размер до 360 пикселей с качеством 85%, используя фильтр Box. Все это приводит к уменьшению размеров, быстродействию и ухудшению качества изображений на домашней странице.
{{ if .Params.images }} {{ $image := index .Params.images 0 }} {{ $src := resources.Get $image }} {{ $small := $src.Resize "360x q85 Box" }} <img class="post-image" alt="{{ .Title }}" src="{{ $small.RelPermalink }}" > {{ end }}
После
С этими изменениями я был готов снова проверить свою оценку Lighthouse. Вы тоже можете попробовать, мой сайт - alexlakatos.com.
Вы заметите, что мой Largest Contentful Paint
снизился примерно на три с половиной секунды. Я бы назвал это победой. Оценка производительности также поднялась до 99, что я бы назвал чертовски хорошим. Тот факт, что мои оценки доступности и SEO подскочили до 100, объясняется тем, что новый шорткод заставил меня переписать все свои теги изображений. Я потратил время на то, чтобы обновить их до атрибута alt
, чтобы мне не пришлось повторять их снова.
Теперь, если бы я хотел сделать больше, мне нужно было бы найти способ заставить конвейер обработки изображений Hugo работать с форматами изображений следующего поколения. Но это история для другого раза. А пока не стесняйтесь обратиться в Твиттер и сообщить мне, если вы нашли это полезным. Или, по крайней мере, развлекательно.
Первоначально опубликовано на https://alexlakatos.com 17 июля 2020 г.