0 Comments

响应式web设计之深挖图像处理技术(1)

发布于:2013-09-25  |   作者:广州网站建设  |   已聚集:人围观

注:这篇文章发表于September 30th, 2011 ,作者是Jason Grigsby

响应式图像Part 1中,我站在一个比较概况的层面,解释了什么是响应式图像,这其中需要解决的问题以及一些共同面临的议题。在这篇文章中,我会对于响应式图像中设计的具体技术做一个更详细的论述,并且来看看这些技术的可用性。如果你还没有读过part 1,也许你会想要先读一下以便了解我在文中用到的一些术语。

当我两个月以前开始做这个工作的时候,我觉得工作的最后我可以说,“这是最有效的三种方法。去下载它们并整合进你的系统吧。”现在看来,这实在是太天真了。

现在我发现的是并没有一个综合的解决方案。相反,我们做了好几个月实验,每个实验都有它的优点与缺点。
广州网站建设,网站建设,广州网页设计,广州网站设计

因为这个原因,我们应该了解一些通用的元素和挑战,这样,对于我们的解决方案中的每个部分,我们就能选择相应最好的技术了。

被放弃的一些方法

动态库标签(Dynamic Base Tag)

很多早期技术都使用Javascript来动态改变库标签。新的库标签将会在路径中加入用于指示需要解析的图像大小的信息。文件加载以后,库标签就会移除。

但是,这种方法会遇到我在part 1中所说的race conditions的问题。

