【问题标题】:Why do all browsers download all CSS files - even for media types they don't support?为什么所有浏览器都下载所有 CSS 文件——即使是它们不支持的媒体类型?
【发布时间】:2011-09-12 18:21:46
【问题描述】:

如果我使用不受支持的媒体类型 ("bork") 指定 CSS 链接,它仍然会被我尝试过的每个浏览器(包括桌面浏览器和多个移动浏览器)下载。

<link href="bork.css" media="bork" rel="stylesheet" type="text/css" />

而且情况变得更糟......

如果文件 bork.css @imports 是另一个 CSS 文件(也具有不受支持的媒体类型),那么第二个 CSS 文件会被下载。

/* Inside "bork.css" */
@import url("bork2.css") bork, bork;

为什么!?

我的第一个假设是某些浏览器可能会搜索嵌套的 @imports 或 @media 块及其支持的媒体类型 - 然后应用这些文件中包含的样式规则...

/* Inside "bork2.css" */
@import url("all.css");
@media all {
  /* rules */
}

...但据我所知,没有一个浏览器可以做到这一点。 (幸运的是,这将是一个错误。)

所以所有这些下载似乎都是多余的 - 除非有一些我一直错过的解释。

编辑:我想了解的是,它促使浏览器制造商去:
“嘿!我们正在努力让我们的浏览器快速疯狂!让我们下载一个一堆我们无意应用的 CSS 文件,同时停止加载其他资源!”

【问题讨论】:

  • webmasterworld.com/forum83/7981.htm 确定不是缓存问题?
  • 绝对确定!不涉及缓存。
  • 您的意思是浏览器决定 忽略media 属性,直到它们执行了不必要的HTTP 请求。是的,但是为什么他们会这样做?
  • 我的问题是页面加载速度和带宽使用情况(尤其是在缓慢而昂贵的移动网络上)
  • 打印媒体样式表也被加载。似乎没有个例外。

标签: css


【解决方案1】:

我认为答案是这样的:

允许并鼓励浏览器解析 media 描述符 - 无论是什么描述符 - 作为使它们对未来友好的一种方式

HTML 的未来版本可能会引入 新值,可能允许参数化 价值观。

*发件人:http://www.w3.org/TR/html4/types.html#h-6.13

这样一来,媒体有一天可能会包含3d-glasses或其他描述符,包括bork;-)

编辑:

关于媒体查询的最新 CSS3 规范说明了这一点,它在一定程度上支持上述内容:

未知媒体 类型评估为假。有效, 它们的处理方式与已知的相同 不匹配的媒体类型 设备的媒体类型。

*发件人:http://dev.w3.org/csswg/css3-mediaqueries/#error-handling

因此它们被视为已知并下载以供使用,只是当时/不适用于该设备。

【讨论】:

  • 未来引入的新媒体价值不会自动使其适用于当今的浏览器。为什么今天下载这些 CSS 文件?
  • 我猜浏览器想要向后兼容,以防开发新的描述符。
  • 本文档描述了解析媒体属性的值,但没有提及如果该值不适用于当前媒体,浏览器实际下载文件的内容。
  • 你的意思是向后兼容未来的变化?这似乎非常,嗯,倒退了。 ;-)
  • @Wesley。是的,同意,但这也可以解释为什么浏览器会下载……因为没有设定值。 @Már Örlygsson 同意 ;-)
【解决方案2】:

认为他们加载所有媒体查询的真正原因是因为许多设备在加载后会更改对这些查询的响应。

在页面加载时对 iPhone5 进行纵向成像(报告“宽度”为 640 像素,但不是“纵向”,不幸的是 iSeries 不支持这些查询)...然后您决定将 iPhone 侧向转动,然后浏览器现在激活伪横向模式(同样,从宽度 @ 1126 而不是“横向”触发)。

很可能,响应式网页设计旨在将不同的样式表提供给显示为 640 的浏览器(相当窄,可能是手机/平板电脑),而不是提供给显示为 1126 的浏览器(更可能是笔记本电脑)。

如果它不费心加载额外的媒体查询表,那么它会突然停止,发出一个 http 请求,等待表加载,然后解析它以显示。这可能会导致相当糟糕的延迟。

由于大多数浏览器都遵循代码重用模式,例如,Webkit 或 Gecko 的核心块可能不知道它们是在笔记本电脑上还是平板电脑上(好像这些线并没有开始模糊),它只是加载每个媒体查询,而不管他们是否选择显示它。

虽然这可以避免每个浏览器看起来很糟糕,但总的来说它破坏了媒体查询背后的大部分实用程序。

手机或廉价的安卓平板电脑不应该下载它根本不需要的额外文件(尤其是在有限的数据计划中)。

目前,我的设计确实使用媒体查询,但我很少使用它们。我网站上的大部分媒体查询都是通过 javascript 加载所需文件来实现的,以消除这种浪费。其余查询用于关闭 javascript 的情况,或者用于需要“以防万一”加载的工作表(例如,我的 640 像素布局通常总是被加载,因为大多数设备可能会在一种情况下显示它或另一种情况)。

如果有人有更好、更清洁的方法来处理这个问题,请告诉我。

