我有标准的“响应式图像服务”问题,但有一些复杂的曲折。我希望我需要为下面的问题构建自己的解决方案,但是几个月后我想我现在应该把它带到社区来寻求我的方法和入门方面的帮助。我还认为我正在寻找的解决方案将具有相当广泛的吸引力,因此这对整个社区来说可能很有价值。
问题:
我们希望为用户提供图像、嵌入视频等(任何需要大量时间/带宽来加载并且在较低分辨率时需要更少的内容),但会根据元素在页面上实际分配的大小来更改加载的尺寸. 这是适用于其他一些类型资产的基本“响应式图像服务”(尽管由于我们为移动设备提供较低带宽的文件版本,我认为这也属于“自适应设计”)。但是暂时不要担心其他类型的内容,让我们专注于图像。
我们需要为每个特定资产放置、每个屏幕宽度断点确定适当的最大宽度,而不提供此信息作为配置。
我正在创建一个平台,该平台将提供依赖于来自许多不同方的 HTML 模板的页面。可以从页面上的任何位置提供图像,并且页面可以使用它们想要的任何样式系统,因此我们仅通过查看屏幕宽度就无法知道图像的合适尺寸是多少。我们需要在每个支持的大小断点处实际评估放置的最大宽度。当然,这可以在给定设计模板的情况下提前手动完成,但我们假设这对这些第 3 方来说工作量太大。
例如,在 Twitter Bootstrap 3 中,当浏览器宽度 < 768 时,包含在 col-md-8 中的图像最多应为 720px 宽度,但如果它位于 col-sm-8 中,则它应该小于 470px。如果我们完全使用不同的框架,这些显然也会不同。我需要能够考虑 CSS自动执行的所有操作的解决方案,因为我不知道 CSS 会做什么。
在图像请求期间我们无法进行任何处理。我们依赖 CDN(Cloudfront)。他们不会在每个边缘位置实施我们的自定义代码,而且我不希望新德里或柏林的访问者必须在他们知道什么之前为每个大小的资产在全球另一端发送另一个请求最终的网址是。这样就排除了这种基于控制器的解决方案和PHP 自适应图像脚本之类的解决方案。
我们需要这个快速。服务器端有很大的回旋余地,因为使用 Rails 3 和 4 进行缓存非常容易和灵活。但出于性能原因,我们可能不能在每个元素上使用 jQuery.width() 。毕竟,我们提供响应式图像的全部原因是为了减少感知的页面加载时间。但我们确实可以访问 jQuery,如果需要的话,我们可能会一直加载 Modernizr(目前仅包括带有条件 HTML 的低 IE)。
我们对 User-Agent 标头的信任不足以将我们的浏览器宽度建立在它们之上。我喜欢 mobvious 1、2和它的朋友responsive-images背后的想法,但是在这么多不同的设备上有这么多版本的浏览器。建立一个真正可靠的系统来确定浏览器宽度,而不是直接使用 JS 计算它有多复杂?
没有 javascript(以及爬虫)的客户端将需要访问图像。这里最简单的解决方案似乎是在
<noscript>....</noscript>
内部包含图像的规范、最大版本。
解决方案 似乎这样做的唯一方法是:
- 让服务器传递所有可用的大小,然后使用 jQuery 以某种性能高效的方式计算客户端上每个元素的宽度(可能使用 $.css_width() 或某种专门的脚本)。所以服务器会创建:
<span data-respv-img-id="picture_of_unicorns"></span>
<noscript data-respv-img-id="picture_of_unicorns" data-img-720- url="//cdn.example.com/assets/picture_of_unicorns_720x480" data-img-320-url="//cdn.example.com/assets/picture_of_unicorns_320x260" data-img-120-url="//cdn.example.com/assets/picture_of_unicorns_120x80">
<img src="//cdn.example.com/assets/picture_of_unicorns_720x480" alt="Magical unicorns">
</noscript>
如果我们在一个小屏幕上并且只有 120 个适合,JS 会将其变成:
<span data-respv-img-id="picture_of_unicorns">
<img src="//cdn.example.com/assets/picture_of_unicorns_120x80" alt="Magical unicorns">
</span>
- 或者让服务器进行某种预处理,这样它就可以准确地知道每个浏览器宽度上的每个位置都适合什么尺寸的图像,并提供:
<span data-respv-img-id="picture_of_unicorns"></span>
<noscript data-respv-img-id="picture_of_unicorns" data-img-1200- url="//cdn.example.com/assets/picture_of_unicorns_720x480" data-img-1024-url="//cdn.example.com/assets/picture_of_unicorns_320x260" data-img-768-url="//cdn.example.com/assets/picture_of_unicorns_120x80">
<img src="//cdn.example.com/assets/picture_of_unicorns_720x480" alt="Magical unicorns">
</noscript>
我们最终会得到与其他方法相同的结果。但是这一次 jQuery 的工作要容易得多,因为我们将所有的大小调整工作都交给了服务器。但这需要在服务器端加载完整的浏览器堆栈来生成每个请求。缓存没问题,但肯定会带来很多复杂性。
请注意,这两种解决方案都允许基于滚动的图像加载,这是我需要实现的另一个方面,但我们现在不需要讨论。
长话短说:您会推荐哪种方法?你能想出更好的方法吗?