(译者注:关于race conditons,参见http://linux.chinaitlab.com/man/linux/HOWTO/Secure-Programs-HOWTO/avoid-race.html,race condition是由于事件发生的相对时间之间的依赖而引起的异常行为问题。)

我发现Google Chrome会同时下载移动端和桌面端的图片。Scott Jehl发现这个问题是由于内部和外部Javascript不同处理方式间的区别引起的。他对webkit提交了一个bug,并将其标记为“不可修复”的,原因如下:

插入库标签会改变页面上随后的所有的URLs。任何脚本都有可能插入一个库标签来避免双重加载,除非有一个挂起的脚本(a pending script)加载,否则不会加载任何事物。这意味着预加载被禁止了,这就脱离了讨论范围了。

在理论上说,你仍然可以使用内联动态库标签,但是Filament Group主要使用的还是基于cookies的办法,因为这种方法似乎更安全。

暂时的图像(Temporary images)

另外一个早期的技术是让图像的src指向一个暂时的图像,然后让Javascript用一个正确的文件路径来替换这个图像的源。在大多数情况下,这个图像是一个一像素的透明的gif图像,它使用了缓存技术,这样,无论它在页面中被引用多少次,浏览器都只需要请求一次。

这种技术的问题在于一旦Javascript失效,浏览器将永远不会加载图像。

基于Javascript的解决方案

你在哪里存储不同版本图像的路径?

如果图像指向的是‘small.jpg’,那么,对于需要加载大图像的大屏幕,你将‘large.jpg’的信息放在哪里?

URL参数

一种解决方法是将不同版本图像的路径作为url参数放在图像属性中。它最简单的形式如下:
广州网站建设,网站建设,广州网页设计,广州网站设计


  1. <img src=”small.jpg?full=large.jpg”> 

如果你有好几个不同大小的图像,只需要在url中增加一部分值就可以了。这种方法的关键在于将其和一个.htaccess文件绑定。

潜在的CDN,代理,以及缓存问题

使用URL参数的最大缺点在于在内容分发网络以及使用代理(代理在对内容进行缓存的时候不会注意到url参数)的情况下会引起问题。一些缓存算法会忽略任何有url参数的内容,这意味着由于图像不会被缓存,页面会变慢。

另外一些缓存算法只会缓存它们看到的第一种版本的图像。如果使用代理缓存看到图像的第一个人恰好是在移动终端上看到图像的,那么随后使用同样的代理缓存的人访问网站的人看到的都将是适用于移动端大小的图像,不论他们使用什么平台,除非这样的缓存过期了。

这在多大程度上会成为一个问题呢?就此我询问了Steve Souders。他说这足以构成一个问题因此你不能忽略它。这引发了Bryan 和Stephanie Rieger对于缓存和CDNs的一些评论。

因此,我认为我们应该找到一些不需要使用url参数的技术。

这种方法的一些例子:

响应式图像JS主分支(https://github.com/filamentgroup/Responsive-Images)

响应式图像切换(https://github.com/allmarkedup/responsive-images-alt )

响应式图像及能感知上下文的大小改变(http://www.craig-russell.co.uk/responsive-images-and-context-aware-image-sizing/)

使用Doubletake.js的响应式图像(http://www.grahambird.co.uk/lab/doubletake/ )

使用PHP及jQuery的响应式图像(http://www.jamesfairhurst.co.uk/posts/view/responsive_images_with_php_and_jquery/)

使用cookies的响应式图像(http://blog.keithclark.co.uk/responsive-images-using-cookies/ )

感知上下文的响应式图像(https://github.com/ahume/Responsive-Images )

数据属性

文件路径不是放在url参数中,而是放在一个或者更多的数据属性中。例如:


  1. <img src=”small.r.jpg” data-fullsrc=”large.jpg”> 

哪一个元素要加入数据属性以及要加入多少都是依赖于具体技术。

循环检查每一个图像

我所知道的这种技术的唯一的缺点是需要循环检查每一个图像的数据属性,然后根据屏幕大小修改源属性。这对于台式机浏览器来说可能不是个大问题,因为在台式机中是循环被大量使用的地方。

这种方法的一些例子:

响应式图像基于数据属性的JS分支(https://github.com/filamentgroup/Responsive-Images/tree/data-attribute-based )

测试响应式图像(http://www.monoliitti.com/images/ )

使用noscript标记创建响应式图像(http://www.headlondon.com/our-thoughts/technology/posts/creating-responsive-images-using-the-noscript-tag)

约定的文件存储结构

在这种方法中,文件路径不是包含在HTML文件中,而是假定图像在服务器上是一种约定俗成的方式放置的。例如,所有的小图像可能都是在/images/sml/文件夹中,而大图像都是在/images/lrg/图像中。

如果是这样的话,html页面就不用为两种图像都提供路径。它只需要提供图像的文件名(例如,boat.jpg),然后让Javascript来修改图像源以便与屏幕大小适应(例如,如果是台式机,图片源就是/images/lrg/boat.jpg for desktop)。

这种方法的一些例子:

响应式图像切换(https://github.com/allmarkedup/responsive-images-alt )

自适应的图像(http://adaptive-images.com/ )

动态文件名

我在part 1中提到我们或许需要任意图像尺寸。这个问题的一些解决方案是基于一种假设,即你可以通过url传递你所想要的大小,然后得到这样大小的图像。

因为图像大小调整是即时完成的,因此没有必要在Html文件中存储不同文件路径。Javascript会修改文件名,将类似于‘boat.jpg’的名字改成‘boat-480×200.jpg’。同时,也不存在缓存或者CDNs的问题,因为任何一个图像都是独特的。

有些图像确实不能被调整大小

这种方法对于人工选择不同大小的图像并没有提供很好的解决方案。它假设大小调整后的图像能在任何情况下工作,这显然是不能的。

这种方法的一些例子:

响应式图像JS中有意义的一些分支(https://github.com/filamentgroup/Responsive-Images/tree/meaningful-base)

响应式图像及tinySrc(http://blog.trasatti.it/2011/05/responsive-images-and-tinysrc.html )

.htaccess的角色(或类似的重写规则)

这种解决方案是基于服务器重写规则的。例子通常是使用Apache 的.htaccess文件写的,单它们可能是任何类型的重写规则。

我们来看看一个.htaccess文件的片段(来源于Responsive Images JS cookie-based branch),来看重写规则是如何使用的:

RewriteEngine On #large cookie, large image RewriteCond %{HTTP_COOKIE} rwd-screensize=large RewriteCond %{QUERY_STRING} large=([^&]+) RewriteRule .* %1 [L]

for the url contains a value for large. This .htaccess file is looking for something like:第一条开启了重写规则。接下来是一对条件(RewriteCond)。第一个条件检查是否有一个名为rwd-screensize值为large的cookie。第二个条件检查url的查询语句是否包含一个针对大图像的值。这个.htaccess文件试图找到一些:


  1. <img src=”small.jpg?largelarge=large.jpg”> 

如果两个条件都满足——cookie被设置为针对大图像且查询语句中有针对大图像的值——则重写规则会发送在查询语句中指定的文件(在上面的例子中,是large.jpg)。

rwd-screensize的cookie值是通过Javascript测试屏幕大小以后进行设置的。

你如何避免浏览器下载好几个图像?

排除了一些基本的方式,我们现在开始谈论最棘手的部分。正如第1部分所提到的,在浏览器开始下载图像之前拦截浏览器,以便可以评估并改变这些图像的来源是棘手的问题,并可能导致race conditions。

现在,动态库标签已被排除,还剩下两种主要技术。

设置cookie

这是Filament Group为Boston Globe提出的解决方法。在文件头部加入了Javascript,这样就能很快做出评估了。

在它决定了屏幕大小以后,它就会设置一个cookie。每个随后的图像请求都会包含这个cookie,服务器端可以使用cookie来决定发送给用户的最好图像。

可能存在的问题

如果浏览器不支持cookie或者用户禁用了它们,插入到文件头部的Javascript就不起作用了。

另外,Yoav Weiss做过一些测试,证明IE9在这种情况下仍然会重复下载文件,Firefox在脚本处于外部的时候也会重复下载文件。这意味着cookies可能带来race condition的问题,而正是这个问题让我们放弃了动态库标签方法。

这种方法的一些例子:

响应式图像的cookie分支(https://github.com/filamentgroup/Responsive-Images/tree/cookie-driven)

使用cookies的响应式图像(http://blog.keithclark.co.uk/responsive-images-using-cookies/)

响应式图像切换(https://github.com/allmarkedup/responsive-images-alt )

飞机