WEB网站页面提速(前端向)

一. 减少对服务器的文件请求

常规的HTTP请求属于“请求”-“应答”-“断开”形式的短连接,每一个独立的资源我们都会向服务器发去一份get请求,再等服务端将我们需要的文件传回来。每一次资源的请求都实实在在地耗费了一次“连接-等待-接收”的时间(当然将http请求设为keep-alive长连接状态可以减少“连接”的次数和时间),如果我们能有效减少对服务器文件的请求次数,便意味着我们可以从这块省下一些页面等待时间,也可以顺便减少服务器的负担。

对于这个解决方案,我们可以这么做:

1. 使用css sprite技术合并多个图片为单个图片文件,实际使用时通过background-position来定位背景位置(相信大家第一个想到的也是这个吧);

2. 合并多个css样式文件为单个样式文件,合并多个脚本为单个脚本,再在页面中引用合并后的样式/脚本文件。对于这个你可以使用r.js来帮忙(看我这篇文章),但我个人倒是不怎么推荐这个方法,因为合并了文件之后,多个页面之间公共部分的样式/脚本文件就无法缓存到客户端了;

3. 使用base64编码来展示图片。就如图github 404页面那样:

你可以使用这个工具来帮你把图片转换为base64编码的文件流,但常规只推荐你把这种方式使用在用户重复访问量较少的页面,因为它们虽然无须从服务端get一遍,但也无法缓存在客户端,导致用户每次访问页面都要重新渲染一次。而且冗长的文件流代码会占用你页面很大的代码空间,维护起页面来估计也会挺心塞;

4. 将小块的css、js代码段直接写在页面上,而非在页面引入独立的样式/脚本文件。相信有的朋友看惯了“保持结构 (标记)、表现 (样式)、行为 (脚本)三者分离”的规范,对此观点可能有些意见。只能说规范不是教条,适合自己的才是硬道理。直接把小段的、复用率低的样式/脚本直接写于页面上带来的利还是大于弊的(弊可能也就是增大了页面代码量、不那么好维护了点)。反观所有主流门户网站的页面源文件,基本没有一个是把样式/脚本都全部作为外部文件引入的(无论他们是否从减少服务器请求这点出发,事实都是这样);

5. 利用http-equiv="expires"元标签,设定一个未来的某时间点作为页面文件过期时间,用户在过期时间之前所获取到的页面文件都仅从缓存中去取。不过这个办法太死板(有时候即使服务端及时把过期时间更改为已结束时间,客户端可能都不会按照新更改的规则去服务端获取新文件资源),常规是不推荐使用的。

二. 减少文件大小

文件太大(特别是图片)导致加载时间较长,往往都是影响页面加载体验的头号大敌,那么尽可能减少请求文件的大小便是相当重要的事情了,我们可以做的事情有:

1. 压缩样式/脚本文件,就此你可以使用gulp或者grunt来实现这点,它们均能很好地减少css/js文件的大小(对于js还能起到混淆变量、函数名的作用);

2. 针对性选择图片格式,在无透明背景需求下,对于颜色较单一、无色彩渐变的图片仅使用gif格式,对于jpg图片也可按照其清晰度要求,在导出jpg的时候选择对应的“品质”进行优化:

如果你喜欢尝鲜,可以学淘宝那样使用webp图片格式,它能很好地优化同画质下的文件大小:

如果你对webp感兴趣,可以查阅这里

3. 使用Font Awesome来替代页面上的图标,其原理是使用@font-face让用户下载一个非常小的UI字体包,把页面上用到的图标以字符的形式来显示,从而减少了图片需求和图标文件大小。

三. 适度使用CDN

使用CDN有几个好处:如果用户在其它站点下载过这个CDN资源,那么来我们站点仅仅从缓存获取即可;减少了对自己站点服务器的文件请求(外部CDN的情况下),减少服务器负担;多个域会使浏览器允许异步下载资源的最大数量增多,比如一个站点只从一个域来请求资源,那么FireFox只允许同时刻最多异步下载2个文件,但如果使用了外部CDN来引入资源,那么FF允许在同时异步下载本域中的两个资源外,还额外允许同时异步下载另一个域(CDN)下的2个资源。

