RETINA时代的前端优化


RETINA时代的前端优化

原文链接:http://yukun.im/css/477

一,什么是Retina?

“Retina”“视网膜屏”是苹果为最新的双密度的屏幕起得名字,其他厂商也有类似的屏幕,只是不叫这个名字。最新的iPhone,iPad,MacBook Pro等设备用的就是这类屏幕。

二,Retina屏幕带来了什么问题?

以MacBook Pro with Retina Display[3]为例,工作时显卡渲染出2880×1800个像素,其中每四个像素一组,输出原来屏幕的一个像素显示的大小区域内的图像。这样一来,用户所看到的图标与文字的大小与原来的1440×900分辨率显示屏相同,但精细度是原来的4倍…由四个像素代替原来一个像素。

wikipedia

这样就会造成普通图片在Retina屏幕上显示模糊

Non-Retina display and retina display

三,这个问题会影响哪些地方?

1,Favicon

2,Web Clip

3,图片

4,图标

四,怎样解决这个问题?

将原来的文件增大为原来的4倍(宽高都X2)

五,目前的几种解决方案

5.1,Favicon

默认图标是16×16,Retina屏幕需要32×32像素或者更大的。

favicon on retina display

对于IE6-10,用经典的32×32像素 ico格式图标放到网站根目录;

其他浏览器可以使用更大的比如96×96的png图标;

<link rel="icon" href="path/to/favicon.png">

Favicon 的兼容问题:understand the favicon

5.2,Web Clip

指定几种分辨率的图片即可

<link rel="apple-touch-icon" href="touch-icon-iphone.png" />

<link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png" />

<link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone-retina.png" />

<link rel="apple-touch-icon" sizes="144x144" href="touch-icon-ipad-retina.png" />

documentation

生成几种分辨率图标的解决方案

the state of favicons/

http://msdn.microsoft.com/en-us/library/ie/gg491740%28v=vs.85%29.aspx

5.3, 图片

5.3.1 使用两倍大的图片

<img src="my200x200image.jpg" width="100" height="100">

这样处理最简单,也不用维护两套图片,但是会让所有浏览器都加载大图片,加载速度会受影响,移动网络流量也较大。

5.3.2 Retina屏幕用 Javascript 替换成大图,默认使用普通图片

<img src="low-res.png"

data-src-retina="high-res.png"

alt="">
var isRetina = (window.retina || window.devicePixelRatio > 1);

if(isRetina){
    $('[data-src-retina]').each(function(){
        $(this).attr('src',$(this).attr('data-src-retina'));
    })
}
// 代码用到了jQuery

这样做需要维护两套图片, 普通屏幕和以前一样,加载默认图片;Retina屏幕会先加载普通图片,然后再加载一次大图,这里只考虑了屏幕情况,也是没有考虑移动网络。

 

5.3.3 服务器端方案

网页顶部用脚本取得屏幕情况,保存到cookies

<script>document.cookie='resolution='+Math.max(screen.width,screen.height)+
("devicePixelRatio" in window ? ","+devicePixelRatio : ",1")+'; path=/';</script>

服务器端设置rewrite 规则,判断cookies & 服务器端图片是否存在决定返回普通图片还是@2x图片。

RewriteCond %{REQUEST_URI} ^/assets/images
#RewriteCond %{REQUEST_URI} !^/assets/images/excluded
RewriteCond %{HTTP_COOKIE} resolution=([^;,]+),2
RewriteCond %{REQUEST_URI} !@2x\.(jpe?g|gif|png)$
RewriteCond %{DOCUMENT_ROOT}/$1@2x.$2 -f
RewriteRule ([^.]+)\.(jpe?g|gif|png)$ $1@2x.$2

这种方法前端处理简单,只需要指定图片宽或高就可以了,判断工作全部交给服务器,缺点是也需要维护两套图片,判断了屏幕情况,没有考虑移动网络。

5.3.4 未来的更好方案

最新版的webkit实现了一个新的特性 srcset属性

<img src="low-res.png" srcset="high-res.png 2x">

测试页面,代码只有上面一行

普通屏幕效果

non-retina srcset

rMBP效果

retina srcset
srcset可以指定多个文件地址,浏览器会根据屏幕dpi,网络情况,加载合适的图片来显示,缺点只有一个,目前只有webkit的nightly版本支持。

http://nightly.webkit.org/

以上几种方法对比

 

2@x图片 CSS、JS替换图片 Server rewrite srcset
维护多份图片 N Y Y Y
移动网络 不太友好 不友好 不太友好
浏览器兼容性 ALL ALL ALL 未来版本
实现难度 简单 教简单 后端配合 简单

 

5.4, 图标

5.4.1 sprite图片

放大版的雪碧图设置尺寸为正常版本的大小。要注意每个图标的位置都要一一对应。

retina css sprite

.content a.fav-link {
    background: url(sprite.png) no-repeat 0 -100px;
}

@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min-device-pixel-ratio: 2) {
                  span.location,
                  span.success,
                  a.delete,
                  .content a.fav-link {
                        /* Reference the @2x Sprite */
                        background-image: url([email protected]);
                        /* Translate the @2x sprite's dimensions back to 1x */
                        background-size: 200px 200px;
                  }
}

优点是兼容旧代码,用来支持Retina屏的新图标不会影响旧样式。缺点很明显,要多维护一套图标,还要保证每个图标都对齐(这时有网格对齐的雪碧图优点就突出了),雪碧图一般不会太大,对流量的影响基本可以不考虑。

5.4.2 icon font

 

已经有人总结了完整的流程,

make font-icon

font-icon pro n cons

或者参考  http://www.iconfont.cn/

优点,清晰锐利,可以设置不同颜色,放大后不会失真,兼容性较好。缺点,只能是单色图标。根据同事的实践,ie8中会有锯齿,目前还没有较好的解决方法。

end.