JavaScript关于提高网站性能的几点建议(一)


Posted in Javascript onJuly 24, 2016

近在学习《高性能网站建设指南》这本书,本文算是一个学习笔记,将学到的东西进行整理一下,方便后面查看。

性能黄金法则(Performance Golden Rule)解释了只有10%~20%的最终用户响应时间花在接受所请求的用户HTML文档上,剩余的80%~90%时间花在为HTML文档所引用的所有组件(图片、脚本、样式表等)进行的HTTP请求上,最终用户响应时间花费在页面组件上

  ——Steve Sounders

1 文件合并(减少HTTP请求数量)

CSS Sprites

  利用css sprites将网站用到的图片合并成一张图片,通过background-position、width、height控制背景图位置来使用某一个图标,这种方式可以将多个图片请求缩减为一次,生成css sprites的工具也很多,grunt和gulp中都有相关的插件,CssGaga也不错。

合并js和css

  和精灵图一样,合并css和js文件也是减少HTTP请求很重要的方式,对css文件的合并目前来说没有什么争议,但是对于当前js模块化盛行,将所有js文件合并成一个文件,仿佛是一种倒退。正确的方式是遵守编译型语言的模式,保持js的模块化,在生成过程中只对初始请求用到的js文件生成目标文件。

2 使用内容发布网络(减少HTTP请求时间)

  HTTP请求时间另一个影响因素是你与网站web服务器所处的距离,显然距离越远,请求所需的时间也越久,通过CDN可以大大改善这一点。

  CDN是分布在多个不同地理位置的web服务器,用于更加有效的向用户发布内容。CDN最主要的功能是给终端用户存放静态文件,另外也提供下载、安全服务等功能。

3 设置浏览器缓存(避免重复HTTP请求)

使用Expire/Cache-control

  浏览器通过使用缓存可以避免每次都进行重复的请求,HTTP 1.0和HTTP1.1分别有不同的缓存实现方式,Expires(1.0)和Cache-control(1.1)。Web服务器通过expires告诉客户端在指定的时间内,都使用该文件的缓存副本,不再向服务端重复发出请求,例如:

Expires: Thu, 01 Dec 2016 16:00:00 GMT (GMT格式)

  这个设置意味着截止到2016年12月1日,都可以使用该缓存副本,无需再发出请求。

  Expires这种通过截止日期的方式,存在一个限制:要求客户端和服务端时钟严格同步,而HTTP 1.1引入的Cache-Control通过指定一个以秒为单位的时间指定缓存日期,则不存该限制,例如:

Cache-Control: max-age=31536000

  这个设置意味缓存时间为一年,推荐使用Cache-Control,但是在支持HTTP 1.1的情况下,另外要注意的一点:Cache-Control和Expire同时存在时,Cache-Control具有更高的优先级。

配置或移除ETag

  使用Expire/Cache-Control可以避免第二次访问时,使用本地缓存避免重复HTTP请求,提高网站速度。然而,在用户点击了浏览器刷新或者在expire已过期的情况下,仍然会向服务端发出HTTP GET请求,而此时如果该文件并没有发生变化,服务端不会返回整个文件而是会返回304 Not Modified状态码。

  服务端判断该文件是否发生变化的依据有两个:Last-Modified(最新修改日期)和ETag(实体标签);

  ETag(Entity Tags)是在HTTP 1.1引入的,与Last-Modified同时存在时要有更高的优先级。服务端通过对比客户端发来的ETag(If-None-Match)和当前ETag,若相同返回304 Not Modifed,否则返回整个文件以及200 OK。

  ETag存在一个问题:当浏览器向一个服务器发送GET请求原始组件,之后又向另一台服务器请求该组件时,ETag是不匹配的,当然,如果你的网站寄宿在一台服务器上不存在这个问题,而现在很多网站使用多台服务器,ETag的存在就大大降低验证有效性的成功率。

  存在这个问题是时的解决办法是对ETag进行配置,移除服务器innode值只保留修改时间戳和大小作为ETag值,或者直接移除ETag,使用Last-Modified来验证文件有效性。

4 压缩组件(减小HTTP请求大小)

  通过对HTTP传输的文件进行压缩减小HTTP请求的大小,提高请求速度,GZIP是目前最常用也是最有效的压缩方式。

  然而,并非所有的资源文件都需要压缩,压缩的成本包括服务端需要花费CPU周期进行压缩,而客户端也需要对压缩文件进行解压缩,必须结合自己网站进行权衡。现在绝大多数网站都对其HTML文档进行压缩,部分网站选择对js、css进行压缩,几乎没有网站对图片、PDF等文件进行GZIP压缩,原因在于这些文件是已经被压缩过的,采用HTTP压缩已经被过压缩的东西并不能使它更小。事实上,添加标头,压缩字典,并校验响应体实际上使它变得更大,而且还浪费了CPU。

  如何对网站开启GZIP,需要在所使用的web服务器(IIS、Nginx、Apache等)中进行设置。

5 CSS文件放在首部

  将CSS文件放在首部和放在尾部,并不影响HTTP请求,因此从请求时间上来讲是一致的,然而从用户体验的角度,将CSS文件放在首部,会获得更好的用户体验。

  原因在于浏览器是从上到下依次解析html文档,将CSS文件置于头部,页面会首先对CSS文件发出请求,随后加载DOM树并对其进行渲染,页面会逐步呈现在用户面前。

  而与之相反,如果将CSS文件放置在尾部,页面加载完整DOM之后请求CSS文件,然后对整个DOM树渲染并呈现给用户,从用户的角度,在css文件没有请求完成之前,整个页面是出于白屏状态的,白屏是浏览器的一种行为,David Hyatt对其的解释是这样的

