本文由99根据Johan Johansson的《How To Make Your Websites Faster On Mobile Devices》所译,整个译文带有咱们本身的理解与思想,若是译得很差或不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://mobile.smashingmagazine.com/2013/04/03/build-fast-loading-mobile-website/,以及做者相关信息javascript
做者:Johan Johanssoncss
译者:99html
最近一项 研究代表,80%的网民对移动端的浏览体验感到失望,同时,当体验提高时,他们会在智能手机上花费更多的时间。前端
这不奇怪,由于64%的智能手机用户但愿网站能够在4秒内加载完毕,但一半的网站花费了二倍以上的时间,达到了9秒。这篇文章会阐述一些可使你的网站在移动端跑得更快的技术。java
让咱们来研究下到底是什么影响了智能手机上的网页加载速度。jquery
最明显的缘由是智能机的网速。最佳状况下,移动端用户使用3g与4g上网。在美国,57%的用户使用3g上网,27%的用户使用4g。在加拿 大,4g用户更少。而在英国,4g仍是新鲜事物。Pcworld的研究代表,在美国,3g平均下载速度为2mbps,4g则为6.2mbps。ofcom 的研究显示,在英国3g的下载速度为2.1mbps。北美和欧洲之外的链接速度通常较慢。1mpbs可换算为122kb每秒,或者0.12mb每秒,所以 以上的数据能够转换以下:css3
若是把上述值乘以移动用户等待时间4秒,这意味着网站对于3g用户来讲最大为1mb,而4g用户为3mb。git
然而下载速度并非瓶颈,网络延迟及智能机的内存与cpu才是瓶颈。即便手机能够在4秒内下载完1mb,页面也要花费更长的时间去加载,由于手机须要接收并解析代码与图片。github
在桌面端,下载文件只占显示网站时间的20%,其他时间花费在解析http请求,获取样式表,脚本文件及图片上。因为移动端的cpu,内存与缓存跟桌面端彻底没法相提并论,这些在手机上会花费更长的时间。web
构建一个快速的网站,就是一个作出艰难决定与砍掉非核心体验的过程。若是某一项需求价值不大,去掉之。这个原则适用于全部开发阶段,尤为是规划和编码时。
若是你想为移动端用户隐藏图片,display:none
与visibility:hidden
是不能阻止文件下载的。测试下面的代码:
<div style="display:none;"> <img src="logo-none.png" /> </div> <div style="visibility:hidden;"> <img src="logo-hidden.png" /> </div>
你能够观察下面的瀑布图,图片容器设置display: none
或visibility: hidden
后仍然会被下载。
替代方案是利用css加载背景图片,以后利用media query媒体查询来经过条件隐藏图片。这个技术最初被Jason grigsby测试过,以后被tim kandlec进一步拓展。亚马逊独立的移动端页面使用了此种技术,根据设备来条件加载特定的图片。
<meta name="viewport" content="width=device-width"> <style> @media (max-width:600px) { .image { display:none; } } @media (min-width:601px) { .image { background-image: url(image1.jpg); } } </style> <div class="image"></div>
你能够看到图片不加载的瀑布图:
若是你已经根据断点来加载分开的样式表,你须要仔细思考这样的作法了。咱们测试了如下的代码:
<link href="extra-small.css" rel="stylesheet" media="screen and (max-width: 390px)" /> <link href="small.css" rel="stylesheet" media="screen and (min-width: 391px) and (max-width: 500px)" /> <link href="medium.css" rel="stylesheet" media="screen and (min-width: 501px) and (max-width: 767px)" /> <link href="large.css" rel="stylesheet" media="screen and (min-width: 768px)" />
你能够看到这四个样式表在竖屏下(portrait mode)都被加载了.
所以不管如何这些样式表都会被加载,你须要把这些文件合并在一个文件里,减小http请求。另外一种方法,你能够经过后端处理,经过判断设备来自动插入样式表。 (这种方式在wordpress.com的响应式网站中使用过)。
另外一种方案可使用内部样式。亚马逊独立的移动产品页面有一个6 KB大小的外部样式表,连同一些内部样式。这只须要经过一个额外的HTTP请求来下载全部的页面样式。亚马逊的桌面版本并非很高效,带有9个外部样式表,总共40 KB。
圆角,阴影,渐变填充等,这些样式不须要使用图片,能够减小http请求,加快加载时间。
Css3能够减小http请求,但增长了处理负荷。咱们建立了一系列的html文件,每一个文件包含一个基本的css3特性。参考下面的图表,你能够发现css3带来的处理时间很小,但不能不考虑。特别注意box-shadow
对处理时间的影响最大。
Data uri方案能够不使用任何额外资源就能够向html及css中插入内容。这个技术能够在web页面中插入任何内容,一般被用于插入图片及web字体文件。这个技术最大的好处是能够减小http请求。
Data uri使用很简单,你能够按照下面的格式,使用base64编码过的数据直接插入html与css中代替图片文件。
data:[MIME-type][;charset=encoding][;base64],[data]
举个例子,下面的小图标就是用data uri建立的:
代码在这:
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAACI0lEQVQoz2P48/bFX1Tw58vn3/dv/rp56dfD238+vocIfl029UOC3dsgS4Y/nz4gq/794sm3VbO+zmr/MqX+S1/l597yb2vn/rpx6VN14od4+3cBRgx/vn9F1vB9/+bPPeVfJlZ/6S793JwDVPcxL/BjQeiHFNf3cbbvgw0Z4JZCwM/Lpz81Zn2qS/1Ul/apOv5jUfiHbP8PSc7vY23fh5m+C9JjALoVzQ8/zx7+0lH4IcvnQ4bXhwzPD8muINXhZu+C9N/56zB8mdr49/cfdH9/fPdj36bPLbkgpYH670KNQaoDdV47aTK8j7H+tmXpX6zg95+f545+7ix656PxzlP5jaf2c2M1hvcRZu8jzb4umfrn6xfs2v78+XFkx9sI2+fass8N1Rje+eu/dtR+YaD0Jj70296df3/+xKrr593bL91tnmnJMbwwVXtuoAbU+kxD5pmu4pvYkK9rVvz58B5Tz7dd257pKDAAlT43giEDFZA2NclXAe5fN60DOgZFx48fb6ICGRCqIchY/bmhKkibivinOdPRLPnQ1cwAUqGrCFQBVIes7ZmmzEtni9+vXiFr+DR9IsMzHfnXIV5vs5OeqUs/05B+rqcIdBhQ81M1yRfW+r+fPUHRMLWfAejir+tWATlf1ix/HR34wlL3ub7Scx2F56Yan6ZPQnPS+6oihlc+Tr/fv4OG+Levv+7d+X700PeDe3/dv4um+tfjhy9drQDa2DKqOJhVKgAAAABJRU5ErkJggg==" />
Wordpress.com的响应式网站使用这个技术插入了图片及字体。波士顿环球报的响应式网站也使用了这个技术,他们的网站在智能手机上,四秒内就加载完毕了。
使用这项技术,今后不用为外部图片及字体文件劳心费神。也须要测试与比较是否值得应用这项技术来代替传统方式。
就像data URIs,可缩放矢量图形(SVG)能够被嵌入到一个页面来减小HTTP请求数。例如,下面的图片是一个内联SVG:
这是代码:
<svg version="1.1" id="drop" x="0px" y="0px" width="17.812px" height="28.664px" viewBox="296.641 381.688 17.812 28.664" enable-background="new 296.641 381.688 17.812 28.664" xml:space="preserve"> <path fill="#EE1C4E" d="M314.428,401.082c-0.443-5.489-5.146-9.522-7 .52-14.186c-0.816-1.597-1.352-5.208-1.352-5.208 s-0.555,3.792-1.388 ,5.425c-2.233,4.371-7.127,8.999-7.507,14.047c-0.36,4.794,4.101,9.191 ,8.896,9.191 C310.49,410.354,314.816,405.941,314.428,401.082z"/> </svg>
SVG文件能够经过一个矢量图形编辑器,如Adobe Illustrator建立。一旦建立,在文本编辑器中打开文件并把其代码拷贝出来(减去任何没必要要的数据)。
上面的代码在HTML文件中会生效,,但不会在样式表中生效。若在一个样式表中嵌入SVG文件,须要先将它转换为一个数据URI。若是这样作,咱们须要从编辑器中(必定要包括元数据)拷贝出,用base64编码,而后使用如下格式嵌入样式表:
data:image/svg+xml[;base64],[data]
这是代码:
background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0i MS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx 1c3RyYXRvciAxNS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOi A2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL 0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8x LjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzE iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Im h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3a WR0aD0iMTcuODEycHgiIGhlaWdodD0iMjguNjY0cHgiIHZpZXdCb3g9IjI5Ni42NDEg MzgxLjY4OCAxNy44MTIgMjguNjY0Ig0KCSBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDI 5Ni42NDEgMzgxLjY4OCAxNy44MTIgMjguNjY0IiB4bWw6c3BhY2U9InByZXNlcnZlIj 4NCjxwYXRoIGZpbGw9IiNFRTFDNEUiIGQ9Ik0zMTQuNDI4LDQwMS4wODJjLTAuNDQzL TUuNDg5LTUuMTQ2LTkuNTIyLTcuNTItMTQuMTg2Yy0wLjgxNi0xLjU5Ny0xLjM1Mi01 LjIwOC0xLjM1Mi01LjIwOA0KCXMtMC41NTUsMy43OTItMS4zODgsNS40MjVjLTIuMjM zLDQuMzcxLTcuMTI3LDguOTk5LTcuNTA3LDE0LjA0N2MtMC4zNiw0Ljc5NCw0LjEwMS w5LjE5MSw4Ljg5Niw5LjE5MQ0KCUMzMTAuNDksNDEwLjM1NCwzMTQuODE2LDQwNS45N DEsMzE0LjQyOCw0MDEuMDgyeiIvPg0KPC9zdmc+DQo=);
Sprites(雪碧图)技术能够把常用的图片合成为一张图片,从而减小http请求。好比当你将四张图片合成到一个sprite中后,http请求从4减小到1.须要显示的图片利用background-position
属性来控制。
字体图标是利用字体文件来包含符号和图表(如Wingdings或Webdings 都是某种图标字体),能够用来代替加载一个图像文件。例如,下面的图标不是一个图像,而是Wingdings字体中的“h”
字符:
Wingdings和Webdings有点过气了,如今有其余更专业的Web字体可用的,能够经过font-face
加载。
单独的Web字体,对于全部图标来说,HTTP请求的数量能够减小到一个。若是Web字体使用数据URI(如上所述)嵌入页面,HTTP请求能够减小到零。这正是WordPress.com使用的技术。这是他们样式表中嵌入的web 字体:
WordPress.com访问全部这些图标,不会有任何额外的HTTP请求,由于图标经过数据URI,以Web字体的方式嵌入到WordPress的样式表中。
同时,字体图标可使用CSS3关键帧动画(这颇有用,好比“加载”图标(小菊花))。 主要的缺点是,字体图标作成的CSS sprites只能是某个纯色。亚马逊的css雪碧图包括彩色图标,所以它不能使用这种技术。
如IcoMoon之类的工具能够很方便的创建一个自定义Web字体。所须要的只是每一个图标的SVG文件。
iframe
每个内联框架(iframe)都会生成一个HTTP请求,这是在iframe内没有另外依赖资源的状况下。这是咱们作一个快速测试,比较一个iframe只含有文本。
包含一个iframe增长了将近0.2s的加载时间。为了保证web站点加载迅速,最好不要使用iframe。
移动先行也适用于前端开发。
编码时以移动用户做为第一考虑,而后为平板电脑和桌面逐步加强,减小没必要要的依赖。另一种方式为桌面端优先,重型组件默认加载,而后为小屏幕隐藏这些组件(称为“优雅降级”)。
下面例子为桌面端优先的编码:
<style> .image { background-image: url(image1.jpg); } @media (max-width:390px) { .image { display: none; } } </style> <div class="image"></div>
在上面的代码中,默认是显示图像,而后在移动设备上经过媒体查询隐藏了图片。
下面的例子为移动端优先的编码:
<style> @media (min-width:391px) { .image { background-image: url(image1.jpg); } } </style> <div class="image"></div>
默认状况下,图片不显示,以后使用媒体查询对更大的屏幕进行渐进加强。
保持你的核心内容在页面上,以后提供到次要内容的连接到次要内容。这将减小HTML的加载负担,同时防止相关的资源被下载。
亚马逊的移动产品页面有通用的产品信息,同时提供连接到“用户评论”、“描述和细节”和“新&
使用提供。
这就减小了三张图片的HTTP请求,且HTML的大小减小45 KB。
亚马逊有一个重定向,来引导游客到单独的移动页面,这带来了0.4秒的延迟。与之相比,戴尔的网站有两个重定向,带来了1.2秒延迟。
响应式图片的思路是让访客图像只下载那些最适合他们的设备的图片,对于智能手机,使用低分辨率图像,能够快速下载和渲染。
亚马逊的独立的移动产品页面使用响应式图像技术,利用媒体查询分配一个特定的背景图像到一个div。这是亚马逊的代码:
<!-- // This meta viewport is inserted for iPhones // --> <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0"> <!-- // This meta viewport is inserted for the Nexus S // --> <meta name="viewport" content="width=device-width"> <style> @media (max-width:390px) { #image-container { max-width: 109px; } .image { background-image: url(image1.jpg); } } @media (max-width:390px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image2.jpg); } } @media (max-width:390px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image3.jpg); } } @media (min-width:391px) and (max-width:500px) { #image-container { max-width: 121px; } .image { background-image: url(image4.jpg); } } @media (min-width:391px) and (max-width:500px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image5.jpg); } } @media (min-width:391px) and (max-width:500px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image6.jpg); } } @media (min-width: 501px) and (max-width: 767px) { #image-container { max-width: 182px; } .image { background-image: url(image5.jpg); } } @media (min-width: 501px) and (max-width: 767px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image7.jpg); } } @media (min-width: 501px) and (max-width: 767px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image8.jpg); } } @media (min-width:768px) { #image-container { max-width: 303px; } .image { background-image: url(image8.jpg); } } @media (min-width:768px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image8.jpg); } } @media (min-width:768px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image8.jpg); } } </style> <div id="image-container"> <div class="image"> <img src="image1.jpg" /> </div> </div>
尽管亚马逊在内部样式中有八个产品图片,在竖屏模式下的iPhone 4或Nexus S只有两个被下载。
《波士顿环球报》的响应式网站,采用了利用不一样的data-fullsrc
来加载图片的响应式图像技术。这是一个html标记,和一个服务器端JavaScript重定向规则的组合:
<img alt="" src="mobile-size.r.jpg" data-fullsrc="desktop-size.jpg" />
src
是手机上使用的图像,确保网站默认为尺寸较小的版本(移动先行),而data-fullsrc
是全尺寸的图像。JavaScript用来检测设备的屏幕大小,以后写入cookie
。对于大屏幕,JavaScript利用data-fullsrc
上的高分辨率图像替换较小的图片。服务器也使用Apache重写规则,来在图像文件的名称中检查.r.
(mobile用的图片带有.r.
),同时显示一个备用GIF,而不会使用较小的移动图像(从而防止手机大小的图像被下载到桌面)。
微软的响应式网站使用的斯科特·杰尔的Picturefill技术:
<div data-picture data-alt="Alternate text here"> <div data-src="image1.png"></div> <div data-src="image2.png" data-media="(min-device-pixel-ratio: 2.0)"></div> <div data-src="image3.png" data-media="(max-width: 539px)"></div> <div data-src="image4.png" data-media="(max-width: 539px) and (min-device-pixel-ratio: 2.0)"></div> <noscript><img src="image1.png" alt="Alternate text here" /></noscript> </div>
注意:上面的代码片断中, data-picture= " "
应该是 data-picture
,没有= " "。(=字符是smashing magazine的所见即所得编辑器自动插入的)。利用这种技术,JavaScript扫描页面的代码,发现包含data-picture
属性的div
。而后根据data-media
属性插入一个新的img
标签。
这些响应式图像技术的主要好处有:
有各类各样的其余技术实现响应式图像。你能够查看这些资源,了解更多的细节:
星巴克的响应式网站在 chrome下禁用javascript后,桌面端良好的网络环境下花费了3.53秒加载完毕,而启用javascript后,花费了4.73秒,增长了 34%。Javascript对加载时间的影响,在移动端较小的内存,cpu及缓存下会表现得更明显。一般,咱们要从新思考javascript的使用, 并保持其在最小尺寸。
一个很好的例子是BBC移 动网站的JavaScript。网站不使用外部JavaScript文件——都是内联。内联脚本仅限于几行,没有显著影响内存,HTML文件和全部内联 JavaScript花费0.78秒加载完毕。就像BBC那样,亚马逊的移动产品页面也没有外部JavaScript文件,而使用最少的内联脚本。 HTML文件和全部内联JavaScript花费0.75秒加载完毕。
(请注意,jQuery不是一个轻量的替代方案,事实上是jquery自己的补充。)这两个网站在iPhone 4下均在4秒内加载完毕。使用一个JavaScript框架前,考虑它是否真的有必要。在某些状况下,使用少许的JavaScript比调用一个框架更有效。
组件对实际加载时间的影响是灾难性的。为了验证这一点,咱们建立了一系列简单的HTML文件,每一个文件包含默认的嵌入代码,一个小部件。你能够看到下面的结果多糟糕。注意,这不是一个完美的测试,由于这些都是在模拟环境中的可控实验,不过结果比较有意思。
在单个页面中,结合他们为一个小部件,结果只包含这个部件的状况下,加载时间长达4秒。
除了优化前端,服务器端技术也能够用来加速加载时间。这些技术都值得考虑,但不会在本文中介绍:
因为移动设备的不可预知性,测试多个设备上的性能是很重要的。这里有一些免费的性能测试工具:
为了知足移动用户的高指望,你须要对网站针对移动设备进行优化,在4秒或更少的时间里加载完毕。最好的方式来达到4秒这个魔术时间,是经过减小JavaScript和优化HTML、CSS和图像,保持智能手机上最少的处理负荷。
使用上面介绍的技术,你就能够本身创建一个符合潮流的移动互联网体验!你有什么要补充的吗?在评论中让咱们知道。
译者手语:整个翻译依照原文线路进行,并在翻译过程略加了我的对技术的理解。若是翻译有不对之处,还烦请同行朋友指点。谢谢!
关于玖玖
某创业团队前端负责人,关注javascript应用与数据可视化。我的博客、新浪微博和Github,欢迎与同窗一块儿共勉。
如需转载烦请注明出处:
如需转载烦请注明出处:
英文原文:http://mobile.smashingmagazine.com/2013/04/03/build-fast-loading-mobile-website/
中文译文:http://www.w3cplus.com/performance/build-fast-loading-mobile-website.html