但是使用CDN有一个很大的问题——增加了dns解析的开销,如果一个页面同时引入了多个CDN的资源,可能会因为dns解析而陷入较多的等待时间,导致得不偿失。

对于这个问题,常规是建议一个站点下只使用同一个可靠、快速的CDN来引入各种所需资源即可,也就是说,建议一个页面从2个不同的域(比如站点域和CDN域)下来请求资源是最佳的选择(据说这个结论是雅虎前端工程师提出的,这里有一篇很不错的文章)。

四. 延迟请求、异步加载脚本

在各主流浏览器下,常规情况,我们的脚本文件跟随其它资源文件一样都是异步下载的,但这里存在一个问题——比如FireFox下载好脚本后的一小段时间内会有“执行阻塞”的情况发生,也就是说浏览器下载好脚本后执行它的这段时间里,浏览器的其它行为被阻塞,导致页面上的其它资源都是无法被请求和下载的:

如果你页面里存在js代码执行时间过长的情况,那么用户就会明显感觉到页面的延迟。解决这个问题有一个简单的方法——将脚本请求标签放置到</body>结束标签前,使得页面上的脚本成为最后被请求的资源,自然也不会阻塞其它页面资源的请求事件了。

另外,虽然上面提到“我们的脚本文件跟随其它资源文件一样都是异步下载的”,但异步下载不代表异步执行,为了严格保证脚本逻辑顺序和依赖关系的正确性,浏览器会按照脚本被请求的先后顺序来执行脚本。那么问题就来了——如果页面上的脚本依赖关系并不大,甚至没有任何相互间的依赖,那么浏览器的这套规则就仅仅增加了页面请求阻塞时间而已(就像你花大钱买了一笔保险,但被保险期间你平安无事啥都没发生。。。嗯,这个比喻有点反人类。。。)。

解决这个问题的办法无非就是让脚本无阻塞地异步执行,比如给script标签加上defer和async属性或者动态注入脚本(可以参考这里),但这些都不是良好的解决方案,要么存在兼容性问题,要么太麻烦还无法处理依赖。

个人是推荐使用 requireJS(AMD规范) 或 seaJS(CMD规范) 来异步加载脚本并处理模块依赖的,前者将“依赖前置”(预加载所有被依赖脚本模块,执行速度最快),后者走的“依赖就近”(懒加载被依赖脚本模块,请求脚本更科学),你可以根据项目具体需求来选择最合适的。

五. 延迟请求首屏外的文件

先解释下,“首屏”指的是页面初始化时候的页面内容显示区域,也就是页面一加载,用户就首先看到的区域。

比如像京东啊淘宝啊,对于需要滚动页面才能看到的图片内容,都做了类似lazyload的处理,这些无非都是走了代理模式的理念,但的确给用户一个错觉——这个页面更快地加载完了,因为我很快就看到了屏幕上的内容(即使我还没下拉滚动条,而页面后方的文件其实还没真正加载呢)。

我们可以这样实现此方案,不依赖任何lazyload库,拿图片来做示范,我们可以这样编写首屏外的图片(假设某张图片地址是a.jpg)的img标签:

<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="a.jpg">

如上所示,页面初步加载这张图片的时候是直接以base64的方式(当然你也可以统一使用一张占位图loading.gif来替代)来快速显示一张极小的图片的,而图片本身的真实路径是存在data-src属性内的,我们可以在页面加载结束后再向服务器请求它真实的文件并替换:

function init() {
    var imgDefer = document.getElementsByTagName(‘img‘);
    for (var i=0; i<imgDefer.length; i++) {
        if(imgDefer[i].getAttribute(‘data-src‘)) {
             imgDefer[i].setAttribute(‘src‘,imgDefer[i].getAttribute(‘data-src‘));
        }
    }
}
window.onload = init;

如上是对图片的延迟加载处理,对于视频、音频文件,可以采取完全一样的原理来延迟加载,从而有效减少页面初始化等待时间。

