`

《高性能HTML5》读后整理的Web性能优化内容

 
阅读更多
  • 读后感

        先说说《高性能HTML5》这本书的读后感吧,个人觉得这本书前两章跟书的标题完全搭不上关系,或者说只能算是讲解了“高性能”这三个字,HTML5完全不见踪影。个人觉得作者应该首先把HTML5的大菜拿出来讲一讲,再去分析性能优化的内容,这样才会有吸引力。因为只是在线试读,没有机会看后面的内容,所以不胡乱评价了。

 

        虽然我觉得这本书没说到点子上,但还是从“高性能”方面学到了很多东西------又一次扩大了知识面!以前,我一直认为一套架构稳定、后台高质量的代码就能让系统高效,但读完这本书两章内容之后,发现前端有那么多可以提高性能的方式,一直被我轻视的前台技术也能有这么“花哨”,又一次井底之蛙了- -||。

 

        在看完这两章内容之后,我意犹未尽,于是乎从网上搜索关键字“Java Web高性能”,在IBM社区找到两篇不错的文章,而让人更意外的是我发现那两篇文章的内容跟《高性能HTML5》前两章高度相似,不知道是谁抄袭谁的,大家可以鉴别下真伪,下面附上地址。

        http://dl2.iteye.com/upload/attachment/0097/9373/b0e69540-e703-3530-81bb-c93de7b850a6.pdf

        http://www.ibm.com/developerworks/cn/java/j-lo-javawebhiperf1/

        http://www.ibm.com/developerworks/cn/java/j-lo-javawebhiperf2/        

 

        前面是读后感,下面是我针对最近几天学习到的提高Web性能进行了篇幅不小的总结,一来为新人提供帮助,二来自己做一下笔记,加深记忆。

 

  •  性能之前端篇

--减少重绘

        在HTML页面完成展现之后,动态改变页面元素或调整CSS样式都会引起浏览器重绘,性能的损耗直接取决于动态改变的范围:如果只是改变一个元素的颜色之类的信息则只会重绘该元素;而如果是增删节点或调整节点位置则会引起其兄弟节点也一并重绘。

        减少重绘并不是说不要重绘,而是要注意重绘范围:①改动的DOM元素越深则影响越小,所以尽量深入节点改动;②对某些DOM样式有多重变动尽量合并到一起修改。

 

以改变一个<a>标签的背景色、宽度和颜色为例。

 

<a href="javascript:void(0);" id="example">传统的代码</a> 
<script> 
 var example = document.getElementById("example"); 
 example.ondblclick = function() { 
 example.style.backgroundColor = "red"; 
 example.style.width = "200px"; 
 example.style.color = "white"; 
 } 
</script> 
 以上会执行3次重绘,而通过CSS代替javascript多次执行则只进行一次重绘。

 

 

<style> 
 .dblClick { 
 width: 200px; 
 background: red; 
 color: white; 
 } 
</style> 
<a href="javascript:;" id="example">CSS优化的代码</a> 
<script> 
 var example = document.getElementById("example"); 
 example.ondblclick = function() { 
 example.className = "dblClick"; 
 } 
</script>
 

 

--避免脚本阻塞加载

        当浏览器在解析常规的script标签时,它需要等待script下载完毕,再解析执行,而后续的HTML代码只能等待。CSS文件引入要放在<head>头部,因为这是HTML渲染必备元素。为了避免阻塞加载,应把脚本放到文档的末尾,而CSS是需要放在头部的!

 

<head>
<link rel="stylesheet" href="common.css">
......
<script src="example.js"></script>
</body>
 

 

--避免节点深层级嵌套

        深层级嵌套的节点在初始化构建时往往需要更多的内存占用,并且在遍历节点时也会更慢些,这与浏览器构建DOM文档的机制有关。浏览器会把整个HTML文档的结构存储为DOM“树”结构。当文档节点的嵌套层次越深,构建的DOM树层次也会越深。

 

如下代码,完全能够去掉<div>或<span>其中一个标签。

 

<div>
  <span>
    <label>嵌套</label>
  </span>
</div>
 

 

--页面缓存

        通常不设置缓存的情况下,每次刷新页面都会重新读取服务器的文件,而如果设置缓存之后,所有文件都可以从本地取得,这样明显极大提高了页面效率。

 

我们可以通过设置页面头的expires来定义页面过期时间,将过期时间定久一点就达到了“永久”缓存。

 

<meta http-equiv="expires" content="Sunday 26 October 2099 01:00 GMT" />
 当然,如果你的项目代码有变更,因为客户端缓存了文件就得不到最新的文件,势必造成显示错误。基于这个问题的解决方案就是给链接文件加一个时间戳,如果时间戳有变化,浏览器会认为是新文件,就会向服务器请求最新文件。

 

 

<script src="example2014-6-17.js"></script>
//如果是JSP,可以用EL表达式来取时间戳信息,这样管理更加方便
<script src="example${your time param}.js"></script>
//或者这样的写法更优秀:
<script src="example.js?time=2014-6-7"></script>
<script src="example.js?time=${your time param}"></script>
 

 

--压缩合并文件

        所有涉及到请求数据的文件尽量做压缩,比如Javascript文件、css文件及图片文件,特别是图片文件,如果没有高清晰要求,完全可以压缩后再使用。

        数量少体积大的文件要比数量多体积小的文件加载速度快,所以有时候可以考虑将多个js文件、多个css文件合并在一起。

 

除此之外减少HTML文档大小还可以采取下面几种方法:

①删掉HTM文档对执行结果无影响的空格空行和注释

②避免Table布局

③使用HTML5

 

--HTML+CSS3+Javascript各司其职

        让三元素各司其职才能做出高性能的网页:HTML是页面之本也是内容之源,有了它就能跟CSS和Javascript交互;CSS3可以说是展现大师,而且日渐强大的CSS能代替Javascript做很多动态的事情如渐变、移动等动态效果;Javascript是动态数据之王,旧浏览器依靠js来完成动态效果展现,但现在的CSS也能完成js的工作,所以尽量将工作交给css,这样会获得更好的性能。(这个说得有点大)

 

--图像合并实现CSS Sprites

        图像合并其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS 的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position可以用数字能精确的定位出背景图片的位置。

        一个页面要用到多个图标,完全可以将多个图标合并成一个图,然后只需要发一次图片请求,通过css定位分割图标即可。

 

--避免使用Iframe

        使用iframe并不会增加同域名下的并行下载数,浏览器对同域名的连接总是共享浏览器级别的连接池,在页面加载过程中iframe元素还会阻塞父文档onload事件的触发。并且iframe是html标签中最消耗资源的标签,它的开销比DIV、SCRIPT、STYLE等DOM高1~2个数量级。

 

避免onload事件被阻塞,可使用JavaScript动态的加载iframe元素或动态设置iframe的src属性(但其仅在高级浏览器IE9及以上有效)。

 

<iframe id="if"></iframe>
document.getElementById("if").setAttribute("src","url");
 

 

--多域名请求

        一般来说,浏览器对于相同域名的图片,最多用2-4个线程并行下载(不同浏览器的并发下载数是不同的)。而相同域名的其他图片,则要等到其他图片下载完后才会开始下载。

        有时候,图片数据太多,一些公司的解决方法是将图片数据分到多个域名的服务器上,这在一方面是将服务器的请求压力分到多个硬件服务器上,另一方面,是利用了浏览器的特性。(大家可以去新浪、腾讯门户网站查看,这些大型站点同一页面加载的图片可能由多个站点提供)

        注:一个HTML请求的域名也不要太多(2~3个差不多),多了可能造成不同服务器连接时间差异,反而影响速度。

 

--避免空链接属性

        如<img src=""><a href="">这样的设置方式是非常不可取的,即使链接为空,在旧的浏览器也会以固定步骤发送请求信息。

        另外<a href="#"></a>也不可取,最好的方式是在链接中加一个空的js代码<a href="javascript:void();"></a>

 

--使用图像的BASE64编码

        base64是一串字符串,他可以代表一个图片的所有信息,也就是可以通过<img src="data:image/png;base64,S">(S表示一串base64码)来显示图片,这种方式不需要再向服务器发送请求,完全由浏览器解析成图片。

        目前高级浏览器都支持此功能,但要注意两点:①低版本浏览器(如IE7)不支持;②base64字符串长度随图片的大小及复杂度成正比,base64也像URL一样,也有超出长度的情况(在IE8下很常见)。所以要根据情况来使用。

 

--显式设置图片的宽高

        如果HTML里的图片没有指定尺寸(宽和高),或者代码描述的尺寸与实际图片的尺寸不符时,浏览器则要在图片下载完成后再“回溯”该图片并重新显示,这会消耗额外时间。

<img src="demo.jpg" width="200" height="200">

 

--显式指定文档字符集

        如果浏览器不能获知页面的编码字符集,一般都会在执行脚本和渲染页面前,把字节流缓存,然后再搜索可进行解析的字符集,或以默认的字符集来解析页面代码,这会导致消耗不必要的时间。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

 

--渐进式增强设计

        渐进式增强设计的通俗解释就是:首先写一段满足所有浏览器的基本样式,再在后面针对不同高级浏览器编写更漂亮的样式

        如下代码,所有浏览器都支持background-color: #2067f5;满足了浏览器基本现实需求,而后面的background-image: -webkit-gradient等则为不同高级浏览器使用,只要浏览器识别就能执行这段代码(不识别,CSS也不会报错只会直接忽略)。

 

<div class="someClass"></div> 
.someClass 
{ width: 100px; 
 height: 100px; 
 background-color: #2067f5; 
 background-image: -webkit-gradient(linear, left top, left bottom, from(#2067f5), 
to(#154096)); 
 background-image: -webkit-linear-gradient(top, #2067f5, #154096); 
 background-image: -moz-linear-gradient(top, #2067f5, #154096); 
 background-image: -ms-linear-gradient(top, #2067f5, #154096); 
 background-image: -o-linear-gradient(top, #2067f5, #154096); 
 background-image: linear-gradient(to bottom, #2067f5, #154096); 
}
参考阅读:多浏览器适配测试

 

 

--懒加载与预加载

        预加载和懒加载,是一种改善用户体验的策略,它实际上并不能提高程序性能,但是却可以明显改善用户体验或减轻服务器压力。

        预加载表示当前用户在请求到需要的数据之后,页面自动预加载下一次用户可能要看的数据,这样用户下一次操作的时候就立刻呈现,依次类推。

        懒加载表示用户请求什么再显示什么,如果一个请求要响应的时间非常长,就不推荐懒加载。

 

--Flush机制

        当一个页面非常大,内容非常多,可以采用flush的形式分部分返回给页面,这样能告诉用户我正在工作,显示一部分内容比白屏等很长时间要好得多。在Java Web技术中,实现Flush非常简单,只要调用 HttpServletResponse.getWriter输出流的flush方法,就可以将已经完成加载的内容写回给客户端。

        这种方式只适用于返回数据特别多、请求时间特别长的情况,常规数据还是用正常的实时全部返回最佳。这种实现方式实际会增加浏览器渲染时间和用户整体等待时间,但从用户体验上会更加优秀。

 

  • 性能之服务器优化

--CDN机制

        所谓的CDN,就是一种内容分发网络,它采用智能路由和流量管理技术,及时发现能够给访问者提供最快响应的加速节点,并将访问者的请求导向到该加速节点,由该加速节点提供内容服务。

        通俗点说,你在成都(浏览器)购买了北京卖家(服务器)的产品,北京卖家通过快递(CDN服务)寄送包裹,从北京到成都可以走路、坐汽车、火车或飞机,而采用CND的快递会选择飞机直达,因为这种寄送方式最快。

 

当然使用CDN有两个注意事项:

1、CDN加速服务很贵,如果你觉得你的网站值得加速,可以选择购买;

2、CDN不适合局域性网站,比如你的网站只有某一个片区访问或者局域网访问,因为区域性网络本来就很近,无需CDN加速。

 

--HTTP协议的合理使用

        浏览器缓存带来的性能提升已经众人皆知了,而很多人却并不知道浏览器的缓存过期时间、缓存删除、什么页面可以缓存等,都可以由我们程序员来控制,只要您熟悉HTTP协议,就可以轻松的控制浏览器。

 

扩展阅读:深入理解HTTP协议

 

--动静分离

        所谓的动静分离,就是将Web应用程序中静态和动态的内容分别放在不同的Web服务器上,有针对性的处理动态和静态内容,从而达到性能的提升。我们知道如果一个HTML有多个域名请求数据文件会提高

Tomcat服务器在处理静态和并发问题上比较弱,所以事先动静分离的方式一般会用Apache+Tomcat、Nginx+Tomcat等。

        以Apache+Tomcat为例,其运行机理是:页面请求首先给Apache,然后Apache分析请求信息是静态还是动态,静态则本机处理,动态则交给Tomcat做处理。

        这其实是负载均衡的雏形,这样的实现不用让开发人员做任何特殊开发,一个<img src="demo.jpg">交给服务器即可,至于这个文件是从Apache还是从Tomcat取得,开发人员完全无需关注。

 

--HTTP持久连接

        持久连接(Keep-Alive)也叫做长连接,它是一种TCP的连接方式,连接会被浏览器和服务器所缓存,在下次连接同一服务器时,缓存的连接被重新使用。HTTP无状态性表示了它不属于长连接,但HTTP/1.1提供了对长连接的支持(不过这必须依赖浏览器和服务器双方均支持长连接功能才行),最常见的HTTP长连接例子是“断点下载”。

        浏览器在请求的头部添加 Connection:Keep-Alive,以此告诉服务器“我支持长连接,你支持的话就和我建立长连接吧”,而倘若服务器的确支持长连接,那么就在响应头部添加“Connection:Keep-Alive”,从而告诉浏览器“我的确也支持,那我们建立长连接吧”。服务器还可以通过Keep-Alive:timeout=..., max=...的头部告诉浏览器长连接失效时间。

        配置长连接通常是要服务器支持设置,有测试数据显示,使用长连接和不使用长连接的性能对比,对于Tomcat配置的maxKeepAliveRequests为50来说,效率竟然提升了将近5倍。

 

--GZIP压缩技术

        HTTP协议支持GZIP的压缩格式,当服务器返回的HTML信息报头中包含Content-Encoding:gzip,它就告诉浏览器,这个响应的返回数据已经压缩成GZIP格式,浏览器获得数据后要进行解压缩操作,一定程度上减轻了服务器传输数据的压力。

        很多服务器已经支持通过配置来自动将HTML信息压缩成GZIP,比如tomcat、又比如很火的Nginx。如果无法配置服务器级别的GZIP压缩机制,可以改为程序压缩。

 

 // 监视对 gzipCategory 文件夹的请求
 @WebFilter(urlPatterns = { "/gzipCategory/*" }) 
 public class GZIPFilter implements Filter { 

 @Override 
 public void doFilter(ServletRequest request, ServletResponse response, 
 FilterChain chain) throws IOException, ServletException { 
 String parameter = request.getParameter("gzip"); 
 // 判断是否包含了 Accept-Encoding 请求头部
 HttpServletRequest s = (HttpServletRequest)request; 
 String header = s.getHeader("Accept-Encoding"); 
 //"1".equals(parameter) 只是为了控制,如果传入 gzip=1,才执行压缩,目的是测试用
 if ("1".equals(parameter) && header != null && header.toLowerCase().contains("gzip")) { 
 HttpServletResponse resp = (HttpServletResponse) response; 
 final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 

 HttpServletResponseWrapper hsrw = new HttpServletResponseWrapper( 
 resp) { 

 @Override 
 public PrintWriter getWriter() throws IOException { 
 return new PrintWriter(new OutputStreamWriter(buffer, 
 getCharacterEncoding())); 
 } 

 @Override 
 public ServletOutputStream getOutputStream() throws IOException { 
 return new ServletOutputStream() { 

 @Override 
 public void write(int b) throws IOException { 
 buffer.write(b); 
 } 
 }; 
 } 

 }; 

 chain.doFilter(request, hsrw); 
 byte[] gzipData = gzip(buffer.toByteArray()); 
 resp.addHeader("Content-Encoding", "gzip"); 
 resp.setContentLength(gzipData.length); 
 ServletOutputStream output = response.getOutputStream(); 
 output.write(gzipData); 
 output.flush(); 
 } else { 
 chain.doFilter(request, response); 
 } 
 } 
 // 用 GZIP 压缩字节数组
 private byte[] gzip(byte[] data) { 
 ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240); 
 GZIPOutputStream output = null; 
 try { 
 output = new GZIPOutputStream(byteOutput); 
 output.write(data); 
 } catch (IOException e) { 
 } finally { 
 try { 
 output.close(); 
 } catch (IOException e) { 
 } 
 } 
 return byteOutput.toByteArray(); 
 } 
……
 }
 

 

  • 总结

        细节决定成败,系统慢是由一个又一个不良的小细节造成的,所以开发初期做好充足的准备,开发中认真负责、不偷工减料,维护期更要注重代码质量,这样才能让我们的系统稳定高效。

        个人觉得一个产品的新版本质量可以从核心js文件看出来:如果核心js文件大小比上一版本大太多,明显在性能上就会有问题,我们要争做像谷歌、亚马逊这样优秀的团队--能够在功能升级的同时减小核心js文件大小。

分享到:
评论

相关推荐

    构建高性能web站点

    在构建高性能Web站点的过程中,我们需要考虑多个关键领域,这些领域涵盖了服务器配置、网络优化、前端性能提升、数据库管理和缓存策略等。以下是一些详细的知识点: 1. **服务器架构**:选择合适的服务器架构至关...

    HTML5高级程序设计读后感整理分享.docx

    2. **Storage API**:HTML5引入了Web Storage(包括localStorage和sessionStorage),提供了比传统Cookie更高效、更大容量的数据存储方式,便于在浏览器端保存用户数据,提高应用性能和用户体验。 3. **WebSockets*...

    html5webpdf

    在移动互联网日益流行的今天,HTML5技术已经成为开发高性能、跨平台移动应用的首选。 第1章讨论了移动互联网时代中WEB技术的变革,如何利用HTML5应对移动设备的挑战和机遇。移动Web开发的第2章着重讲解了如何使用...

    前端面试题整理—性能优化及安全篇.docx

    本篇文章主要涵盖了前端开发中性能优化和安全相关的知识点,包括 web 语义化、SEO、会话跟踪、图像优化、Web 攻击技术、渐进增强、内存泄漏、从输⼊URL 到页⾯加载的过程、重绘和回流的优化、⽹站性能优化等。...

    html5技术整理

    HTML5引入了一系列新的结构元素,如、、、和等,这些元素使得网页内容的结构更加清晰,有利于搜索引擎优化(SEO)和无障碍访问(WCAG)。 二、表单控制的改进 HTML5对表单控件进行了升级,新增了、、等输入类型,...

    Tomcat性能优化及JVM内存工作原理

    Tomcat作为一款广泛应用的Java Servlet容器,其性能优化对于提升Web应用的响应速度和稳定性至关重要。而JVM(Java Virtual Machine)内存管理是影响性能的关键因素之一。本文将详细探讨Tomcat的性能优化策略以及JVM...

    webUI 4.27版本的插件

    首先,WebUI的核心是其集成的浏览器组件,允许在UE4环境中嵌入HTML5内容。这使得开发者可以利用现代Web技术如JavaScript、CSS3和WebGL来构建复杂的用户界面,而不必受限于UE4内置的图形工具。这种灵活性极大地扩展了...

    Web全栈高级视频教程第十期.txt打包整理.zip

    5. 性能优化:如代码压缩、图片优化、懒加载、预加载等技术,提升用户体验。 在后端开发方面,可能涉及的知识点有: 1. 后端语言:如Node.js、Java、Python或Ruby,讲解其语法特性、常用库和框架,如Express、...

    HTML5技术手册(最新整理chm版).rar

    1. **语义化标签**:HTML5引入了许多新的语义化元素,如、、、、和等,这些标签有助于更好地描述网页内容结构,提高页面可读性和搜索引擎优化。 2. **离线存储**:通过`applicationCache`,HTML5允许网页在离线状态...

    搜集整理html5 静态模板260套(06)

    HTML5是一种先进的网页标准,它在过去的十年里彻底改变了网页设计和开发的格局。作为下一代超文本标记语言,HTML5...这个包含260套模板的压缩包为开发者提供了丰富的资源,帮助他们快速构建符合现代标准的高性能网站。

    网站各方面详细优化,WEB

    网站优化是提升用户体验、搜索引擎排名以及降低服务器负担的关键步骤,主要涵盖了前端性能优化、后端服务优化、SEO(搜索引擎优化)等多个层面。以下是对这些关键知识点的详细解释: 1. **前端性能优化**:前端是...

    Web前端知识整理 初学者.zip

    9. Web性能优化:包括代码压缩、图片优化、CDN(内容分发网络)使用、缓存策略等,以提高网页加载速度。 10. SEO(搜索引擎优化):让网站更容易被搜索引擎收录,提升搜索排名。 11. Accessibility(无障碍访问)...

    java web 笔记整理

    Java Web技术是构建互联网应用程序的重要工具,主要用于创建动态、交互式的网页服务。...通过深入学习和实践,可以进一步探索更多的高级主题,如RESTful API设计、WebSocket通信、缓存策略、性能优化等。

    1+X Web前端中级样题加知识点整理.zip

    8. **Web性能优化**:包括减少HTTP请求、压缩资源、缓存策略、懒加载、预加载等方法。 9. **Web安全**:了解XSS(跨站脚本攻击)和CSRF(跨站请求伪造)等常见攻击方式及其防御措施。 10. **移动Web开发**:响应式...

    Web环境下使用Starling出现的问题收集整理

    Starling是一个基于Adobe Flash的ActionScript 3库,用于在HTML5 Canvas或WebGL上创建高性能的2D图形,尤其适合游戏开发。本篇文章将针对在Web环境下使用Starling时常见的问题进行收集整理,并提供解决方案。 1. **...

    loadrunner性能测试脚本准备资料整理

    它以其强大的功能、广泛的协议支持和易用性,帮助测试人员模拟大量用户并发行为,从而评估系统在高负载下的性能。本文将深入探讨LoadRunner性能测试脚本的准备过程,旨在为读者提供详尽的知识点指导。 一、...

    Linux系统web服务器LAMP全套源码包整理

    通过深入理解LAMP组件的工作原理和相互配合,开发者不仅可以构建高性能的Web应用,还能掌握服务器管理与维护的核心技能。这个源码包的整理为学习者提供了一个宝贵的实践平台,有助于提升在Linux系统上的Web开发和...

    Html5 快速索引指南

    这份“HTML5快速索引指南”是针对那些希望迅速掌握这一技术的专业人士或初学者设计的,它以简洁、实用的方式整理了HTML5的关键知识点。 一、HTML5的基本结构 HTML5的文档类型声明简化为`&lt;!DOCTYPE html&gt;`,这标志着...

    Web访问特征模型建模[整理].pdf

    综上所述,Web访问特征模型建模是一个多方面的研究领域,涵盖了统计分析、数据建模和网络性能优化等多个层面。通过深入理解这些特征,我们可以设计出更智能的Web缓存策略和预取算法,以适应不断变化的用户行为和网络...

    html5实现股票行情源码

    HTML5的Canvas API可以用于绘制这样的动态图表,提供高性能的图形渲染。 3. **funds-index.htm**: 这个文件可能是基金指数的展示页面,基金指数通常用于衡量基金的整体表现,可能包含HTML5的表格、图表或者其他交互...

Global site tag (gtag.js) - Google Analytics