favicon что не хотел умирать

7 сентября 2026 г. designdevlog

Маленькая вещь. Заняло путь слишком долго. Favicon, маленький значок в ярлычке браузера, самый маленький ресурс на целом этом сайте и это боролось со мной тверже чем обратный прокси сделал.

Что это должно быть

Значок вкладки здесь маленький монограмм BMK с горной глифом неловко засунут в это, соответствие запирание в заголовке. Я не нарисовал это вручную как растровое изображение, я построил это как HTML плитку (static/_favicon-tile.html) используя действительный проданный Literata шрифт и действительные цвета сайта, потом отрендировал это в PNG с Playwright так глиф действительно использует то же самое типография как остаток сайта вместо некоторого回退система шрифт что SVG <text> элемент бы молча заменили. Два размера получают сгенерированы, 32px за вкладку и 512px за всё что хочет больший значок (домашний экран сокращения, того рода вещь), плюс яблоко-касание-значок на 180px.

<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png?v=2" />
<link rel="icon" type="image/png" sizes="512x512" href="/favicon-512.png?v=2" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=2" />

Заметь ?v=2 на конце каждого. Того не было первоначально. Это рубец ткань из целой той истории.

Раунд один: оно просто не обновилось

Я перерисовал favicon полпути через переделку, переродил PNGs, развернул, обновил страницу. Старый значок. Ещё старая горная форма в вкладке. Я допустил я испортил сборку, проверил файл на диске, и новые байты были прямо там, правильные пиксели, правильный файл, правильный путь. Браузер просто не просил это опять.

Оказывается favicons это один тип ресурса где браузеры кеш с чем-то близко к религиозной набожности, и в основном игнорируют нормальные заголовки управления кешем ты бы использовал на чём-то другом. Chrome в частности исторически кешировал favicon сайта долгое время независимо от что сервер говорит, иногда нуждаясь истории и кеша очищенных полностью, иногда нуждаясь действительного изменения URL, не просто свежих байт в тот же URL. Простой перезагрузить не будет это касаться. Перезагрузка с отключённый кеш в devtools, что вещь я попробовал второй и что обычно фиксирует точно этот класс проблемы, не был.

Раунд два: винить неправильный слой

Перед я выяснил это был браузер, я потратил время подозревая контейнер, потому что этот стек работает позади Docker и я был обожжён стареющие слои сборки ранее (действительный другой баг ранее в этом проекте вовлекал node_modules получающие раздавленными в Docker сборке потому что я ещё не писал .dockerignore ещё). Так я пошел вниз той дорожки первый: перестроил образ фронтенда с --no-cache, подтвердил новые PNG байты сидящие в frontend/build/client/favicon-32.png в запущенном контейнере, curl URL прямо против самого контейнера порт чтоб обойти Caddy полностью. Свежие байты, каждый раз, прямо из источника. Сервер делал его работу правильно всё время. Это никогда не был контейнер. Это было чисто сидящим в моём собственном браузере favicon кешем, несколько слоёв далеко от чего-либо развёртывание мог касаться.

Это часть та что действительно стоила время: исключить мою собственную инфраструктуру перед я признал баг жить где-то я имею ноль контроля.

Исправление

Ты не можешь сказать браузер favicon кеш инвалидироваться. Что ты можешь делать это перестать просить таже URL. Всё я пробовал перед выясняя то держал таже URL:

<!-- перед: таже URL каждый раз, браузер никогда не переспрашивает это -->
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />

Строка запроса на конец href делает это другой ресурс как далеко как кеширование озабочено, даже хотя оно разрешает в ровно таже файл на диске:

<!-- после -->
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png?v=2" />

?v=2 это целое исправление. Следующий раз я изменяю favicon арт по-настоящему, то становится ?v=3, и так далее. Это та же самая уловка как кеш-разрушение CSS или JS пакета с хешем содержимого, просто сделано вручную здесь так как favicon так редко редактируется что целая трубка инструмента сборки для это ощущалось как избыточное убийство. Одно число, толкаемое вручную, каждый раз когда пиксели действительно изменяются.

Что я сказал бы прошлой мне

Проверь лёгкий, тупой, постыдный объяснение перед интересным. «Браузер просто быть упрямы о маленькой PNG» это скучный ответ и я хотел баг быть чем-то больше технически удовлетворение, некоторая Docker слой-кеширование тонкость я мог писать умнее исправление за. Это не было. Это была пять-символ строка запроса я мог имел добавляемый в первый десять минут если я имел верил скучный объяснение вместо погони контейнера вокруг половину часа первый.

Вещь что делала это хуже прежде чем она становилась лучше

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

Есть тоже меньший, скучный причина сторона сборки действительно заслуживала первый взгляд: таже favicon PNGs существуют скопированные в несколько разные места выхода сборки сразу, frontend/build/client/, SvelteKit разработка выход под .svelte-kit/output/client/, и источник static/ каталог они все происходят от. Три копии та же самая два файла через нормальная сборка это ровно вид вещь та идёт старая в одном месте и не другом если шаг сборки получает прыгнут, так исключая «неправильная копия получает служена» не была параноя, это просто не было где настоящий баг жил этот раз.

Я также мысленно через просто переименование файлы полностью, favicon-32-v2.png вместо удара строка запроса, что гарантирует кеш мисс с нулём неясность. Решил против это, так как то означает обновление каждый референс к старому имени файла через app.html и в любом месте оно связано, насупротив касание одного числа в одном месте. Строка запроса делает таже работу для доля редактирования.

0 комментариев

Войдите , чтобы оставить комментарий.

Войти

Забыли пароль?

Нет аккаунта?