目录
Web表现层调用过程... 2
延迟... 3
什么是延迟... 3
延迟的构成... 3
最基本的优化思路:... 4
Web表现层性能优化... 4
Web性能的基本指标... 4
Web性能测试的常见工具... 5
连接网络并发送请求部分的优化手段... 5
对DNS查找的优化思路... 5
对连接网络并发送请求的优化思路... 5
使用浏览器缓存... 5
可以考虑使用本地存储... 6
尽量减少Http请求... 6
尽量使用长连接,也就是KeepAlive. 6
合理使用内联... 6
合理使用异步的方式来加载内容... 7
对AJAX请求尽量使用GET方法... 7
使用多域名增加最大并发数... 7
使用外部的JS和CSS. 7
网络来回传输内容部分的优化手段... 8
基本的优化思路... 8
使用浏览器缓存... 8
精简JS. 8
精简CSS. 8
精简图片... 8
压缩要传输的内容... 8
减小Cookie. 8
针对Web组件使用域名无关性的Cookie. 9
用更小的并且可缓存的favicon.ico. 9
不要混用不同品牌的网络设备... 9
服务器处理请求部分的优化手段... 9
服务器端的性能... 9
基本的优化思路... 9
Tomcat的基本优化... 9
1:合理分配Tomcat需要的内存... 9
2:Tomcat本身的配置优化... 10
JavaScript的常见优化... 11
其它优化事项... 13
浏览器渲染绘制部分的优化手段... 13
基本的优化思路... 13
图片、JS的预载入... 14
将脚本放在底部... 14
将样式文件放在页面顶部... 14
CSS尽量写在<head>.. 14
最小化iframe的数量... 14
减少DOM访问... 14
避免不必要的渲染... 15
使用<link>而不是@importChoose. 15
所有图片都应该指定高宽属性,否则浏览器会重新渲染网页... 15
尽量少用帧数过多过快的FLASH,GIF动画... 15
尽量避免使用CSS子选择符... 15
尽量避免渲染过程的”中断”,比如等待js的执行... 15
不要在HTML中使用缩放图片... 15
避免使用CSS表达式... 15
现代浏览器... 15
浏览器的优化机制... 15
更好的利用浏览器的机制... 16
Web表现层调用过程
把一次请求/应答大致分成如下几个大部分:
1:连接网络并发送请求
2:网络来回传输内容
3:服务器处理请求并返回内容
4:浏览器解析处理内容,进行渲染并绘制
从输入URL地址或者点击URL的一个链接到页面呈现的一次请求,大致需要下面几个步骤
1:查找DNS,解析出URL对应的IP地址
2:初始化网络连接
3:发送HTTP请求
4:网络传输请求到服务器
5:Web服务器接收到请求,经过处理转发到相应的Web应用
6:Web应用处理请求,并返回相应的应答
7:网络传输应答内容到前端浏览器
8:浏览器开始解析从服务器端返回的内容,开始渲染和绘制
9:根据HTML内容来构建DOM(文档对象模型)
10:加载和解析样式,构建CSSOM(CSS对象模型)
11:根据DOM和CSSOM来构建渲染树,这个过程是按照文档顺序从上到下依次进行的
12:会根据构建渲染树的过程,在适当的时候,把已经构建好的部分绘制到界面上,中间还会伴随着重绘(repaint)和回流(reflow)等,如此循环操作,直到渲染绘制完成
13:整个页面加载完成,会触发0nLoad事件。
简单分析一下这个过程
1:要通过URL请求服务器,浏览器就要知道这个URL对应的IP是什么,只有知道了IP地址,浏览器才能准备的把请求发送到指定的服务器的具体IP和端口号上面。浏览器的DNS解析器负责把URL解析为正确的IP地址。
这个解析工作是要花时间的,而且这个解析的时间段内,浏览器不能从服务器那里下载任何东西。浏览器和操作系统提供了DNS解析缓存支持。
2:当获得了IP地址之后,浏览器会请求与服务器的连接,TCP经过三次握手后建立连接通道
3:浏览器真正发送HTTP请求,这个请求包含了很多东西,如cookie和其他的head头信息。
4:网络开始传输请求到服务器,这个会包括很多时间,比如网络阻塞时间、网络延迟时间和真正传输内容的时间等,这是个很复杂的过程
5:Web服务器接收到请求,会根据URL里面的上下文,转交给相应的Web应用进行处理
6:Web应用会依次通过很多处理,比如:filter、aop的前置处理、IoC处理、真实处理对象的寻找和创建等,这个根据每个应用的具体实现而不同。
然后会把请求转交到真实的处理对象,进行相应的业务处理,并生成Response对象
7:通过网络传输应答内容回到前端的浏览器。其实首先到达浏览器的是纯粹的html代码,不包含什么图片,外部脚本,外部CSS等,也就是页面主要的html结构。
8:接下来就是浏览器解析页面,进行渲染和绘制的过程了,大致如下:
(1)装载和解析Html文档,构建DOM,如果在解析中发现需要其它的资源,比如图片,那么浏览器会发出请求以获取这个资源
(2)装载和解析CSS,构建CSSOM
(3)根据DOM和CSSOM来构建渲染树
(4)然后对渲染树的节点进行布局处理,确定其在屏幕的位置
(5)把渲染好的节点绘制到界面上
以上步骤是一个渐进的过程,渲染引擎不会等到所有Html都被解析完才创建并布局渲染树,它会在获取文档内容的同时把已经接收到的局部内容先展示出来。
9:重绘(repaint)的发生:如果渲染到后面,发现需要修改前面已经绘制元素的外观,比如背景色、文字颜色等,不影响它周围和内部布局的行为,这就需要重绘这个元素
10:回流(reflow)的发生:如果渲染到后面,发现需要修改前面已经绘制好的元素的某些行为,这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲染,这就是回流
延迟
什么是延迟
延迟指的是:消息或分组从信息源发送到目的地所需的总时间
延迟的构成
1:传播延迟
指的是消息从发送端到接收端需要的时间,是信号传播距离和速度的函数。取决于距离和信号通过的媒介。
2:传输延迟
指的是把消息中的bit转移到链路所需要的时间,是消息长度和链路速率的函数。取决于链路的速率,跟客户端到服务器的距离无关。
3:处理延迟
指的是处理分组头部、检查位错误、确定分组目标所需要的时间。通常由硬件来完成,如路由器要根据分组头部来选择出站路由。
4:排队延迟
指的是分组排队等待处理的时间。如果分组到达的速度超过了路由器的处理能力,那么分组就要进入缓冲区排队。
最基本的优化思路:
1:尽量减少不必要的网络延迟
2:尽量减少请求数量
3:尽量减少来回传递的数据量
4:提高后台程序的响应速度
5:提高每个环节和步骤的处理能力,以加快速度
Web表现层性能优化
Web性能的基本指标
1:请求响应时间:从客户端发起请求,到web应用对用户请求作出响应,再发送反馈直至用户接收完毕所需要的时间,也被称为TTLB(Time to Last Byte),建议3/5/10秒。
2:最大并发用户数:用来衡量可用性,就是在不出现系统崩溃的情况下,能同时提供服务的最大用户数量,通常分成两种:
(1)严格意义上的并发:即所有的用户在同一时刻做同样的操作
(2)广义的并发:多个用户同时进行了操作,但是这些操作可以是相同的,也可以是不同的
3:事务响应时间:是针对业务的概念,事务可能由一系列请求组成,以完成业务功能
4:TPS(Transaction Per Second):每秒钟系统能够处理的交易或者事务的数量,通用用来衡量系统处理能力
5:吞吐量:在一次性能测试过程中,通过网络传输的数据量的总和。吞吐量/传输时间就是吞吐率
Web性能测试的常见工具
1:用于测试页面资源加载速度,比如:
Firebug、Chrome的开发者工具、HttpWatch等
2:用于测试页面渲染呈现,以及js运行速度,比如:
dynaTrace Ajax、Speed Trace等
3:对页面进行整体评价分析,比如:
WebPageTest、Page Speed、yslow等
4:专业的测试工具,比如:
Selenium、WebLoad、ab、LoadRunner等
连接网络并发送请求部分的优化手段
对DNS查找的优化思路
尽量减少DNS查找
由于浏览器每访问一个新的域就需要一次DNS查找,然后依赖浏览器或者操作系统的缓存,再次访问的时候就不再查DNS了。因此DNS查找越少,页面下载性能越好。
1:合理规划应用访问的域名,尽量控制在5个以内
2:谨慎使用第三方或外部域名的资源,比如:第三方统计、使用外部分享等
对连接网络并发送请求的优化思路
1:尽量利用浏览器缓存,能不发出请求最好
2:尽量减少HTTP请求
3:尽量保持长连接
4:尽量使用异步来加载资源,这样访问不到的资源就不用请求了
5:尽量最短距离的访问,比如使用离客户端最近的CDN
6:对于必须请求下载的内容,合理规划域名数量,尽量多个请求并发下载
使用浏览器缓存
在用户浏览网站的不同页面时,很多内容是重复的,比如相同的JS、CSS、图片等。
如果能够建议甚至强制浏览器在本地缓存这些文件,将大大降低页面产生的流量,从而降
低页面载入时间。
根据服务器端的响应Header,一个文件对浏览器而言,有几种不同的缓存状态:
1:服务器端告诉浏览器不要缓存此文件,每次都到服务器上更新文件
2:服务器端没有给浏览器任何指示
3:在上次传输中,服务器给浏览器发送了Last-Modified或Etag数据,再次浏览时浏览器将提交这些数据到服务器,验证本地版本是否最新的,如果为最新的则服务器返回304代码,告诉浏览器直接使用本地版本,否则下载新版本。一般来说,有且只有静态文件,服务器端才会给出这些数据。
4:服务器强制要求浏览器缓存文件,并设置了过期时间。在缓存未到期之前,浏览器将直接使用本地缓存文件,不会与服务器端产生任何通信。
因此我们要做的是尽量使用第四种状态,特别是对于JS、CSS、图片等变动较少的文件。这个主要是使用过期头,比如:Expires和Cache-Control,还有keep-alives,Last-modified等
可以考虑使用本地存储
Html5提供了LocalStorage的功能;目前主流的浏览器都支持,大约是每个网站5M的大小。从LocalStorage读取数据的最佳策略是,用最少的键存最多的数据。
尽量减少Http请求
1:合并页面对象(Html、css、js、image等),如可以把多个CSS文件合成一个,把多个JS文件合成一个等。建议一个文件的大小控制在30-50KB。
2:使用CSS Sprites(译为“CSS图像拼合”或“CSS贴图定位”)技术,把多个图片合成一个图片,然后利用CSS的“background-image”,“background-repeat”,“background-position”的组合进行背景定位。要注意图片也不要过大,否则下载时间过长,而且对内存消耗较大。
还有一些需要考虑的,比如:
(1)在图片合并的时候,要留足够的空间,防止板块内不会出现不必要的背景
(2)在宽屏,高分辨率的屏幕下的自适应,图片如果不够宽,很容易出现背景断裂
(3)开发的时候比较麻烦,需要测量计算每一个背景单元的精确位置
(4)维护的时候比较麻烦,每次修该都要改这张合并的图片
(5)由于图片的位置需要固定为绝对数值,这就失去了诸如center之类的灵活性
3:图像地图:把一幅图像分成多个区域,每个区域指向不同的URL地址。
4:内联图象:使用 data:[medeiatype][base64]data的形式在实际的页面嵌入图像数据
总之就是尽量减少页面的对象,这样自然就减少了Http请求数量。但是这样合并后,如果没有下载完,就什么都干不了,所以需要合理的合并和拆分;另外也可能会对项目的模块化管理以及维护带来一些副作用,请合理平衡。
尽量使用长连接,也就是KeepAlive
Http1.1默认的KeepAlive是打开的,能在浏览器和服务端之间保持长连接,从而复用这个连接。
合理使用内联
内联在减少Http请求数的同时,也会带来很多问题:
1:没有浏览器缓存
2:没有边缘缓存,如CDN
3:没有按需加载
4:不能进行预加载
内联的使用建议:
1:非常小的文件,而且使用的地方很少,应该使用内联,超过4K的文件不要内联
2:页面中的图片(从页面直接引用的图片,非css引用的图片)尽量不要内联
3:如果不是首屏至关重要的内容,都不应该被内联起来
4:谨慎内联css图片
合理使用异步的方式来加载内容
比如:使用图片延迟加载技术来减少Http请求数和并发数,同时减少下载内容的数据量,因为访问不到的就不用下载了。
所谓图片延迟加载,就是每次只加载当前屏幕可见区域的图片,其余的图片在用户滚动页面到该位置后才开始加载,可以使用jQuery.LazyLoad
对AJAX请求尽量使用GET方法
XMLHttpRequest的POST要两步,而GET只需要一步。但要注意的是GET最大能处理的URL长度有限制。
缓存Ajax调用,要正确设置Http头
通常应该设置Expires为将来的时间,1ast-modified为过去的时间,而Cache-control为public告诉中间的代理程序,这些数据可以缓存
考虑使用CDN,既可以加快客户端的访问速度,也可以减轻服务端的压力
使用多域名增加最大并发数
因为浏览器从一个域能同时下载的量是有限制的,一般在6个或更多,但是浏览器只对单个域名限制并发数,而不对单个IP限制并发数,所以可将一个IP地址映射到多个域名,然后使用这些域名访问网站资源,这样使用两个域名并发数就可以达到12个了。
但需要注意的是,域名并不是越多就越好的,因为域名解析也需要花费时间,而且并发数太多也会耗费客户端太多的CPU,域名数量到了一定程度,网页性能就会开始下降,所以在应用中需要根据实际情况寻找一个平衡点。
使用外部的JS和CSS
将内联的JS和CSS做成外部的JS、CSS,减少重复下载
网络来回传输内容部分的优化手段
基本的优化思路
1:尽量利用浏览器缓存,能不传具体内容最好
2:尽量减少需要传输的内容的数据量
3:尽量最短距离的访问,比如使用离客户端最近的CDN
4:尽量优化网络链路
使用浏览器缓存
这个前面已有讲述
精简JS
1:精简:从代码中移除不必要的字符以减少其大小
2:混淆:在精简的同时,还会改写代码,函数、变量名被转换成更短的字符串
可以使用ShrinkSafe来精简JS。常见的压缩工具如:jsmin、YUIcompressor等。
精简CSS
从代码中移除不必要的字符以减少其大小,可以使用CSS Compressor
精简图片
优先考虑使用CSS来代替,其次才是图片的裁剪。
如果可能,请选用有损压缩的格式,比如jpg等
说明:对大图片进行精简,要在效果和大小之间做出平衡。
压缩要传输的内容
传输之前,先使用GZIP压缩再传输给客户端,客户端接收之后由浏览器解压,这样虽然稍微占用了一些服务器和客户端的CPU,但是换来的是更高的带宽利用率。对纯文本的压缩率是相当可观的。
减小Cookie
根据Http规范的描述,每个客户端最多保持300个Cookie,针对每个域名最多20个Cookie(实际上多数浏览器现在都比这个多,比如Firefox是50个),每个Cookie最多4K,注意这里的4K根据不同的浏览器可能不是严格的4096。对于Cookie最重要的就是,尽量控制Cookie的大小,不要塞入一些无用的信息。
针对Web组件使用域名无关性的Cookie
这里说的Web组件,多指静态文件,比如图片、CSS等,这些都是不需要Cookie数据的。
用更小的并且可缓存的favicon.ico
不要混用不同品牌的网络设备
因为他们的互操作性和可用性上,可能会有兼容问题
服务器处理请求部分的优化手段
服务器端的性能
影响服务器端的性能是多方面的,包括软件架构、部署环境、服务器硬件配置、软件设计、开发实现等等各方面。当然这里我们只讨论服务器端的Web层,同样涉及很多内容,比如:
Nginx、Varnish、JVM、Web服务器(Tomcat)、Web应用开发(如:Filter、Spring MVC、CSS、Javascript、Jsp等等)
基本的优化思路
1:尽量缩短单个请求的处理时间
2:尽可能多的并发处理请求
3:一定要做到能横向扩展
Tomcat的基本优化
Tomcat默认的配置已经是经过优化的了,留给我们可优化的空间很小,我
们主要能调整的是:跟具体使用场景相关的设置,大致有:
1:合理分配Tomcat需要的内存
这个是在启动Tomcat的时候设置catalina.sh中的JAVA_OPTS,常见设置如下:
(1)-server:启用JDK的Server版
(2)-Xms:虚拟机初始化时的最小内存
(3)-Xmx:虚拟机可使用的最大内存(建议到物理内存的80%)
(4)-XX:PermSize:持久代初始值
(5)-XX:MaxPermSize:持久代最大内存(默认是32M)
(6)-XX:MaxNewSize:新生代内存的最大内存(默认是16M)
说明:
(1)一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。因为默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。
(2)察看配置是否生效:jmap-heap tomcat的进程号
2:Tomcat本身的配置优化
在server.xml中的〈Connector〉中配置,常见设置如下:
(1)maxConnections:最大连接数,对BIO模式,默认等于maxThreads;对NIO默认10000;对APR/native默认8192
(2)maxThreads:最大线程数,即同时处理的任务个数,默认值为200
(3)acceptCount:当处理任务的线程数达到最大时,接受排队的请求个数,默认100
(4)minSpareThreads:最小空闲线程数,默认10
(5)compression:设置是否开启GZip压缩
(6)compressableMimeType:哪些类型需要压缩,默认是text/html,text/xml,text/plain
(7)compressionMinSize:启用压缩的输出内容大小,默认为2048
(8)enableLookups:是否反查域名,为了提高处理能力,应设置为false
(9)connectionTimeout:网络连接超时,单位毫秒。设置为-1表示永不超时,通常可设置为2000毫秒。
说明:
(1)如果要加大并发连接数,应同时加大maxThreads和acceptCount,可以两个设置一样
(2)WebServer允许的最大连接数还受制于操作系统的内核参数设置,可通过ulimit-a查看
(3)如果配置了<Executor>,在<Connector>中通过executor属性指定参照<Executor〉,那么<Connector>中关于线程的配置失效,以<Executor>中配置为准
3:关于BIO/NIO/APR
(1)BI0是最稳定最老的一个连接器,是采用阻塞的方式,意味着每个连接线程绑定到每个Http请求,直到获得Http响应返回,如果Http客户端请求的是keep-Alive连接,那么这些连接也许一直保持着直至达到timeout时间,这期间不能用于其它请求。
(2)NIO是使用Java的异步I0技术,不做阻塞,要使用的话,直接修改server.xml里的Connector节点,修改protocol为:protocol="org.apache.coyote.http11.Http11NioProtocol"
(3)APR是使用原生C语言编写的非堵塞I/0,但是需要安装apr和native,直接启动就支持apr,能大幅度提升性能。使用时指定protocol为protocol=“org.apache.coyote.http11.Http11AprProtocol”。可以到http://apr.apache.org/download.cgi去下载,大致的安装步骤如下:
A:安装apr
./configure--prefix=/usr/local/apr
make make instal1
B:安装apr-iconv
./configure--prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr
make make install
C:安装apr-util
./configure--prefix=/usr/local/apr-util --with-apr=/usr/local/apr --with-apr-
iconv=/usr/local/apr-iconv/bin/apriconv
make make install
D:安装tomcat-native,就在Tomcat的bin下自带
tar zxvf tomcat-native.tar.gz
cd tomcat-native-1.1.29-src/jni/native
./configure --with-apr=/usr/local/apr
make make install
E:设置apr的环境变量
进入Tomcat的bin路径下,打开catalina.sh,在文件的#!/bin/sh下添加如下内容:LD_LIBRARY PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib expot LD_LIBRARY_PATH
这样就只是给这个TOMCAT添加了APR,不破坏其它TOMCAT的配置
G:重新启动Tomcat,查看日志信息,应该有类似如下的信息:
org.apache.catalina.core.AprLifecycleListener.init Loaded APR based Apache
Tomcat Native library 1.1.29 using APR version 1.5.0.
参考配置如下:
<Connector port="8080" protocol="org.apache.coyote.httpl1.HttpllAprProtocol"
URIEncoding="UTF-8"
maxConnections="10000"
maxThreads="2000"
acceptCount="2000"
minSpareThreads="100"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
enableLookups="false"
disableUploadTimeout="true"
connectionTimeout="20000"
redirectPort="8443"/>
JavaScript的常见优化
1:尽量把JS放在页面底部
2:循环中要多次使用的表达式,比如:判断长度的表达式、获取对象的表达式,最好在外面做个变量来保存
3:减少页面重绘,比如:不要在循环中改变元素外观,应该拼接好后,一次性的设置给元素,这样就只需要重绘一次
4:尽量避免使用eval
5:把全局域的变量缓存成为局部域的变量,全局变量其实是window对象的成员,而局部变量是放在函数的栈里的,局部变量访问更快
6:尽量避免对象的嵌套查询,比如:objl.obj2.obj3这样的表达式就会引起多次查找,应该把各个对象用局部变量缓存起来,这样后续使用就直接使用
7:当需要将数字转换成字符时,采用如下方式:“”+数字的方式最快
8:当需要将浮点数转换成整型时,应该使用Math.floor()或者Math.round()。而不是使用parseInt(),Math是内部对象,速度是最快的
9:尽量让代码简洁,比如变量名、方法名在不影响语意的情况下尽量简单
10:连加多个字符串的,可以使用数组,把要连接的字符串放到数组中,然后使用数组的join方法,形如:var str=myArr.join(“”);
11:尽量用JSON格式来创建对象,而不是var obj=new Object(),因为前者是直接复制,而后者需要调用构造器
12:尽量使用JSON格式来创建数组,即直接使用:[parm,param,param...],而不是采用new Array(parm,param,,param...)这种语法。因为使用JSON格式的语法是引擎直接解释的。而后者则需要调用Array的构造器
13:尽量使用正则表达式来操作字符串,例如替换、查找等。因为JS的循环速度比较慢,而正则表达式的操作是用C写成的API,性能比较好
14:对于大的JS对象,因为创建时时间和空间的开销都比较大,因此应尽量缓存
15:避免使用document.write,可以使用innerHTML来向页面添加对象
16:避免使用setTimeOut方法,应用setInterval,setTimeout每次要重置定时器
17:避免with语句,with会创建自己的作用域,会增加其中执行代码的作用域长度
18:尽量减少对DOM的操作,避免回流,引起回流的操作常见的有:
(1)改变窗体大小
(2)更改字体
(3)添加移除stylesheet块
(4)内容改变哪怕是输入框输入文字
(5)CSS虚类被触发如:hover
(6)更改元素的className
(7)当对DOM节点执行新增或者删除操作或内容更改时
(8)动态设置一个style样式时
(9)当获取一个必须经过计算的CSS值时,比如访问offsetWidth、clientHeight等
为了避免回流的发生,建议:
(1)在对DOM进行操作之前,尽可能把多次操作内容准备好,然后尽量1次操作完成
(2)在对DOM操作之前,把要操作的元素,先从当前DOM结构中删除,等处理好过后再添加回到DOM中。从DOM中删除元素的方法有:
A:通过removeChild()或者replaceChild()实现真正意义上的删除
B:设置该元素的display样式为“none”
(3)对获取的那些会触发回流操作的属性,比如offsetWidth等缓存起来
(4)尽量避免通过style属性对元素的外观进行修改,因为会触发回流操作
A:使用更改className的方式替换style.xxx=xxx的方式
B:使用style.cssText=’’;一次写入样式
C:避免设置过多的行内样式
(5)添加的结构外元素尽量设置它们的位置为fixed或absolute
(6)避免使用表格来布局
(7)避免在CSS中使用JavaScript表达式
19:对局部使用的JS,采用异步装载、按需装载JS的方式,比如使用jQuery的:
jQuery.getScript(“t.js",function){t1();});
这个是没有缓存js的,要缓存的话,如下:
jQuery.ajax({
url:"t.js",
dataType:"script",
cache:true
}).done(function){
t1();
});
其它优化事项
1:尽量避免重定向,尤其是一些不必要的重定向,如对Web站点子目录的后面添加个“/”,
就能有效避免一次重定向
2:避免Http 404错误
3:尽可能减少系统中的时序约束
4:尽量实现无状态,尽可能在浏览器端维护会话,采用Cookie
5:尽量利用分布式缓存来存放状态,且要避免:
(1)避免某些功能要求关联到某个服务器
(2)不要使用状态或者会话复制
(3)不要把缓存放在执行操作的系统上,应该是公共的
6:合理利用页面缓存,比如varnish
7:合理利用对象或数据缓存,如memercached
8:尽可能使用异步通信,通常下面这些都应该是异步的:
(1)调用外部api,或者是第三方的应用
(2)长时间运行程序
(3)容易出错的,或者频繁更改的方法
(4)没有时间约束的方法,比如发邮件
浏览器渲染绘制部分的优化手段
基本的优化思路
1:尽量加快资源的获取
2:尽量减少DOM节点
3:尽量减少渲染过程的中断和等待
4:尽量减少重绘
5:尽量避免回流
图片、JS的预载入
预载入图像最简单的方法是在JavaScript中实例化一个新Image()对象,然后将需要载入的图像的URL作为参数传入。
function preLoadImg(url){
var img=new Image();
img.src=url;
}
例如在登录页面预载入JS和图片
将脚本放在底部
脚本放在顶部带来的问题:
1:使用脚本时,对于位于脚本以下的内容,逐步呈现将被阻塞
2:在下载脚本时会阻塞并行下载
放在底部,当脚本没加载进来,用户就触发脚本事件,可能会出现JS错误问题。
将样式文件放在页面顶部
样式表加载完成后,才会构建渲染树,因此样式文件放在页面底部可能会出现两种情况:
1:白屏
2:无样式内容的闪烁
CSS尽量写在<head>
不要出现在<body>中,否则会引起重新渲染
最小化iframe的数量
iframe会导致重绘,同时iframe也是SEO的大忌。针对前端优化来说iframe
有其好处,可以异步和并发加载资源。
减少DOM访问
查找DOM会花费时间,如果更改了位置和外观,可能会引起重绘和回流,建议:
1:使用临时变量(或数组)缓存已经访问过的元素
2:“离线”更新节点,再将它们添加到树中
3:避免使用JavaScript输出页面布局-一应该是CSS的事儿
4:批量操作时,使用字符串拼接,用innerHTML开销更小,速度更快,同时内存也更安全
避免不必要的渲染
比如:
(1)position:fixed:fixed定位在滚动时会不停的进行渲染,特别是如果是页面顶部有个fiexd,页面底部有个类似返回顶部的fixed,则在滚动时会整个页面进行渲染,效率非常低。可以加transform:translateZ(0);解决。
(2)hover 特效:建议页面滚动时,先取消hover效果,滚动停止后再加上hover效果。这个可以通过在外层加类名进行控制
(3)应该设置border:none,而不是border:0,设置为0,仍然是会渲染的
使用<link>而不是@importChoose
在IE中@import 指令等同于把link标记写在HTML的底部。
所有图片都应该指定高宽属性,否则浏览器会重新渲染网页
尽量少用帧数过多过快的FLASH,GIF动画
尽量避免使用CSS子选择符
CSS子选择符会造成一次浏览器的筛选和定位计算,
比如能用.div的,就尽量不要用.nav ul li a.div这样的写法
尽量避免渲染过程的”中断”,比如等待js的执行
不要在HTML中使用缩放图片
避免使用CSS表达式
现代浏览器
浏览器的优化机制
1:资源预取和排定优先次序
2:DNS预解析
3:TCP预连接
4:页面预渲染
更好的利用浏览器的机制
1:CSS和JavaScript等重要资源应该尽早在文档中出现
2:应该尽早交付CSS,从而避免渲染阻塞并让JavaScript执行
3:非关键性的JavaScript应该推迟,以避免阻塞DOM和CSSDOM的构建
我们可以在文档中嵌入提示,以触发浏览器为我们采用其他优化机制
1:预解析特定域名,如:<link rel=“dns-prefetch”href=“//abc.com”>
2:预先获取页面后面要用的资源,如:<link rel=“subresource”href=“/js/a.js”>
3:预先获取将来导航要用的资源,如:<link rel=“prefetch”href=“/img/a.jpg”>
4:根据对用户下一个目标的预测,预渲染特定页面,如:<link rel=“prerender” href=“//abc.com/a/b/d.html”>
这些提示会触发浏览器的优化机制,如果浏览器不支持,会当成空操作,没有害处