在样式树没有完全加载之前,渲染dom树就是一种浪费,因为在样式树加载完成之后会再次渲染,出现FOUC(无样式内容闪烁)问题。

  另外要注意的一点,使用link而不是@import引入css样式表,使用@import引入的样式即使写在首部,也会在文档最后加载。

6 JS文件放在尾部

  HTTP请求是并行的,不同浏览器并行下载的数目也不一样(2、4、或者8个),并行下载提高了HTTP请求的速度。而将JS文件放在首部,不仅会阻塞后面文件的下载而且会阻塞页面的渲染。

  为什么会这样呢?原因有两个:

JS文件中可能存在document.write修改页面的内容,因此页面会在脚本执行完成之后才可使渲染。

不同JS文件不管大小如何,可能存在依赖关系,因此必须按照顺序进行执行,因此在加载脚本的时候并行下载是禁止的。

所以,最好的方式是讲js文件放置在尾部,等页面所有可视化组件加载完成之后再进行请求,提高用户体验。

以上所述是小编给大家介绍的JavaScript关于提高网站性能的几点建议(一),希望对大家有所帮助,如果大家想了解更多内容,敬请关注三水点靠木。在下篇文章小编给大家介绍javascript提高网站性能优化的建议(二)

Javascript 相关文章推荐
jQuery下通过$.browser来判断浏览器.
Apr 05 Javascript
jQuery setTimeout()函数使用方法
Apr 07 Javascript
jQuery表单验证插件解析(推荐)
Jul 21 Javascript
原生js实现回复评论功能
Jan 18 Javascript
js控制按钮,防止频繁点击响应的实例
Feb 15 Javascript
jquery PrintArea 实现票据的套打功能(代码)
Mar 17 Javascript
微信小程序实现皮肤功能(夜间模式)
Jun 18 Javascript
全站最详细的Vuex教程
Apr 13 Javascript
微信小程序导航栏滑动定位功能示例(实现CSS3的positionsticky效果)
Jan 24 Javascript
使用Vue-cli3.0创建的项目 如何发布npm包
Oct 10 Javascript
javascript canvas封装动态时钟
Sep 30 Javascript
vue-cli 3如何使用vue-bootstrap-datetimepicker日期插件
Feb 20 Vue.js
JavaScript提高网站性能优化的建议(二)
Jul 24 #Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
Jul 24 #Javascript
省市二级联动小案例讲解
Jul 24 #Javascript
基于jQuery实现多标签页切换的效果(web前端开发)
Jul 24 #Javascript
js简单实现调整网页字体大小的方法
Jul 23 #Javascript
jquery实现ajax加载超时提示的方法
Jul 23 #Javascript
数据结构中的各种排序方法小结(JS实现)
Jul 23 #Javascript
You might like
openPNE常用方法分享
2011/11/29 PHP
几种有用的变型 PHP中循环语句的用法介绍
2012/01/30 PHP
Yii操作数据库的3种方法
2014/03/11 PHP
PHP使用ajax的post方式下载excel文件简单示例
2019/08/06 PHP
基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解
2013/05/07 Javascript
js显示文本框提示文字的方法
2015/05/07 Javascript
jQuery匹配文档链接并添加class的方法
2015/06/26 Javascript
js插件dropload上拉下滑加载数据实例解析
2016/07/27 Javascript
js 基础篇必看(点击事件轮播图的简单实现)
2016/08/20 Javascript
原生js实现tab选项卡切换
2020/03/23 Javascript
require、backbone等重构手机图片查看器
2016/11/17 Javascript
详解vue slot插槽的使用方法
2017/06/13 Javascript
vue侧边栏动态生成下级菜单的方法
2018/09/07 Javascript
Node+OCR实现图像文字识别功能
2018/11/26 Javascript
vue.js使用v-model实现表单元素(input) 双向数据绑定功能示例
2019/03/08 Javascript
Vue.js组件实现选项卡以及切换特效
2019/07/24 Javascript
vuex实现数据状态持久化
2019/11/11 Javascript
[57:55]完美世界DOTA2联赛PWL S3 Magma vs Phoenix 第二场 12.12
2020/12/16 DOTA
python利用elaphe制作二维条形码实现代码
2012/05/25 Python
Python编程实现蚁群算法详解
2017/11/13 Python
python3+PyQt5实现支持多线程的页面索引器应用程序
2018/04/20 Python
python 获取字符串MD5值方法
2018/05/29 Python
python得到电脑的开机时间方法
2018/10/15 Python
python通过tcp发送xml报文的方法
2018/12/28 Python
python flask框架实现传数据到js的方法分析
2019/06/11 Python
浅谈Python中(&,|)和(and,or)之间的区别
2019/08/07 Python
Pytorch之finetune使用详解
2020/01/18 Python
使用python求解二次规划的问题
2020/02/29 Python
python使用pyecharts库画地图数据可视化的实现
2020/03/25 Python
Python MOCK SERVER moco模拟接口测试过程解析
2020/04/13 Python
Python 生成短8位唯一id实战教程
2021/01/13 Python
8款精美的CSS3表单设计(登录表单/下拉选择/按钮附演示及源码)
2013/02/04 HTML / CSS
Booking.com美国:全球酒店预订网站
2017/04/18 全球购物
Agoda.com官方网站:便宜预订全球酒店,高达80%的折扣
2018/04/04 全球购物
信息部岗位职责
2013/11/12 职场文书
利用python实时刷新基金估值(摸鱼小工具)
2021/09/15 Python