六. 优化页面模块排放顺序

这里有一个很好的例子,比如有一个页面是这样的——左边是侧边栏,用于存放用户的头像啊、资料啊,以及网站投放的广告啊,而右侧是文章内容区域:

那么我们的代码很可能是这样的:

<body>
  <sidebar>
    <!-- 侧边栏内容 -->
  </sidebar>

  <content>
    <!-- 文章内容 -->
  </content>
</body>

于是乎,浏览器按照它的UI单线程准则从上到下先加载了侧边栏,再加载我们的文章。。。

很明显,这样不是一个人性化的加载顺序,我们得弄清楚,页面上各个区域模块,对于用户而言,哪个才是最重要、最应当首先展示的

对于上面的例子,文章内容才应该是用户首先要看到、需要浏览器优先请求和显示的区域。所以我们得修改我们的代码为:

<body>
  <content>
    <!-- 文章内容 -->
  </content>

  <sidebar>
    <!-- 侧边栏内容 -->
  </sidebar>
</body>

当然这里仅仅是用一个小示例来挑起各位的脑洞,懂得举一反三和实际运用才是硬道理。

七. 其它建议

1. 不要在css中使用@import,它会让一个样式文件去等待另一个样式文件的请求,无形中增加了页面等待时间(当然如果走的scss,@import就是另一回事了,呃跑题了~);

2. 避免页面或者页面文件重定向查找,这相当于你走进了一间卫生间,然后看到上面的牌子说“此处不同,请去前面左拐的卫生间”,又得重走一遍;

3. 减少无效请求——比如通过css/js来请求一个不存在的资源,可能会导致较长的等待和阻塞(直到它返回错误信息);

4. 无论你是否决定将脚本放到页尾,但一定要保障脚本放置于样式文件后方;

5. 文件在小于50K的时候,直接读取文件流会比从文件系统中去读取文件来的快些,大于50K则相反。比如有一张图片,如果它小于50K,我们可以将它转为二进制数据存储在数据库中,页面若要读取该图片则从数据库上来读取,若文件大小大于50K,那建议存放在可访问的文件夹中以文件的形式来读取即可;

6. 使用 cookie-free domains 来存放资源,减少无用cookie传输的网络开销(可以参考这篇文章);

7. 配置.htaccess文件、走Gzip页面压缩形式、开启keep-alive连接模式等后端解决方案,这边就不细说了。

相信页面提速的方案绝对不仅仅局限于上面提到的这些,而且每个项目都有着各种需求和情况,只能按需选择适合自己的方案。

但最重要的还是——尽量把用户的体验放在第一位,无论是页面的加载或者交互,都应当多从用户角度切入去思考和设计最优选的方案,这样相信你一定能做出出色、受欢迎的作品。

转载:http://www.cnblogs.com/vajoy/p/4183569.html

时间: 2024-10-31 10:54:12

WEB网站页面提速(前端向)的相关文章

WEB网站安全性(前端向)

相信进来的时候你已经看到alert弹窗,显示的是你cookie信息(为配合博客园要求已删除).单纯地在你的客户端弹出信息只是类似于迫使你在自己的房间脱衣服——没人看得到,自然也不算啥恶意行为.那么如果我把你的信息通过脚本发送到我的服务器保存起来呢?先放心,我不打算这么做,也没那笔闲钱去购置一个服务器来做羞羞的事情,也不希望博客园把我这地盘给封掉了. 如同标题所写的,今天要聊的是WEB安全机制,但这“前端”二字倒是说的狭义了些,安全的问题大部分还是更依赖于后端的过滤和拦截措施,后端的朋友如果感兴趣

浅谈WEB页面提速(前端向)

记得面试现在这份工作的时候,一位领导语重心长地谈道——当今的世界是互联网的世界,IT企业之间的竞争是很激烈的,如果一个网页的加载和显示速度,相比别人的站点页面有那么0.1秒的提升,那也是很大的一个成就. 然后我不知道怎么写下去了,就在群里问了那群狗头军师,结果是这样的... 推荐免费培训课:http://www.jinhusns.com/Products/Curriculum/?type=xcj 好的,是时候“语锋一转”切回主题了 —— 如何提升我们站点页面的访问速度.减少等待时间,从而最大化地

