如何阻止HTTP请求只是一个图标?

每个人都知道如何在HTML中设置favicon.ico链接:

<link rel="shortcut icon" href="http://hi.org/icon.ico" type="image/x-icon">

但是对于只有几个字节的小图标,我们需要然而,另一个可能会降低速度的HTTP请求是愚蠢的。

所以我想知道,我怎么能使favicon的一部分可用的精灵(例如,background-position=0px -200px;),双重说,在网站的其余部分的标志,以加快网站和保存宝贵的和有价值的HTTP请求。我们如何将其与我们的标志和其他艺术品一起放入现有的精灵图像中?

58250 次浏览

好观点,好想法,但不可能。favicon需要是一个单独的、独立的资源。没有办法将它与另一个图像文件合并。

这是个好主意,但如果谷歌在他们的主页上还没有这样做,我敢打赌它(目前)也不会这样做。

你可以试试数据URI。没有HTTP请求!

<link id="favicon" rel="shortcut icon" type="image/png" href="data:image/png;base64,....==">

除非你的页面有静态缓存,否则你的favicon将无法被缓存,根据favicon图像的大小,你的源代码可能会因此变得有点臃肿。

数据URI favicons似乎在大多数现代浏览器中都可以工作;在我的Mac电脑上,它可以在最新版本的Chrome、Firefox和Safari浏览器上运行。但似乎不能在ie浏览器上运行,可能也不能在某些版本的Opera上运行。

如果你担心旧的Internet Explorer版本(现在你可能不应该担心),你可以包含一个Internet Explorer条件注释,它会以传统的方式加载实际的favicon.ico,因为旧的Internet Explorer似乎不支持数据URI favicons。

`<!--[if IE ]><link rel="shortcut icon" href="http://example.com/favicon.ico"  type="image/x-icon" /><![endif]--> `
  1. 在根目录中包含favicon.ico文件,以涵盖以任何方式请求它的浏览器,因为对于这些浏览器,如果无论您做什么,它们都已经在检查,那么您最好不要用404响应浪费HTTP请求。

你也可以只使用另一个流行站点的favicon,这个站点很可能缓存了他们的favicon,比如http://google.com/favicon.ico,这样它就可以从缓存中提供服务。

正如评论者指出的那样,仅仅因为你可以这样做并不意味着你应该这样做,因为一些浏览器会请求favicon.ico,不管我们设计了什么技巧。与gzipping、为静态内容使用远未来过期头文件、缩小JavaScript文件、将背景图像放入精灵或数据uri、从CDN提供静态文件等操作所节省的开销相比,这样做所节省的开销是微乎其微的。

我在这个页面上找到了一个有趣的解决方案。它是用德语写的,但你应该能看懂代码。

您将图标的base64数据放入外部样式表中,因此它将被缓存。在你的网站头部,你必须定义带有id的favicon,并且favicon在样式表中设置为该id的background-image

link#icon {
background-image:url("data:image/x-icon;base64,<base64_image_data>");
}

还有HTML

<html>
<head>
<link id="icon" rel="shortcut icon" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="/styles.css" />
...
</head>
<body>
...
</body>
</html>

很抱歉,您不能将favicon与其他资源合并。

