上篇文章我简要的介绍了下网站静态化的演进过程,有朋友可能认为这些知识有点过于稀松日常了,并且网站静态化的技术基点也不是那么高深和难以理解,所以它和时下突飞猛进的web前端技术相比,就显得不三不四了。其实当我打算写本系列的以前我我的以为web前端有一个点是不少人都知道重要,可是有经常低估它做用的,那就是web前端和web服务端如何融合的这个点上,这个点再加上咱们要作出一个规模庞大,高并发,快速响应的网站时候它对于web前端的架构技术的演进起到了一个不可忽视的做用。javascript
网站的web前端要实现高效,第一个要解决的短板就是网络的延迟性对网站的加载效率的影响,固然不少人会说网速快不快这是网络运营商的问题,不是网站的问题,可是你们确定也见过就算咱们用上了千兆宽带也会有些网站加载速度慢的让人没法忍受,网站自己的确是无法控制网络速度的能力,可是若是咱们不下降网络对页面加载效率的影响,其余任何优化网站的手段也就无从谈起,缘由就是网络效率对于网页加载效率的影响是起到大头做用的,只有这个大头被解决了,那么解决其余的小头才能发挥做用。php
回到上文讲到的网站静态化的关键点动静分离,解决这个关键点的本质就是为了下降网速对网站加载效率的影响,可是咱们在处理动静分离问题时候采起的策略不一样会对咱们整个网站架构产生重大影响,特别是将网页作好动静拆分后,静态的资源尽力向浏览器端推移,这就致使了前端架构出现了之前服务端才有的MVC模式,这就致使web前端架构产生了质的变化,如是一些原来适用于flash这样的重客户端的技术也被传统的web前端所采用,MVC模式在web前端进一步演进由此而出现了MVP(Model-View-Presenter)模式,MVVM(Model-View-ViewModel)模式。也许上篇文章里有人对讲述动静分离的原理有点异议,可是当今突飞猛进的web前端技术就是这些常见技术不断演化而来,这就是我上篇想表达的内容,我以为这个系列的特色应该是细节,这是和上个系列存储的瓶颈注重思想是有所不一样的。css
动态网站最难以动静分离的就是页面了,其余的静态资源例如:图片、外部脚本文件等等这些和静态网站的手法基本一致,其实业界很早就关注了动态网站的动静分离问题,而且为不一样的动静分离方案都进行了总结,今天我就介绍下这些技术。本人web服务端的工做语言是java,所以下面服务端的例子是使用java的web技术阐述的,其余语言例如php都有与之对应的技术,因此请那些不是使用java做为服务端工做语言的朋友能够类比学习。html
在java的web开发里,页面技术jsp自己就包含了将页面动静分离的手段,例以下面的代码:前端
<%@ include file=”header.jsp” %> <body> ………. <%@ include file=”footer.jsp” %>
通常一个网站的头部和尾部都是同样,所以咱们把头部的代码单独放置在一个header.jsp页面里,页面尾部的代码放置下footer.jsp页面里,这样技术人员在开发页面时候就再也不须要重复编写这些重复的代码,只须要引用便可,这个作法最大的好处就是能够避免不一样页面在相同代码这块的不一致性,假如没有这个统一引用的话,手动编写或者复制和粘贴,出错的几率是很是的高的。java
可是这个作法有一个问题,问题就是这种动静分离其实都是做用于单个页面的,也就是说每一个页面都要手动的重复这个动静分离的操做,大多数状况这种作法都不会有什么问题,可是对于一个大型网站而言这种作法就有可能会制造没必要要的麻烦,这里我截取了一张京东的首页,以下图所示:web
讲述前我要事先声明下,京东网站可能不存在我要讲述的问题,我这里只是使用京东网站的首页作例子来讲明,看图里的首页和食品两个条目,有些公司作这样的网站时候这些导航进入的页面会是一个独立的工程,每一个工程都是由独立的项目组开发维护的,虽然项目组不一样可是他们页面的总体结构会是一致的,若是按照上面的动静分离手段,那么每一个项目组都要独立维护一份相同的头部尾部资源,这个时候麻烦来了,若是该公司要新增个新的条目,那么每一个项目组都要更新本身不变的资源,若是该企业一共分了5个项目组,如今又作了一个新的条目,那么其余与之无关的项目组都得折腾一次更改统一引用文件的工做,要是作的不仔细就有可能出现页面展现不一致的问题,为了解决这个问题,java的web开发里就会考虑使用模板语言替代jsp页面技术,例如模板语言velocity,这些模板语言都包含一个布局的功能,例如velocity就有这样的功能,咱们看看velocity的布局模板实例,以下所示:ajax
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>#springMessage("page_upop_title")</title> <meta http-equiv="X-UA-Compatible" content="requiresActiveX=true"/> <meta name="keywords" content='#springMessage("page_upop_keywords")'/> <meta content='#springMessage("page_upop_description")' name="description"/> </head> <body oncontextmenu="return false" onselectstart="return false"> #if($pageHead) #parse($pageHead) #end $screen_content #parse($page_footer) </body> </html>
页面里咱们能够引入这个布局格式,这个布局文件其实就是页面里不变的东西抽取了出来,它完成了页面动静分离,页面只要应用这个布局文件便可,到了这里这个布局文件和前面的include方式区别不大,那么咱们再看看下面的代码:spring
<property name="layoutUrl" value="layout/default.vm"/><!--指定layout文件-->
这是布局文件的引用方式,咱们能够把布局文件放置在网络上,项目里应用这个文件所在地址便可,这样咱们就把项目里不变的静态资源抽取在同一个地方,若是在碰到布局要作修改,那么咱们只须要改一个地方便可。apache
无论服务端采起何种动静分离,动静资源的整合都是有服务端完成,按照上文提到网站静态化的思想,这些作法不会给网站性能提高带来任何好处,它们只是给开发,运维提供了便利而已,按前文的思路,咱们要把动静分离往前移,服务端往前移碰到的第一个点就是静态的web服务器例如apache或ngnix。
在讲解静态的web服务器动静分离前我要先讲一下为何咱们要在服务端前面加个静态web服务器的道理。我我的以为在每一个服务端以前都布置一个静态web服务器,该服务器起到一个反向代理的做用,并且我以为无论咱们是否使用CDN,最好都这么作,这么作有以下好处:
好处一:方便日志的记录。
好处二:在服务端以前设立了一个安全屏障,即静态web服务器能够在必要时候过滤有害的请求。
好处三:能够控制流入到服务端的请求个数,当并发很高时候,能够利用静态web服务器能承担更高并发的能力来缓冲服务端的压力,这里我补充一些实践技巧,以java里经常使用的web容器tomcat为例,通常官方给出它的最大并发数应该不会超过200,若是咱们在tomcat前放置了一个apache服务器,那么咱们能够把tomcat的最大并发数设置为无效大,把并发数的控制放置在apache这边控制,这么作会给咱们系统运维带来很大的好处,tomcat虽然有一个建议最大并发数,可是实际运行里java的web容器到底能承受多大并发其实要看具体场景了,所以咱们若是能够动态控制apache的并发数,这个操做很方便的,那么咱们就能够动态的调整tomcat这样容器的承载能力。
好处四:能够便于咱们作动静分离。
这里咱们以apache为例子讲解将动静分离前移到apache的一些作法,apache有一个功能叫作SSI,英文全称是Server Side Include,页面上咱们通常这样使用SSI,SSI有一种标签,例如:
<!--#include file="info.htm"-->
页面通常使用注释的方式引入,这个和jsp的引入有点区别的,SSI的作法其实和服务端的引入相似,只不过使用SSI将原本服务端作的动静整合交由了apache完成了,咱们能够把静态文件直接放置在Apache这里,若是这个静态web服务器上升到CDN,那么这些静态资源就能够在靠近用户的地方使用,SSI说白了就是像apache这样的静态资源服务器接收到服务端返回后,将一部份内容插入到页面了,而后将完整页面返回至浏览器。这个作法若是优化的得当,能够很好的提高网站的加载效率。
Apache这样的静态资源服务器还支持一种动静整合的技术,这个技术就是ESi,它的英文全称叫作Edge Side Includes,它和SSI功能相似,它的用法以下所示:
<esi:include src="test.vm.esi?id=100" max-age="45"/>
它和SSI区别,使用esi标签获取的资源来自于缓存服务器,它和SSI相比有明显的性能优点,其实网页特别是一个复杂的网页咱们作了动静分离后静态的资源自己还能够拆分,有的部分缓存的时间会长点,有点会短点,其实网页里某些动态内容自己在必定时间里有些资源也是不会发生变化的,那么这些内容咱们能够将其存入到缓存服务器上,这些缓存服务器能够根据页esi传来的命令将各个不一样的缓存内容整合在一块儿,由此咱们能够发现使用esi咱们会享受以下优势:
优势一:静态资源会存放在缓存里,那么获取静态资源的效率会更高。
优势二:根据静态资源的时效性,咱们能够对不一样的静态资源设置不一样的缓存策略,这就增长了动静分离方案的灵活性。
优势三:缓存的文件的合并交由缓存服务器完成,这样就减小了web服务器自己抓取文件的开销,从而达到提高web服务器的并发处理能力,从而达到提高网站访问效率的目的。
(友情提示:ESI这块我还了解的不太深刻,据说它其实能够直接使用在jboss上,相关知识我还要继续收集资料学习)
SSI和ESI是静态web服务器处理动静资源整合的手段,那么咱们再把动静整合操做往前移,这个时候就到了浏览器端了。浏览器端的动静整合的技术称之为CSI,英文全称叫作Client Side Includes,这个技术就是时下javascriptMVC、MVVM以及MVP技术采起的手段,实现CSI通常是采用异步请求的方式进行,在ajax技术还没出现的年代咱们通常采起iframe的方式,不过使用CSI技术页面加载就会被人为分红两次,一次是加载静态资源,等静态资源加载完毕,启动异步请求加载动态资源,这么一作的确会发生有朋友提到的一种加载延迟的问题,这个延迟咱们可使用适当的策略来解决的,关于CSI的使用是本系列的重点,我会在后面文章里重点讲解。