数码产品性能查询
该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。
在看完这两章内容之后,我意犹未尽,于是乎从网上搜索关键字“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 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文件引入要放在
头部,因为这是HTML渲染必备元素。为了避免阻塞加载,应把脚本放到文档的末尾,而CSS是需要放在头部的!
<link rel="stylesheet" href="common.css">......<script src="example.js"></script>
--避免节点深层级嵌套
深层级嵌套的节点在初始化构建时往往需要更多的内存占用,并且在遍历节点时也会更慢些,这与浏览器构建DOM文档的机制有关。浏览器会把整个HTML文档的结构存储为DOM“树”结构。当文档节点的嵌套层次越深,构建的DOM树层次也会越深。
如下代码,完全能够去掉
<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%24%7Byour%20time%20param%7D.js"></script>//或者这样的写法更优秀:<script src="example.js?time=2014-6-7"></script><script src="example.js?time=%24%7Byour%20time%20param%7D"></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个差不多),多了可能造成不同服务器连接时间差异,反而影响速度。
--避免空链接属性
如这样的设置方式是非常不可取的,即使链接为空,在旧的浏览器也会以固定步骤发送请求信息。
另外也不可取,最好的方式是在链接中加一个空的js代码标签的背景色、宽度和颜色为例。
<iframe id="if"></iframe>document.getElementById("if").setAttribute("src","url");
以上会执行3次重绘,而通过CSS代替javascript多次执行则只进行一次重绘。
<iframe id="if"></iframe>document.getElementById("if").setAttribute("src","url");
避免脚本阻塞加载
当浏览器在解析常规的script标签时,它需要等待script下载完毕,再解析执行,而后续的HTML代码只能等待。CSS文件引入要放在
头部,因为这是HTML渲染必备元素。为了避免阻塞加载,应把脚本放到文档的末尾,而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); }
--避免节点深层级嵌套
深层级嵌套的节点在初始化构建时往往需要更多的内存占用,并且在遍历节点时也会更慢些,这与浏览器构建DOM文档的机制有关。浏览器会把整个HTML文档的结构存储为DOM“树”结构。当文档节点的嵌套层次越深,构建的DOM树层次也会越深。
如下代码,完全能够去掉
// 监视对 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(); } …… }
页面缓存
通常不设置缓存的情况下,每次刷新页面都会重新读取服务器的文件,而如果设置缓存之后,所有文件都可以从本地取得,这样明显极大提高了页面效率。
我们可以通过设置页面头的expires来定义页面过期时间,将过期时间定久一点就达到了“永久”缓存。
前端入门到VUE实战笔记:立即学习
>在学习笔记中,你将探索 前端 的入门与实战技巧!
已抢5911个
抢已抢83543个
抢已抢13561个
抢已抢48002个
抢已抢182609个
抢已抢84054个
抢