这意味着你基本上有两个选择:

    如果你对你的网站没有图标感到满意-你可以让href指向一个已经被加载的非图标资源(例如,一个样式表,脚本文件,甚至一些受益于预取的资源)。 (我的简短测试表明,这可以在大多数(如果不是所有的话)主要浏览器上运行。

  1. 接受额外的HTTP请求,只要确保你的favicon文件有侵略性的HTTP缓存控制头设置。 (如果你有其他网站在你的控制下,你甚至可以让他们偷偷地预装这个网站的图标-连同其他静态资源。)

注:创造性解决方案:

  • 奇怪的CSS数据URI技巧(由评论者Felix Geenen链接)不起作用
  • 使用JavaScript执行favicon <link>元素的延迟注入(如用户yc建议)可能只会让事情变得更糟——导致两个 HTTP请求。

正确的解决方案是使用HTTP管道

HTTP管道是一种将多个HTTP请求写入到单个套接字而不等待相应响应的技术。只有HTTP/1.1支持管道,1.0中不支持。

它要求服务器支持它,但不一定参与其中。

HTTP管道需要客户端和服务器都支持它。符合HTTP/1.1的服务器需要支持流水线。这并不是说服务器必须通过管道处理响应,而是说如果客户端选择通过管道处理请求,服务器必须不会失败。

许多浏览器客户端在应该这样做的时候却没有这样做。

HTTP管道在大多数浏览器中是禁用的。

  • Opera默认启用了流水线。它使用启发式来控制所使用的流水线级别,取决于所连接的服务器。
  • 由于担心代理和行首阻塞问题,ie8不支持流水线请求。
  • Mozilla浏览器(如Mozilla Firefox, SeaMonkey和Camino)支持流水线,但默认情况下是禁用的。它使用了一些启发式方法,特别是关闭IIS服务器的管道。
  • Konqueror 2.0支持流水线,但默认情况下是禁用的。[引文需要]
  • 谷歌Chrome不支持流水线。

我建议你尝试在Firefox中启用管道,或者直接使用Opera(不寒而栗)。

我认为在大多数情况下,它不会导致另一个HTTP请求,因为这些请求通常在第一次访问后被转储到浏览器的缓存中。

这实际上比任何提出的“解决方案”都更有效。

@yc的回答的一个小改进是从通常会被使用和缓存的JavaScript文件中注入base64编码的favicon,并且通过在相关的meta标记中提供数据URI来抑制请求favicon.ico的标准浏览器行为。

这项技术避免了额外的http请求,并且被证实适用于Windows 7上最新版本的Chrome、Firefox和Opera。然而,它似乎工作在Internet Explorer 9至少。

文件index . html

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Suppress browser request for favicon.ico -->
<link rel="shortcut icon"type="image/x-icon" href="data:image/x-icon;,">
<script src="script.js"></script>
...

文件script.js

var favIcon = "\
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABrUlEQVR42mNkwAOepOgxMTD9mwhk\
[...truncated for brevity...]
IALgNIBUQBUDAFi2whGNUZ3eAAAAAElFTkSuQmCC";


var docHead = document.getElementsByTagName('head')[0];
var newLink = document.createElement('link');
newLink.rel = 'shortcut icon';
newLink.href = 'data:image/png;base64,'+favIcon;
docHead.appendChild(newLink);


/* Other JavaScript code would normally be in here too. */

演示:turi.co /了/ favicon.html

你可以使用base64编码的favicon,像这样:

<link href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAACbUlEQVRIx7WUsU/qUBTGv96WSlWeEBZijJggxrREdwYixMnByYEyOvgfsBAMG0xuDsZ/QGc3NDFhgTioiYsmkhBYGLSBkLYR0va8gSjvQXiIT7/l5ibfOd/v3pN7gSmVSMTj8ThRfzdYk8lkMpl83/+AVFVVVXU0eHiVJEmSpB8DIcpkMplsdhCYz+fzhQJROBwOh8PDQN+oQCAQCASIRFEURZHI45GkP0/e7Xa73e70AMJnjel0Op1OA6oaDB4eAkAw6PcDvZ5t6zrw/Hx2trAw/cHYZ426ruu6DtzcGEYuBzQa19etFvD4WKtls4AoRqMPDwBjjLGPrt84ilgsFovF6EOapmmaRiP6O/jbAIguL4vFYpHGqlKpVCoVomq1Wq1Wibxer9fn+w+Q9+cUiUQikQhNrfdgWZZlWf4yyGhj27Zt254MUK/X6/X6F0aiKIqiKIOCYRmGYRjGZADLsizLIgqFQqHV1SkAnp5OTn79ItK0qyuPZ7SxaZqmaU4GKJfPzxmbfAPc/f3pqaIQLS8vLtZqgOP0bYyJoiAARC5Xrwf4/Vtbb2+Th1YqlUqlErC01GgkEkCz2WxyHLC+LsuiCAiCJLlcgM+3vd3pcBzXaJTLR0dEs7Ptdv+D4TiOG/A6DsBxQKvV621sAGtru7vl8ngAjuvXv7xcXIgiwNjMjCj2h+k4fQfPA4LA8xwHCO323V2hABiG223bwPy8xwMAbvfcHGMAY32j47y+3t4OAsZpZ2dzEwAsy7IcBxAExhwHMIxOx3GAlZVUyjT/1WFIudzenstFlEpFo9M8o+Pj/X2eJzo4SCR4fnzdb2N4Pyv9cduVAAAAAElFTkSuQmCC" rel="icon" type="image/x-icon" />

这并不是问题的真正答案,而只是对马塞尔yahelc给出的答案的补充。我为404图标问题提供了一个优雅的解决方案。

一些应用程序和浏览器检查favicon.ico文件,如果图标在站点根目录中没有找到,你可以简单地用204响应头响应请求。

Apache的例子:

Apache选项一(也是我最喜欢的),在你的.htacces或.conf中简单的一行代码:

Redirect 204 /favicon.ico

Apache选项二:

<Files "favicon.ico">
ErrorDocument 204 ""
</Files>

为了进一步阅读,有一个很好的Stoyan Stefanov的博客文章

这真的重要吗?

许多浏览器以低优先级加载favicon,这样它就不会阻塞页面加载,所以是的,这是一个额外的请求,但它不在任何关键路径上。

JavaScript解决方案很糟糕,因为JavaScript代码已经被检索和执行,下面所有的DOM元素将被阻止呈现,并且它不会减少请求的数量!

您可以使用8位PNG图像代替ICO格式,以获得更小的数据占用。你唯一需要改变的是使用“data:image/png”;不是“data:image/x-icon"MIME类型头:

<link
href="data:image/png;base64,your-base64-encoded-string-goes-here"
rel="icon" type="image/png"
/>

“type"属性可以是" image/png"或“图像/ x-icon"。两者都对我有用。

你可以使用GIMP或convert将ICO转换为8位PNG:

convert favicon.ico -depth 8 -strip favicon.png

并使用base64命令将PNG二进制编码为Base64-string:

base64 favicon.png

这是最简单的方法:

<!DOCTYPE html><html><head>
<link rel="shortcut icon" href="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAA
lwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4
OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3
JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9y
Zy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdG
lvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25z
LmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj
4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAg
PC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAABLJJREFUWAnFV+trW2UY/yVN0j
S32q6bnWunQ1e11k3YXMUy8AbDoSBDv4mfFPTj/gD9ug/7B/woqCCISnGItcyppbgN
Rhn2st5G2yxt1svSJe1yPYnP703fcs7JSZo4YS9Ncs57eX6/5/Y+T12fX7hYdAHy92
iG+1GCU2X3/6V3k9sNl8uFUqnUkMiHJkDfuQV4M7WFbC4Hr8fTEAlPQ3RtmwleFI0z
mQxO95/EQP8pLEaj+PaHQbS3RmAUi7YTla8PRYDGLhgGPnz/HI719Srp0VgMhszRHf
WM/+wC+jy1tY2zb72uwOl7WmPi1gwCfr887609CdZtAfpZa0XNc/k8nug8gBPHjylF
uTY7N4/JmVmEQkFlBbWwx9eeBNyiKbVLZ7IKlEAtomEmm0Vvz1G0tLQoiKXoHXzz/Y
9qX75QgM/jhb/ZB5KtlRk1CdDM2+k0SKLn6SM4KBoXRHhsOY6J2XmsbWxgdv42Jqdn
cH3sJo4c7sKhg50oFku4s7yMuYUleJqahEizzDm7pCoBgt8XH7/Q8wzOvPmamLtz1w
UMvPjdu1hYjIrPp9He9hjOf/oJ9rW37e5hBiwuRXFpaBjR5RWEgkFHEq4vLlysuDkI
nhTwV068hPfeOau0oJ21KXUsKNvbvux7suKq734axNT0nLhOLCHuNI8KC1B4Wg7RnO
++fUaB03x0gxlYA1EYZcoxta73cJ3PD8SFuWxOnbdCl2k4EuCN9sbpATT7fMpsBLcP
DcR5gpuHBk8mU/jyq6+xcW8TYckMpziwSKagvKTX4x0deOpwt5JpBjKD1PM8eu064q
vraI2EHcEpw0pAqnK+YODA/n3wS6pxNEpAa58TK05IdoQl+AyjoGQ5fVkI0JbFoqEi
tlFgu/C01IeM3B2UY4s7y1YrAbXUeEm1SNx58Un8sDJKiNbsdiwEaD6m4JakoFPAOA
HZ57TleFs+2d2lMsotl1G1YSHATR5PEzYSCXXt8p2kGh36zED/y+o8qyNridOwEOBB
j5htI7GJ1bU1p/11zZX9XkJ31yF89MG5nTpScAxoCwFKZ86z8NxeWKwLrNom7YrjL/
bh/GcfY39Hu2RYJYkKAvR9KBjAjZv/CJHMThQ37gYS066IhMNgWmpSZtIVBHio2euV
AhLH+OSU2qsFmQ828jx69Rpi8VX4vJX9YgUBCmbBCIsVhv8cQTKVKt/jDsFIYvpjJ0
RLUuPYygqujF5FG3tEo7IkOxKgUObwvcR9DF2+omRTmE5NDco5/dFzSoGd4sWaMvjL
kCJZJQmsV7FZC9bziBSQv2+M4Y+RUbWki5IGZXPC1oy/eo4buY9W/PnX3zC/uFTuEa
VJcRoV1dC8iSRawyFcGv4dqe1tvHrqpFS1EFbX1zE+dQvT0hVlpNSyzvc+exR9zz8n
zUmbVL8ELv81grHxSbTK/lrtuWNDYibBZ14iSSEQlP6PGbIpZTadzkg/6Fdr1PaBvI
cCLYgIYa7TKsFAYNdtdpn6vaYF9CYCREQTxkBS/gPySZb42SvIvDhYNQRsQBlkal3i
R/cSWka137oI8LAOQF7VDDiDwHrw3Si/l9eFl5CtZzhmQa2DZlynfXut28/8C/JOMz
7+5SRKAAAAAElFTkSuQmCC">
</head></html>

它代表什么图标?回答下面!

2020年杀手级解决方案

这个解决方案必然是在这个问题最初提出9年后才出现的,因为直到最近,大多数浏览器还不能处理.svg格式的favicons。

但现在情况不同了。

看:https://caniuse.com/#feat=link-icon-svg


1)选择SVG作为Favicon格式

