RETINA时代的前端优化
一,什么是Retina?
“Retina”“视网膜屏”是苹果为最新的双密度的屏幕起得名字,其他厂商也有类似的屏幕,只是不叫这个名字。最新的iPhone,iPad,MacBook Pro等设备用的就是这类屏幕。
二,Retina屏幕带来了什么问题?
以MacBook Pro with Retina Display[3]为例,工作时显卡渲染出2880×1800个像素,其中每四个像素一组,输出原来屏幕的一个像素显示的大小区域内的图像。这样一来,用户所看到的图标与文字的大小与原来的1440×900分辨率显示屏相同,但精细度是原来的4倍…由四个像素代替原来一个像素。
这样就会造成普通图片在Retina屏幕上显示模糊
三,这个问题会影响哪些地方?
1,Favicon
2,Web Clip
3,图片
4,图标
四,怎样解决这个问题?
将原来的文件增大为原来的4倍(宽高都X2)
五,目前的几种解决方案
5.1,Favicon
默认图标是16×16,Retina屏幕需要32×32像素或者更大的。
对于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" />
生成几种分辨率图标的解决方案
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">
测试页面,代码只有上面一行
普通屏幕效果
rMBP效果
srcset可以指定多个文件地址,浏览器会根据屏幕dpi,网络情况,加载合适的图片来显示,缺点只有一个,目前只有webkit的nightly版本支持。
以上几种方法对比
2@x图片 | CSS、JS替换图片 | Server rewrite | srcset | |
维护多份图片 | N | Y | Y | Y |
移动网络 | 不太友好 | 不友好 | 不太友好 | 好 |
浏览器兼容性 | ALL | ALL | ALL | 未来版本 |
实现难度 | 简单 | 教简单 | 后端配合 | 简单 |
5.4, 图标
5.4.1 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
已经有人总结了完整的流程,
优点,清晰锐利,可以设置不同颜色,放大后不会失真,兼容性较好。缺点,只能是单色图标。根据同事的实践,ie8中会有锯齿,目前还没有较好的解决方法。
end.