网站加载量优化:网页加载性能优化详解(2)
1.2.2 资源处理
对于本地存储,我们可以使用来存储数据,或者能转为数据形式的文件。例如一些SEO要求不高的文字,链接等等。
图2-11 数据存储
对于图片、CSS、JS等文件,我们也可以转为文本来存储在本地。这种方式大量应用于移动端。例如《掌上英雄联盟》APP的图片大部分都转化为base64编码存储在本地(不用离线存储的原因前面提及了)。Google和Bing的移动版,也将CSS和JS拆分后本地存储了。
图2-12 脚本的本地存储
图2-13 图片转base64编码后的本地存储
另外,对于本地存储更新,我的做法是:先判断本地是否存在已存储的内容,如果没有数据或者版本已过期(所谓版本是我设置的一个变量,当修改这个变量时即为版本过期),加载相应的JS数据,通过一个函数将数据处理为需要的格式,然后存储在本地;如果有且版本没过期,直接从本地获取数据。接着将数据通过函数进行进一步的处理,插入相对应的结构中。
图2-14 本地数据版本判断
第2章 按需加载
2.1 滚动加载
2.1.1 滚动加载的方法
其实这是很多大型网站都使用了的方法,比如淘宝、拍拍等等。对于不同显示器分辨率不同,所以第一屏高度不一样,节省的加载量所浮动。
首先,记录所有需要滚动加载对象的纵坐标值到一个数组。然后使用JS的监听方法(IE是attachEvent,其他浏览器是addEventListener),监听页面的scroll事件。一旦页面滚动,就会执行一个编写的函数,来判断对象是否处于浏览器的当前一屏内,如果是,将加载对象,如果不是,继续监听。当页面内的所有对象都被加载后,取消监听。
图3-1 执行流程
对于图片,滚动页面后,我们可以看到如图3-2的效果。
图3-2 图片滚动加载过程
2.1.2 板块滚动加载
其实把每个板块按照上面说的那种方式,像图片一样,滚动加载就可以实现这种效果,类似于bigPipe+Lazyload。
我们将页面拆分为框架、板块、板块内容,甚至可以细分到板块样式、板块脚本。当页面滚动完成时,判断处于当前屏的板块,动态并行加载板块内容。这种方式可以大大减少页面的加载量,但会影响SEO。
图3-3 板块滚动加载方式
2.2 点击加载
2.2.1 形式
点击后动态加载有很多形式,这是我们平时使用最多的方式。诸如页卡、翻页、展开、下拉、切屏等等都会使用到。以往的我们可能直接在页面写入内容,或者使用include载入,并将看不到的内容隐藏掉。但如果用户并没有点击切换,那么直接加载这些内容就产生多余的加载量。
图3-4 触发加载页卡内容
图3-5 翻页触发动态加载
2.2.2 触发加载
一般来说,动态填充数据的前期判断有两种形式。
一种是使用条件语句,判断内容区域是否有内容,如果没有,填充内容。这种方式最容易想到,但每次触发的时候都会判断一次。
另外一种是监听的方式。我们监听触发的对象是否被点击,如果点击,就像目标对象填充内容,然后取消这个监听。
图3-6 判断的两种方式
很显然,第二种方式只需执行一次,测试结果也表明这种方式是最快的。
2.2.3 数据插入方式
我们的新闻系统在生成新闻列表的时候,会根据我们的模板同时生成html页面、xml文件(我们很少使用)、json文件,在选择将列表插入页面的时候,我们有两种方式。
一种是动态加载json文件,用JS生成内容,插入页面;另一种是使用XHR加载html文件,使用responseText获取内容,插入页面。
图3-7 html文件
图3-8 json文件
其实,使用第二种方法有明显的好处。第一是,html文件体积比json文件小,加载量减少;第二是直接使用html文件,减少了JS动态生成结构的开销。
2.3 延时加载
对于一组有加载时间间隔的资源,我们其实可以对其做加载延时,按照其前后出现的顺序,在时间间隔后即时加载下一个资源。例如轮播广告就很适合这么做。
图3-9 轮播广告
2.3.1 轮播广告
以往轮播广告的加载模式是一次性全部加载,虽然采用延迟加载,但用户可能不会浏览到所有的轮播广告。当用户在首页只停留5秒时(例如轮播广告设置的是5秒切换一次),第二张广告图片以后的图片加载就没有必要了。
图3-10 轮播广告加载的请求瀑布图
其实我们可以这样,第一次加载第一张广告图片,当5秒后,判断第二张图片是否加载过,如果没有,加载第二张图片,以此类推。判断的方式很简单,我们只要在初期生成轮播广告结构的时候,不设置img标签的src属性,然后加载时判断这张图片是否有src属性,如果没有,加载图片并设置这个属性。
图3-11 判断方式
这样,如果用户在首页停留时长只有14秒,那么就节省了第4、5张广告图片的下载量,大约有100K左右。
图3-12 优化后的请求瀑布图