AI编程助手
AI免费问答

HTML5性能优化_html/css_WEB-ITnose

  2016-06-24 11:24   1168浏览 原创

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 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实战笔记:立即学习
    >在学习笔记中,你将探索 前端 的入门与实战技巧!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。