与此同时,如果您能想到一个简单的实现功能来规避这个问题(可能是浏览器内置的 android 风格的清单?),您可能想向 Mozilla 或 Chromium 团队写信……似乎就像他们可以在这个上用一只手一样。

【讨论】:

  • 浏览器肯定知道它的窗口大小,因此可以安全地忽略标记为仅用于较大窗口的样式表。此外,浏览器在看到 CSS &lt;link&gt;s 之前已经达到“移动友好”&lt;meta&gt; 声明,这进一步消除了为不受支持的屏幕媒体加载 CSS 的需要。
  • ...还请注意,浏览器总是加载 media="bork" 样式表,即使他们无意使用这些样式(因为 bork 不是受支持的媒体类型)
【解决方案3】:

在考虑了更多之后,我形成了一个理论,即可能有一个通用的“规则”在起作用——任何样式表、图像或脚本都会被下载,不问任何问题,无论指定的 mime-type 或媒体属性如何.

不过,经过快速测试,结果有点模棱两可……

  1. &lt;script src="bork.js" type="bork/bork"&gt;&lt;/script&gt;
  2. &lt;script src="bork2.js" type="text/bork"&gt;&lt;/script&gt;

Chrome 12 下载 既不
IE8 下载 #2
Firefox 4 下载两者
Opera 11 下载两者
Safari 5 Win 小伙子两者都

仍然没有在任何浏览器中进行解析或运行。任何一个文件中的 javascript alert(); 都不会运行。这与 CSS 加载情况略有不同,因为浏览器解析 bork-media CSS 代码以获取 @include 指令并递归下载这些资源。

【讨论】:

    【解决方案4】:

    答案可能归结为媒体查询。以这些为例:

    <link rel="stylesheet" media="(min-width: 300px)" href="example1.css" />
    <link rel="stylesheet" media="(min-width: 1000px)" href="example2.css" />
    

    如果使用窗口大小为 600px 的浏览器,将应用 example1.css 样式表。如果窗口大小调整为 1200 像素,则样式表 example2.css 可以立即应用,而无需等待它先下载。

    值得注意的是,即使仍然下载了不匹配的媒体查询样式表,它也不会在下载时阻止渲染(通常需要下载所有 CSS 文件才能开始渲染)。

    【讨论】:

    • “值得注意的是,即使仍然下载了不匹配的媒体查询样式表,它在下载时也不会阻塞渲染” - 换句话说,非-匹配的样式表是异步加载的。接得好。你能引用一个来源吗?
    【解决方案5】:

    有时,有必要考虑平淡无奇的答案。浏览器可能会下载所有样式表,这仅仅是因为每个浏览器的作者在优化速度时只真正考虑了存在单个(主)样式表的情况,并且许多网站都使用单个样式表的做法鼓励了这一点行为。如果没有人对其进行测试,那么几乎可以肯定它不是正在优化的案例,因为人们更喜欢处理可见(或至少可测量)的结果。也许您的问题会鼓励某人改变测试制度……

    此外,我敢肯定,绝大多数网站的样式表都是静态文档,因此能够被高度缓存(如果网站所有者选择付费,也可以通过 CDN 交付)。

    【讨论】:

    • +1 有趣的理论,但它引出了一个问题,为什么没有一个浏览器(包括允许关闭图像和脚本文件的移动浏览器)决定跳过不受支持的样式表。打印样式表很常见,几乎没有手机支持打印。
    【解决方案6】:

    我能想到的唯一合乎逻辑的原因是,当您动态 (javascript) 将 &lt;link&gt; 元素的错误属性值更改为可识别的值时,文件 必须 立即可用。
    事实上,在某些情况下,如果您想加载文件但将其设备推迟到以后使用,则可以将其视为一项功能。

    【讨论】:

    • +1 这是一个已经考虑过的理论。但是,我从未在野外见过这种情况。
    【解决方案7】:

    因此,如果您真的不想在发生某些事情之前下载 CSS 文件,您可以尝试验证页面何时加载是否满足某些条件,如果满足,那么您可以执行 "lazy load" 并将注释代码(type 8 元素,在本例中是您的 style 标签)存储在新创建的 style 标签子中,这将使浏览器验证新创建的内容,并将下载 CSS 文件以使样式生效。

    您在尝试实施它时可能遇到的任何问题,请不要犹豫,要求澄清一下,也许我可以帮助您解决问题。它适用于几乎所有您不想被下载或处理的东西(图像、js、css 等),直到发生某些事情或满足某些限制。

    我已经对其进行了测试并且 IT WORKS :D,所以您可以使用此代码开始,希望对您有所帮助

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>TEST CODE</title>
    <script type="text/javascript"> 
    
        function test(){
            var elems = document.body.childNodes;
            alert(elems);
            for (var i = 0, il = elems.length; i < il; i++) {
               var el = elems[i];
               alert(el.nodeType);
               if (el.nodeType == 8) {
               var style = document.createElement('style');
               style.innerHTML = el.nodeValue;
               document.getElementById("css").appendChild(style);
               break;
               }
            }
        }
     </script >
    
     <style id="css">
     </style>
     </head>
     <body onload="test()">
     <!--@import url(red.css) (min-width:400px) and (max-width:599px);-->
     </body>
     </html>
    

    【讨论】:

      猜你喜欢
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多