响应式设计,重点是视网膜显示和桌面。精灵和JS:要牺牲什么?

时间:2012-08-06 00:11:26

标签: html css web-applications retina-display

我会尝试尽可能地加以总结。我正在开发一个需要的Web应用程序:

  • 响应,重点是桌面和iPhone(视网膜显示)
  • 支持所有现代浏览器以及ie8和ie9
  • 服务器效率,意思是:尽可能少的JS和精灵内的许多图标

定位设备宽度/高度与定位像素比率:

对于条件 CSS ,我选择了目标像素比率,而不是为特定平台和设备或使用safari用户代理创建不同的布局。所以我使用@media (-webkit-min-device-pixel-ratio: 2)加上我所有的响应式样式。

现在我正在尝试决定如何处理图片

每张背景的两张图片与一张带背景调整大小的图片

因为我想尽可能少地保持服务器请求,我使用精灵(4或5“模板”)而不是单独的png(SVG讨论是另一回事!)。但IE8(我的用户的很大一部分)不支持Background-size,因此需要像jquery.backgroundSize.js这样的JS回退。

所以:

  

从性能和良好实践的角度来看,精灵的组合,条件背景大小和IE8的JS后备是最佳选择吗?

我没有在这个特定的(现在很常见的)情景中找到其他问题。这不是一个讨论问题,我更感兴趣的是知道是否有关于如何处理这种情况的实际协议:Retina显示,精灵,IE和JS。

2 个答案:

答案 0 :(得分:1)

条件background-size不是首选选项。如果您选择使用该属性为具有“正常”像素比率的客户端使用高分辨率精灵,您最终会图像质量低于预渲染图像的图像质量,客户端扩展图形并传输比所需要的大4倍的精灵的额外计算开销。通过background-size上的依赖,您最终还会人为地限制您的网站与旧版浏览器的兼容性,而IE8 JS后备版也可能会引入内容闪烁(无论您的方案是否可接受)。

我会使用预渲染版本的每像素比率(因此您最终会有两倍的图像文件)。您将能够为用户提供比background-size更高质量的图形。如果您手动构建精灵(而不是使用自动化工具生成它们并附带css),这将引入维护开销,但整体解决方案将更为可取。

  1. 制作css文件的高dpi版本,例如 main-highdpi.css 有条件地将其与适当的媒体查询包含在一起,与<link rel="stylesheet" media="only screen and (-webkit-min-device-pixel-ratio: 2)" type="text/css" href="main-highdpi.css" />

  2. 不同
  3. 创建您依赖的精灵的高分辨率版本并更新css精灵参考。我不认为首选的命名约定已经达成一致(使用@2x后缀资源名称似乎很受欢迎,例如 main.png&amp; main@2x.png

    < / LI>
  4. 利润!

  5. 我会提倡这样一种方法,因为光栅图像的渲染质量较高(与使用background-size缩放相反),缺乏兼容性问题和更快的客户端渲染。缺点是传输更大的图像文件,这是一个可接受的价格,以获得高分辨率图像到客户端设备(并且精灵将被缓存无论如何)。至少你不会最终要求同时复制this article suggests

    请务必牢记个别设备限制(图像大小和尺寸等)。

答案 1 :(得分:0)

我的网站主要是内容和一些非常基本的脚本,所以我选择在页面中嵌入我的所有javascript并避免使用外部脚本(jquery等),因为它们会对页面加载时间产生重大影响。

我还选择将高分辨率图像作为默认图像,如果默认图像是错误的,则有些图像会被下载两次。带宽在移动设备上最为关键,因此高分辨率应该是默认值,而低分辨率将在以后激活。

我也赞成简单而不是在所有情况下选择最佳图像,因为坦率地说,大多数访客甚至都不会注意到差异。对于出现错误的人而言,这不是一场灾难。

最后,我希望它使用新的srcset草案标准,这似乎是这个问题的长期解决方案,即使它还没有实现。

因此,我使用图片代码,src用于高分辨率,srcset代表低分辨率:

<img src="foo.png" srcset="foo-low.png 1x" width="42" height="42">

然后用javascript我处理所有图像标签。我在</body>之前选择了内联javascript而不是domready事件来提高页面加载速度 - 我们希望浏览器尽快知道正确的图像网址,在这种情况下,每毫秒计算一次。

    <script type="text/javascript">
      function swapRetinaImagesOut() {
        // skip anything with a "retina" screen
        if (window.devicePixelRatio > 1)
          return;

        // check if the browser appears to support the "srcset" attribute
        if (typeof(document.createElement('img').srcset) != "undefined")
          return;

        // find all images with an "srcset" property, and swap them
        var imageEls = document.getElementsByTagName('img');
        for (var i = 0; i < imageEls.length; i++) {
          var imageEl = imageEls[i];
          var srcset = imageEl.getAttribute('srcset');
          if (!srcset)
            continue;

          imageEl.src = srcset.match(/^[^ ]+/)[0];
        }
      }

      swapRetinaImagesOut();
    </script>
  </body>
</html>

这很简单但很有效,我期待任何人都可以做出改进。