推荐:如何加速网页的打开速度 - 优设网 - UISDC

推荐:如何加速网页的打开速度

2013/02/21 10040评论区

speed1

对于加载精简来说,最大的好处莫过于对页面的加速。加速有两点:第一是由于资源加载量减少,对于页面首屏加载速度的提升;第二是某些加载精简的方法,会在一定程度上加快页面的渲染速度。同时,由于加载量的减少,剩下了一些带宽,从而减少了带宽费用。
当然,事情都有两面的地方。加载精简会在一定程度上影响页面的SEO;部分方法也会造成一些额外的脚本开销。
寻找合适你的方法很重要,毕竟每个网站性质、用处、节点都可能不同。比如项目初期,可能宣传和扩散知名度方面重要些,这时候建议不要大量使用动态生成内容的方式,影响SEO。

第1章 存储资源

1.1 离线存储

1.1.1 为了移动

由于浏览器支持情况不同,离线存储在PC端没有大量的使用,反而在移动端的支持情况越来越好,如今Android、iOS都能使用离线存储,所以离线存储广泛的使用于离线APP应用。
对于离线存储,最重要的便是manifest文件。我们将需要缓存的文件列入cache段,将不需要缓存的内容列入network段即可。

speed2

图2-1 manifest文件示例
当浏览器加载页面时,发现manifest文件后,会检查它的内容是不是有修改,如果是,重新下载cache段的文件并缓存;如果不是,则跳过。

speed3

图2-2 更新离线缓存

需要注意的是,当我们使用离线存储时,浏览器会强行只读离线缓存的文件。我们需要将页面使用到的所有的资源都列入manifest文件中,不论是在cache段,还是network段。否则浏览器将报错,说找不到文件。

speed4

图2-3 未将所有文件列入的加载报错情况

1.1.2 更新

对离线存储的资源更新,需要修改manifest文件的内容。当然,我们一般不会随意修改文件名已达到修改manifest文件内容的目的。一般的做法是,在文件内新增一行注释,注释中写明目前的版本号,以后每次需要更新的时候,修改版本号就行了。

speed5

图2-4 第二行即为注释的版本信息

另外,我们可能需要功能更加强大的离线存储缓存更新的机制。试想一个新闻类的APP,我们需要在手机离线时读取本地存储的数据,当APP发现用户联网后,将读取在线的内容,更新本地的数据和页面信息。
对于图2-5,我们使用HTML5新提供的online时间在页面加载的时候判断手机是否在线。监听window的online和offline时间,可以判断手机是不是已经联网。一旦检测到手机联网,我们就可以调用applicationCache对象的update方法,去检测manifest文件是否有更新,如果有,下载新的版本。当updateready时,使用swapCache方法刷新缓存。

当然swapCache不能刷新页面的内容,只是把离线存储的文件更新成我们下载的新内容,我们还需要再使用JS替换页面的内容。

图2-5 离线存储进阶应用

1.1.3 残缺美

在使用离线存储的时候,总有些感到不是很爽的地方,列出来吐吐槽。
首先是两个更新的问题。我们知道,修改manifest文件后,浏览器会重新下载文件,而且是全部重新下载。这其实很蛋疼,有时候我们只需要更新其中一个文件,有点儿殃及池鱼的感觉。另外,在更新manifest文件后,我们需要刷新两次页面才能将最终的新内容呈现在页面上。

然后,如果我有很多文件要存储,需要把文件一个一个列入cache段里,就算使用程序生成,出来的manifest文件也有一定的体积。对于一个需要缓存300个文件的页面,使用相对路径,生成的manifest文件也有4K。在碰上更新的话,下载量有点儿大。

图2-6 APP有200多个小图标需要缓存

最后,对于同一个页面的带参URL路径,离线存储会当成不同的新文件进行缓存。如果您有100个不同的参数需要穿,而用户竟然访问过这100个文件,那就……

speed6

图2-7 如果您有100个不同的传参

1.2 本地存储

1.2.1 本地存储的方法

