Javascript 一个小小的图标需要另一个 HTTP 请求,这不是很愚蠢吗?如何将网站图标放入精灵中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5199902/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:08:45  来源:igfitidea点击:

Isn't it silly that a tiny favicon requires yet another HTTP request? How can I put the favicon into a sprite?

javascripthtmlcssperformancefavicon

提问by Sam

Everybody knows how to set up a favicon.ico link in HTML:

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

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

But I think it is just silly that for a tiny several-byte icon you need yet another HTTP request. So I wondered, how could I make that image part of a sprite (e.g. background-position=0px -200px;) in order to speed up and save that valuable HTTP request. How can I get this into an existing sprite image with my logo and other artworks?

但是我认为对于一个很小的几个字节的图标,您还需要另一个 HTTP request是愚蠢的。所以我想知道,我怎样才能使该图像成为精灵(例如background-position=0px -200px;)的一部分,以加快和保存有价值的 HTTP 请求。如何将其与我的徽标和其他艺术品一起放入现有的精灵图像中?

The robot pointing to favicon.ico, item number 31 on the waterfall graph, is my pet ZAM. He's usually happier and he has a good point letting me know it's time for some creative upgrades on the web, though he and I don't agree on his outfit, which I think is a bit silly today...

指向favicon.ico瀑布图上第 31 项的机器人是我的宠物 ZAM。他通常更快乐,他有一个很好的观点让我知道是时候在网络上进行一些创造性的升级了,尽管他和我不同意他的着装,我认为今天这有点愚蠢......

enter image description here

在此处输入图片说明

采纳答案by Marcel

A minor improvement to @yc's answeris injecting the base64-encoded favicon from a JavaScript file that would normally be used and cached anyway, and also suppressing the standard browser behavior of requesting favicon.icoby feeding it a data URI in the relevant metatag.

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

This technique avoids the extra http request and is confirmed to work in recent versions of Chrome, Firefox and Opera on Windows 7. However it doesn'tappear to work in Internet Explorer 9 at least.

这种技术避免了额外的 http 请求,并被确认在 Windows 7 上的最新版本的 Chrome、Firefox 和 Opera 中工作。但是它似乎至少在 Internet Explorer 9 中不起作用。

index.html

索引.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

脚本.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 JS would normally be in here too. */

Demo: turi.co/up/favicon.html

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

回答by James Anderson

I think for the most part it does not result in another HTTP request as these are usually dumped in the browser's cache after the first access.

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

This is actually more efficient than any of the proposed "solutions".

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

回答by Yahel

You could try a data URI. No HTTP request!

您可以尝试使用数据 URI。没有 HTTP 请求!

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

Unless your pages have static caching, your favicon wouldn't be able to be cached, and depending on the size of your favicon image, your source code could get kind of bloated as a result.

除非您的页面具有静态缓存,否则您的网站图标将无法被缓存,并且根据您的网站图标图像的大小,您的源代码可能会因此变得臃肿。

Data URI favicons seems to work in most modern browsers; I have it working in recent versions of Chrome, Firefox and Safari on a Mac. Doesn't seem to work in Internet Explorer, and possibly some versions of Opera.

数据 URI 图标似乎适用于大多数现代浏览器;我让它在 Mac 上最新版本的 Chrome、Firefox 和 Safari 中运行。似乎在 Internet Explorer 中不起作用,可能在某些版本的 Opera 中也不起作用。

If you're worried about Old IE (and you probably shouldn't be these days), you could include an IE conditional comment that would load the actual favicon.ico in the traditional way, since it seems that older Internet Explorer doesn't support Data URI Favicons

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

`<!--[if IE ]><link rel="shortcut icon" href="http://example.com/favicon.ico"  type="image/x-icon" /><![endif]--> `
  1. Include the favicon.ico file in your root directory to cover browsers that will request it either way, since for those browsers, if they're already checking no matter what you do, you might as well not waste the HTTP request with a 404 response.
  1. 在您的根目录中包含 favicon.ico 文件以覆盖以任何一种方式请求它的浏览器,因为对于这些浏览器,如果无论您做什么,它们都已经在检查,您最好不要浪费带有 404 响应的 HTTP 请求.

You could also just use the favicon of another popular site which is likely to have their favicon cached, like http://google.com/favicon.ico, so that it is served from cache.

您也可以只使用另一个流行网站的网站图标,该网站可能会缓存他们的网站图标,例如http://google.com/favicon.ico,以便从缓存中提供服务。

As commenters have pointed out, just because you cando this doesn't mean you should, since some browsers will request favicon.ico regardless of the tricks we devise. The amount of overhead you'd save by doing this would be minuscule compared to the savings you'd get from doing things like gzipping, using far-future expires headers for static content, minifying JavaScript files, putting background images into sprites or data URIs, serving static files off of a CDN, etc.

正如评论者指出的那样,仅仅因为您可以这样做并不意味着您应该这样做,因为无论我们设计什么技巧,某些浏览器都会请求 favicon.ico。与您通过执行 gzip 压缩、使用远期到期的静态内容标头、缩小 JavaScript 文件、将背景图像放入 sprite 或数据 URI 等操作所节省的费用相比,您这样做所节省的开销是微不足道的,从 CDN 提供静态文件等。