web页面提速

首页 加关注 联系 关于 管理 浅谈WEB页面提速(前端向) posted @ 2014-12-27 14:19 vajoy 阅读(6078) 评论(36) 编辑 收藏 记得面试现在这份工作的时候,一位领导语重心长地谈道——当今的世界是互联网的世界,IT企业之间的竞争是很激烈的,如果一个网页的加载和显示速度,相比别人的站点页面有那么0.1秒的提升,那也是很大的一个成就. 然后我不知道怎么写下去了,就在群里问了那群狗头军师,结果是这样的... 好的,是时候“语锋一转”切回主题了 —— 如何提升我们

web页面提速(摘抄)

记得面试现在这份工作的时候,一位领导语重心长地谈道——当今的世界是互联网的世界,IT企业之间的竞争是很激烈的,如果一个网页的加载和显示速度,相比别人的站点页面有那么0.1秒的提升,那也是很大的一个成就. 然后我不知道怎么写下去了,就在群里问了那群狗头军师,结果是这样的... 好的,是时候“语锋一转”切回主题了 —— 如何提升我们站点页面的访问速度.减少等待时间,从而最大化地提升用户访问体验呢? 针对这个问题,我们今天会从前端的角度来提出系列解决方案,它们都能有效地提升你页面的访问速度. 一. 减

提升网站页面打开速度的12个建议

我们知道用户都喜欢浏览速度快的网站,不喜欢花费太多的时间等待网页的打开,等待的时间过长,会让用户失去耐心,甚至烦躁时会直接关闭网页,这样就会失去一些潜在的客户了. 其次,从SEO的角度来说,关键字的排名与网页的打开速度也有关系,Google的Web搜索团队曾在官方博客上宣布,将把网站的速度作为PR(PageRank)算法的一个因子,在所有因素都相等的情况下,速度快的网站将排在速度慢的网站前面.同时指出很多网站都没有利用最佳的页面优化技术,页面加载速度都存在很大缺陷.那么,我们该如何补救并提高网站

(转)web网站架构演变

浅谈web网站架构演变过程 前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变. 该系统具备的功能: 用户模块:用户注册和管理 商品模块:商品展示和管理 交易模块:创建交易和管理 阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架如maven+spring+struct+hibernate.maven+spri

web网站架构

浅谈web网站架构演变过程 前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变. 该系统具备的功能: 用户模块:用户注册和管理 商品模块:商品展示和管理 交易模块:创建交易和管理 阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架如maven+spring+struct+hibernate.maven+spri

雅虎网站页面性能优化的34条黄金守则(转)

雅虎团队经验:网站页面性能优化的34条黄金守则1.尽量减少HTTP请求次数      终端用户响应的时间中,有80%用于下载各项内容.这部分时间包括下载页面中的图像.样式表.脚本.Flash等.通过减少页面中的元素可以减少HTTP请求的次数.这是提高网页速度的关键步骤.      减少页面组件的方法其实就是简化页面设计.那么有没有一种方法既能保持页面内容的丰富性又能达到加快响应时间的目的呢?这里有几条减少HTTP请求次数同时又可能保持页面内容丰富的技术. 合并文件是通过把所有的脚本放到一个文件中

网站页面的呈现方式

下午经过一场激烈的关于前端页面呈现问题的头脑风暴,: 经过讨论之后初步确定应该是两种方式: 第一种为,页面模板由后端返回,并由浏览器进行缓存.页面需要的业务数据,则通过服务调用的从后端获取.当数据获取之后,在前端页面通过JS的方式,将数据渲染. 第二种为,浏览器呈现的页面是有后端实现模板和数据的整合,并生成页面的HTML字符串,并把该字符串从后端返回给浏览器.页面的JS文件则主要完成前端的交互. 其实这两种方案,现有的技术都有使用,但是他们还是有一定的区别,此时我能想到的区别有: 1)第一种方案