userData是IE提供的一个本地存储方法,他将需要存储的内容放置在本地的一个XML文件中,并在页面的一个元素中设置一个调用的锚点。具体使用方法为:使用getElementById获取页面内的一个元素,使用addBehavior(“#default#userData”)对其添加本地存储的行为;使用setAttribute将需要存储的内容对其进行赋值,并用save(“XXX”)方法将内容存储在名为XXX的XML文件中;使用load(“XXX”)方法加载本地的XXX.xml文件,并用getAttribute获取已经存储的内容。

图2-8 IE的本地存储数据

关于HTML5本地存储localStorage的详细方法,请参见我的翻译文章《网络应用程序本地存储的前世今生》。

图2-9 Chrome的本地存储数据

对于IE浏览器,使用IE提供的userData方法;对于支持HTML5的浏览器(Firefox、Chrome、Safari、Opera等),使用localStorage提供的方法;对于其他浏览器使用常规方法加载内容。

speed7

图2-10 判断流程

1.2.2 资源处理

对于本地存储,我们可以使用来存储数据,或者能转为数据形式的文件。例如一些SEO要求不高的文字,链接等等。

speed8

图2-11 数据存储

对于图片、CSS、JS等文件,我们也可以转为文本来存储在本地。这种方式大量应用于移动端。例如《掌上英雄联盟》APP的图片大部分都转化为base64编码存储在本地(不用离线存储的原因前面提及了)。Google和Bing的移动版,也将CSS和JS拆分后本地存储了。

speed9

图2-12 脚本的本地存储

speed10

图2-13 图片转base64编码后的本地存储

另外,对于本地存储更新,我的做法是:先判断本地是否存在已存储的内容,如果没有数据或者版本已过期(所谓版本是我设置的一个变量,当修改这个变量时即为版本过期),加载相应的JS数据,通过一个函数将数据处理为需要的格式,然后存储在本地;如果有且版本没过期,直接从本地获取数据。接着将数据通过函数进行进一步的处理,插入相对应的结构中。

speed11

图2-14 本地数据版本判断

第2章 按需加载

2.1 滚动加载

2.1.1 滚动加载的方法

其实这是很多大型网站都使用了的方法,比如淘宝、拍拍等等。对于不同显示器分辨率不同,所以第一屏高度不一样,节省的加载量所浮动。
首先,记录所有需要滚动加载对象的纵坐标值到一个数组。然后使用JS的监听方法(IE是attachEvent,其他浏览器是addEventListener),监听页面的scroll事件。一旦页面滚动,就会执行一个编写的函数,来判断对象是否处于浏览器的当前一屏内,如果是,将加载对象,如果不是,继续监听。当页面内的所有对象都被加载后,取消监听。

speed12

图3-1 执行流程

对于图片,滚动页面后,我们可以看到如图3-2的效果。

图3-2 图片滚动加载过程

2.1.2 板块滚动加载

其实把每个板块按照上面说的那种方式,像图片一样,滚动加载就可以实现这种效果,类似于bigPipe+Lazyload。
我们将页面拆分为框架、板块、板块内容,甚至可以细分到板块样式、板块脚本。当页面滚动完成时,判断处于当前屏的板块,动态并行加载板块内容。这种方式可以大大减少页面的加载量,但会影响SEO。

图3-3 板块滚动加载方式

2.2 点击加载

2.2.1 形式

点击后动态加载有很多形式,这是我们平时使用最多的方式。诸如页卡、翻页、展开、下拉、切屏等等都会使用到。以往的我们可能直接在页面写入内容,或者使用include载入,并将看不到的内容隐藏掉。但如果用户并没有点击切换,那么直接加载这些内容就产生多余的加载量。

图3-4 触发加载页卡内容

speed13

图3-5 翻页触发动态加载

2.2.2 触发加载

一般来说,动态填充数据的前期判断有两种形式。
一种是使用条件语句,判断内容区域是否有内容,如果没有,填充内容。这种方式最容易想到,但每次触发的时候都会判断一次。
另外一种是监听的方式。我们监听触发的对象是否被点击,如果点击,就像目标对象填充内容,然后取消这个监听。

图3-6 判断的两种方式

很显然,第二种方式只需执行一次,测试结果也表明这种方式是最快的。

2.2.3 数据插入方式

我们的新闻系统在生成新闻列表的时候,会根据我们的模板同时生成html页面、xml文件(我们很少使用)、json文件,在选择将列表插入页面的时候,我们有两种方式。
一种是动态加载json文件,用JS生成内容,插入页面;另一种是使用XHR加载html文件,使用responseText获取内容,插入页面。

speed14

图3-7 html文件

图3-8 json文件

其实,使用第二种方法有明显的好处。第一是,html文件体积比json文件小,加载量减少;第二是直接使用html文件,减少了JS动态生成结构的开销。

2.3 延时加载

对于一组有加载时间间隔的资源,我们其实可以对其做加载延时,按照其前后出现的顺序,在时间间隔后即时加载下一个资源。例如轮播广告就很适合这么做。

speed15

图3-9 轮播广告

2.3.1 轮播广告

以往轮播广告的加载模式是一次性全部加载,虽然采用延迟加载,但用户可能不会浏览到所有的轮播广告。当用户在首页只停留5秒时(例如轮播广告设置的是5秒切换一次),第二张广告图片以后的图片加载就没有必要了。

图3-10 轮播广告加载的请求瀑布图

其实我们可以这样,第一次加载第一张广告图片,当5秒后,判断第二张图片是否加载过,如果没有,加载第二张图片,以此类推。判断的方式很简单,我们只要在初期生成轮播广告结构的时候,不设置img标签的src属性,然后加载时判断这张图片是否有src属性,如果没有,加载图片并设置这个属性。

图3-11 判断方式

这样,如果用户在首页停留时长只有14秒,那么就节省了第4、5张广告图片的下载量,大约有100K左右。

图3-12 优化后的请求瀑布图

 

第3章 其他方式

3.1 文件压缩

3.1.1 代码

老生常谈的方法。我们可以将代码里多余的空格,回车,无用标签删除,替换名字较长的变量名等等方式减少脚本文件大小。

speed16

图4-1 脚本压缩对比

3.1.2 多媒体

对于图片,不同格式,不同压缩率都会造成图片大小的千差万别。选择一个合适并且图片质量可以接受的压缩方式,可以节省很大一笔加载量。

speed17

图4-2 图片压缩对比

对于视频、音频、Flash来说,也都一样,码率、格式等等方面都会对大小造成影响。

speed18

图4-3 视频压缩对比

3.2 CSS 3

CSS 3是一个不算太新,但由于我朝浏览器限制而得不到大范围应用的技术。其实我们可以在一些效果表现不是很重要的页面使用CSS 3来针对浏览器做一些差异化效果,已达到减少加载量的目的。

3.2.1 替换图片

对于移动端,或者一些PC页面,我们可以用CSS 3来替换一些图片效果,比如渐变、阴影、圆角等等。

图4-4 绿色按钮

例如图4-4中的绿色按钮,使用CSS 3渐变和图片所造成的加载量差距很大,在能使用CSS 3的时候,尽量不要使用图片。

speed19

图4-5 CSS 3和图片的大小对比

3.2.2 替换JS动画

一些对象移动、宽高变换等效果,其实可以使用CSS 3动画来实现。例如使用CSS 3和JS,来实现一个对象左右切换的效果,需要的代码量如图4-6所示。我们可以看到,CSS 3的代码量极少,而且执行过程中没有JS那些复杂的运算。

speed20

图4-6 CSS 3和JS的代码量对比

3.3 服务器

3.3.1 GZIP

雅虎13条里的内容。其压缩比例很大,大部分网站都使用了。

图4-7 gzip效果

3.3.2 缓存

设置Expires、Cache-Control以减少页面加载量,使浏览器从本地读取缓存。

Expires和Cache-Control
max-age均用于检测文件是否过期,如果没有,浏览器读取本地缓存。Expires是HTTP1.0的内容,需要返回一个304 Not Modified,并且过期时间是GMT时间,一旦客户端日期不准确,可能导致失效。Cache-Control是HTTP1.1的内容,使用文件自身的age值来做和请求时间对比,相对稳定。

speed21

图4-8 304 Not Modified

3.3.3 优图

优图是公司开发的,用于图片无损压缩的系统。目前互娱已经接入,在图片上传到服务器时,自动进行无损压缩,加载量减少的效果非常明显。

speed22

图4-9 优图

 

第4章 三个话题

4.1 对比

在以前一次分享文档中,有同学提问为啥要抛开浏览器与服务器的缓存机制,自己实现一套本地存储机制,有没有什么特别的优势。其实相对与传统缓存来说,本地存储的好处有4点。

一是,对于存储需要处理的数据来说,本地存储可以在第一次加载的时候就将处理的数据存在本地,而传统缓存策略需要每次加载的时候都处理一次数据。
二是,本地存储相对稳定,有独立的存储空间,一般不会向服务器发送请求,而传统缓存时常会丢失。
三是,相对于传统缓存策略,本地存储的读取速度要更快些。当然,也有例外,Chrome的本地存储读取速度要慢于缓存文件的加载。
四是,对于iOS设备,Safari在重启后(包含本身的重启,或者设备的重启),缓存会被清空,而本地存储和离线存储不会。

4.2 SEO

4.2.1 Landing Page

对于互娱这边的游戏,客户端会有一个Landing Page,上面包含了最新的新闻,活动等等信息,玩家每次启动客户端都会看到这个页面。

根据监控,Landing Page平均每天给官网带来250w左右的PV,而官网平均每日PV大约1000多万。这个量应该完全填补了SEO的损失。而且游戏官网的用处一般仅限于给玩家提供游戏的功能服务、新闻、活动信息等等,玩家查询游戏攻略、资料一般会去媒体站,而不是游戏官网。

图5-1 《英雄联盟》的Landing Page

4.2.2 内页链接

在某些内容需要动态加载的时候,我们可以写一个到内页的链接,让搜索引擎爬虫顺着这个链接到内页去记录信息。

图5-2 到内页的链接

例如页卡中的新闻列表需要动态填充,如果不做处理,爬虫可能无法获取这些列表中的新闻链接。我们可以像图5-2的那两种方式,写一个到列表页的链接,这样爬虫就可以顺着这个链接到列表页去抓取信息。

4.3 效果

4.3.1 健康度

健康度是我们以前接的加载时间检测系统,最近我们换用了OZ系统。使用了以上方法的网站,在3秒健康度上,有了很大的提升。

speed23

图5-3 3秒健康度

4.3.2 请求减少

采用以上方式减少加载量,虽然会造成整个网页的全部请求量有少许增加,但因为是按需加载,所以可以大大减少首屏请求量。

speed24

图5-4 首屏请求量

图5-5 整页请求量

4.3.3 带宽消耗

在我们接入优图后,图片服务器的带宽消耗大大减少。在图片压缩一半后,我们的带宽消耗减少了4G。

speedold

图5-6 图片压缩一半后服务器带宽消耗趋势图

由于公司系统只能针对服务器做带宽消耗监控,所以我们看不到做文件存储和按需加载后的带宽减少情况,但我们可以大概算算。如果一个游戏官网全部页面平均每天有PV1500w,用户平均每次加载页面节省10KB,假设第1天正常加载,后29天全部读缓存,每月可以节省带宽488MB。对于有几十款游戏产品的我们来说,这是一个很可观的量。

 

结束语

正如开篇所说的那样,介绍的这些方法,有部分会伤害SEO,增加脚本开销。所以大家在使用的时候需要进行一个合理的选择。

例如对于一个新产品,SEO相对更加重要些,这个时候可以适当选用一些减少加载量的方法;当产品成熟,有大量用户的时候,可以考虑进行更加深入的加载量优化。

希望此文档能帮助到今后做网站加载量优化的同学。

 

原文:http://tgideas.qq.com/
作者:DG

优设大课堂

非特殊说明,本文版权归原作者所有,转载请注明出处
本文地址:https://www.uisdc.com/page-loading-speed

发表评论 加载中....

评论加载中....

uisdc

评论区都快饿瘪了,看看我期盼的小眼神...

版式设计 交互设计师 界面设计 设计师干货 排版布局 职场 优设专访 优设大课堂 设计达人 配色 视觉设计 web前端开发 素材下载 设计流程 AI教程 设计理论 神器下载 字体下载 设计师专访 psd下载 平面设计 设计趋势 海报设计 用户体验设计 设计规范 动效设计 logo设计 图标设计 产品设计 ICON 神器推荐 App设计 字体设计 职场规划 酷站推荐 交互设计 ui设计 优秀网页设计 设计师职场 ps技巧 酷站 用户体验 PS教程 网页设计 经验分享

您还没有登录

优设启用更安全省心的 微信扫码登录

微信扫码

300万设计师聚集地!优设网是极具人气的设计师平台
2012年成立至今,一直专注于设计师的学习成长交流

把好文章收藏到微信

打开微信,扫码分享
学设计 优设网 在这里