回答by Dongsheng Cai

You could use base64 encoded favicon, like:

您可以使用 base64 编码的图标,例如:

<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" /> 

回答by Felix Geenen

I found an interesting solution on this page. It is german but you will be able to understand the code.

我在这个页面上找到了一个有趣的解决方案。它是德语,但您将能够理解代码。

You put the base64 data of the icon into an external stylesheet, so it will be cached. In the head of your website you have to define the favicon with an id and the favicon is set as a background-imagein the stylesheet for that id.

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

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

and the html

和 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>

回答by Pekka

Good point and nice idea, but impossible. A favicon needs to be a single, separate resource. There is no way to combine it with another image file.

好点子和好主意,但不可能。网站图标需要是一个单独的资源。没有办法将它与另一个图像文件结合起来。

回答by Andy Davies

Does it really matter?

真的有关系吗?

Many browsers load the favicon as a low priority so that it doesn't block the page load in anyway, so yes it's an extra request but it's not on any critical path.

许多浏览器将图标加载为低优先级,因此它不会以任何方式阻止页面加载,所以是的,这是一个额外的请求,但它不在任何关键路径上。

The accepted solution is horrible as until the JS has been retrieved and executed all the DOM elements below will be blocked from rendering and it doesn't reduce the number of requests!

接受的解决方案很糟糕,因为在检索并执行 JS 之前,下面的所有 DOM 元素都将被阻止呈现,并且不会减少请求的数量!

回答by Matt Joiner

The proper solution is to use HTTP pipelining.

正确的解决方案是使用HTTP 流水线

HTTP pipelining is a technique in which multiple HTTP requests are written out to a single socket without waiting for the corresponding responses. Pipelining is only supported in HTTP/1.1, not in 1.0.

HTTP 流水线是一种将多个 HTTP 请求写出到单个套接字而不等待相应响应的技术。流水线仅在 HTTP/1.1 中受支持,在 1.0 中不支持。

It's required that servers support it, but not necessarily partipate.

需要服务器支持,但不一定参与。

HTTP pipelining requires both the client and the server to support it. HTTP/1.1 conforming servers are required to support pipelining. This does not mean that servers are required to pipeline responses, but that they are required not to fail if a client chooses to pipeline requests.

HTTP 流水线需要客户端和服务器都支持它。需要符合 HTTP/1.1 的服务器来支持流水线。这并不意味着服务器需要管道响应,但如果客户端选择管道请求,则要求它们不会失败。

Many browser clients don't do it, when they should.

许多浏览器客户端不这样做,而应该这样做。

HTTP pipelining is disabled in most browsers.

  • Opera has pipelining enabled by default. It uses heuristics to control the level of pipelining employed depending on the connected server.
  • Internet Explorer 8 does not pipeline requests, due to concerns regarding buggy proxies and head-of-line blocking.
  • Mozilla browsers (such as Mozilla Firefox, SeaMonkey and Camino), support pipelining however it is disabled by default. It uses some heuristics, especially to turn pipelining off for IIS servers.
  • Konqueror 2.0 supports pipelining, but it's disabled by default.[citation needed]
  • Google Chrome does not support pipelining.

大多数浏览器都禁用了 HTTP 流水线。

  • Opera 默认启用流水线。它使用启发式方法根据连接的服务器控制采用的流水线级别。
  • Internet Explorer 8 不管道请求,因为担心有问题的代理和行头阻塞。
  • Mozilla 浏览器(例如 Mozilla Firefox、SeaMonkey 和 Camino)支持流水线,但默认情况下是禁用的。它使用一些启发式方法,特别是关闭 IIS 服务器的流水线。
  • Konqueror 2.0 支持流水线,但默认情况下是禁用的。[需要引用]
  • 谷歌浏览器不支持流水线。

I would recommend you try enabling pipelining in Firefox and try it there, or just use Opera (shudder).

我建议您尝试在 Firefox 中启用流水线并在那里尝试,或者只使用 Opera(不寒而栗)。

回答by Anthony Hatzopoulos

Not really an answer to the question but simply to compliment the answers given by Marceland yahelcI offer an elegant solution to the 404 favicon issue.

不是真正的问题的答案,而只是为了赞美Marcelyahelc给出的答案,我为 404 图标问题提供了一个优雅的解决方案。

Because some apps and browsers and whatnot check for a favicon.com and if the icon is not found in the site root you can simply respond to the request with the 204 responseheader.

因为某些应用程序和浏览器等不会检查 favicon.com,如果在站点根目录中找不到该图标,您可以简单地使用204 响应标头响应请求。

Apache Examples:

阿帕奇示例:

Apache option one (and my favorite), simple one liner in your .htacces or .conf:

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

Redirect 204 /favicon.ico

Apache option two:

Apache选项二:

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

For further reading, there is nice blog post by Stoyan Stefanov at http://www.phpied.com/204-no-content/

如需进一步阅读,Stoyan Stefanov 在http://www.phpied.com/204-no-content/ 上有一篇不错的博客文章

回答by cusimar9

Its a great idea, but if Google hasn't done it on their homepage, I'm betting it can't (currently) be done

这是一个好主意,但如果谷歌没有在他们的主页上做过,我敢打赌(目前)不能做到