现在,在2020年6月,这些浏览器可以处理SVG图标:

  • 火狐
  • 边缘
  • 歌剧
  • Chrome for Android
  • kaio浏览器

注意这些浏览器仍然不能:

  • Safari
  • iOS狩猎
  • Firefox for Android

然而,考虑到上面的内容,我们现在可以合理地使用SVG图标


2)将SVG表示为数据URL

这里的主要目标是避免HTTP请求。

正如本页上的其他解决方案所提到的,一个非常聪明的方法是使用数据的URL而不是HTTP URL

svg(尤其是小的svg)将自己的完美的借给数据url,因为后者只是明文(包含任何可能存在歧义的百分比编码字符),而前者是XML,可以非常直接地写成一长行明文(包含少量百分比代码)。


3) 整个 SVG是一个单一的表情符号

注意:此步骤是可选的。你的SVG 可以是一个单一的表情符号,但它也可以是一个更复杂的SVG。

2019年12月,莱安德罗利纳雷斯率先意识到,由于Chrome已经加入Firefox,支持SVG favicon,因此值得进行实验,看看是否可以用表情符号创建favicon:

https://lean8086.com/articles/using-an-emoji-as-favicon-with-svg/

利纳雷斯的预感是对的。

几个月后(2020年3月),代码盗版Lea Verou意识到同样的事情:

https://twitter.com/leaverou/status/1241619866475474946

favicon再也不一样了。


4)自己实施解决方案:

下面是一个简单的SVG:

<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16">


<text x="0" y="14">🦄</text>
</svg>

这里是与数据的URL相同的SVG:

data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Ctext%20x='0'%20y='14'%3E🦄%3C/text%3E%3C/svg%3E

最后,这里是数据的URL作为Favicon:

<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Ctext%20x='0'%20y='14'%3E🦄%3C/text%3E%3C/svg%3E" type="image/svg+xml" />

5)更多的技巧(…这些不是你父母的偶像!)

由于Favicon是SVG,任何数量的过滤器效果(SVG和CSS)都可以应用于它。

例如,除了上面的白色独角兽,我们可以通过应用过滤器轻松地创建黑独角兽图标:

style="filter: invert(100%);"

黑独角兽图标:

<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Ctext%20x='0'%20y='14'%20style='filter:%20invert(100%);'%3E🦄%3C/text%3E%3C/svg%3E" type="image/svg+xml" />