【问题标题】:Eliminate style loading using media queries使用媒体查询消除样式加载
【发布时间】:2017-12-08 05:25:22
【问题描述】:

我尝试通过消除不必要的下载来加快初始加载速度。 我将样式拆分为纵向和横向 css。 并且只想根据媒体查询加载一种样式。 但似乎他们正在一起加载。

<body>
  <link rel="stylesheet" type="text/css" href="style-p.css" media="(orientation: portrait)" />
  <link rel="stylesheet" type="text/css" href="style-l.css" media="(orientation: landscape)" />
</body>

【问题讨论】:

    标签: html css media-queries


    【解决方案1】:

    &lt;link&gt; 标签中的media 属性的目的是决定何时应用资源,而不是是否加载。它总是加载。


    所以,简单地说,您似乎想要的是没有 JavaScript 是不可能的。当前的 CSS Editor's Draft 中没有任何内容表明它应该或将永远可以使用干净的 HTML + CSS。

    如果你仔细想想,这很有意义。将您的设备从landscape 翻转到portrait 所需要的只是一位热心同事背上的宠物。如果您必须在应用布局更改之前等待资源加载,则不可能提供体面的用户体验。

    规范最接近主题的是:

    用户代理必须重新评估媒体查询以响应他们知道的用户环境的变化,例如,如果设备从横向平铺到纵向,并改变依赖于这些媒体的任何构造的行为相应地查询。

    但是有一个重要的注意事项:大多数现代浏览器做出了以下(智能)选择:它们加载 &lt;link&gt; 资源,其 media 属性评估为非阻塞 false 以减少初始渲染所需的时间向用户发送的页面。
    One of the first articles 在该主题上广为传播是由 Keith Clark 撰写的。您可能还会发现 Taylor Hunt 的 follow up 很有趣。


    如果您仍然对基于@media 查询条件加载样式表感兴趣,则需要load them using JavaScript。对于 JavaScript 中@media 查询的性能检测,我推荐enquire.js

    【讨论】:

      【解决方案2】:

      目前,浏览器仍然无法根据 media 属性动态加载 &lt;link&gt; 中的资源。

      请参阅 this article 以更深入地讨论和实现此功能。


      选项 1:保持原样

      如果您的应用程序不是那么大并且样式不占用太多带宽,那么最好保持它们不变。缓存是你的朋友。初始加载可能很慢,但后续对资源的请求将通过缓存进行代理。


      选项 2:使用 JavaScript 加载样式

      如果您的样式每个占用大约 500KB,您最好使用 JavaScript 异步加载它们。

      这会给你的应用程序增加更多的复杂性(更不用说你是否使用了复杂的构建工具,如 grunt、gulp 或 webpack),但它可以使初始加载更快(或者至少,似乎 更快)。

      如果你想走这条路,你可以简单地在你的&lt;body&gt; 的底部包含一个小脚本,它检查用户的环境,加载适当的 css 文件,将内容注入到样式标签中,并附加该样式标记到文档&lt;head&gt;


      其他说明

      就个人而言,我认为将样式分为landscape 样式和portrait 样式并不是组织样式的最佳方式。更好的代码分离技术可能是为应用程序的不同页面设置不同的样式,并且仅根据活动页面加载特定样式。 (但这仍然取决于您的布局是否严重依赖纵向/横向媒体查询)。

      不言而喻,但这些都取决于您使用的环境以及您可以访问的可用服务器端解决方案。这甚至取决于您愿意付出多少努力来将初始加载时间缩短 10 毫秒。

      我想说您现在最好的选择是将两个文件合并为一个文件(这样在 HTTP/2 之前加载的资源加载速度更快)并将其保留在您的所有页面上。第一次加载后,它会被缓存,并且该资源将(几乎)立即加载。如果您绝对讨厌白屏,请在您的应用开始时添加一个有趣的动画预加载,以在您的用户等待您的样式在第一次渲染时加载时娱乐他们。

      【讨论】:

      • 你做了一些一般性的声明。比如“浏览器在加载链接时不检查媒体查询”。虽然这在过去可能是正确的,但它可能会改变,所以你的答案会逐渐变得不正确(部分已经是)。考虑使用您提供的信息和建议的来源来支持您的回答。
      • @AndreiGheorghiu 据我所知,我测试过的所有(最新)浏览器似乎都没有动态加载这些资源。我也没有看到任何关于 w3c 或 CSSOM 的规范,其中明确指出浏览器必须基于 media 属性动态加载 css 资源。虽然,我知道这可能会在未来发生变化,因此我已经改写了我的答案,听起来更具前瞻性。感谢您的意见。
      • 您可能会发现这些资源很有趣:keith clark's piece on async CSS - 超过 1 岁,taylor hunt's follow up
      • 指向media 的查询&lt;link&gt;s 上得到评估。如果当前不适用,则资源将异步加载,因此是非阻塞的。所以它没有做OP想要的(根本没有加载),但它确实得到了评​​估。这和你说的不一样。期待任何证明我错的事情。
      • 有趣的阅读。感谢您的资源!我不知道这些已被某些浏览器评估并设为非阻塞。
      【解决方案3】:

      这样的东西可以工作

      <link rel="stylesheet" media="screen and (min-device-width: 800px)" href="800.css" />
      <link rel='stylesheet' media='screen and (min-width: 701px) and (max-width: 900px)' href='css/medium.css' />
      

      尝试使用此解决方案:

      1. https://stackoverflow.com/a/8101452/1964336

      2. https://stackoverflow.com/a/19675410/1964336

      3. https://css-tricks.com/resolution-specific-stylesheets/

      更多解释: CSS 语法:链接:https://www.w3.org/TR/css3-mediaqueries/

      <link rel="stylesheet" media="mediatype and|not|only (media feature)" href="mystylesheet.css">
      

      媒体类型可以是打印、屏幕等。

      【讨论】:

      • 您能否解释一下为什么在 OP 的代码中添加 screen and 会使其工作?
      • 因为它是一个 css 语法。 w3schools.com/cssref/css3_pr_mediaquery.asp
      • 好的,在这种情况下解释为什么media="(orientation: portrait)" 不起作用。不还是CSS语法吗?
      • 我猜,根据这个语法&lt;link rel="stylesheet" media="mediatype and|not|only (media feature)" href="mystylesheet.css"&gt;,你缺少only
      • 您的答案是唯一一个我还没有投票的答案。我很想,因为您链接了 w3schools,在我看来,就标准和最佳实践而言,它是一个低质量的信息来源。我建议用更可靠的信息来源代替它,例如 w3c 或 mdn。
      【解决方案4】:

      media 属性中,使用screen and (orientation: portrait) 而不是(orientation: ********)

      <link rel="stylesheet" type="text/css" href="style-p.css" media="screen and (orientation: portrait)" />
      <link rel="stylesheet" type="text/css" href="style-l.css" media="screen and (orientation: landscape)" />
      

      【讨论】:

      • 请注意 code-only 答案在 SO 上是不鼓励的。你应该简单地解释一下原理;为什么这个解决方案有效。如果你不知道它为什么起作用,至少参考信息来源。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-18
      • 2018-01-07
      • 1970-01-01
      • 2012-05-16
      • 2014-07-08
      • 2012-01-24
      • 1970-01-01
      相关资源
      最近更新 更多