Home >Web Front-end >HTML Tutorial >Detailed explanation of performance optimization in HTML5

Detailed explanation of performance optimization in HTML5

黄舟
黄舟Original
2017-07-27 09:56:101788browse

HTML5 Performance Optimization

--Reduce redraw

After the HTML page is displayed, dynamically changing page elements or adjusting CSS styles will cause the browser to redraw. , the performance loss directly depends on the scope of dynamic changes: if you only change the color of an element or other information, only the element will be redrawn; if you add or delete nodes or adjust the node position, its sibling nodes will also be redrawn. .

Reducing redrawing does not mean not to redraw, but to pay attention to the redrawing range: ① The deeper the DOM element is changed, the smaller the impact, so try to make deeper node changes; ② How heavy is the weight of some DOM styles? Changes should be merged and modified as much as possible.

Take changing the background color, width and color of an 3499910bf9dac5ae3c52d5ede7383485 tag as an example.


<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>


The above will be redrawn 3 times, but if executed multiple times through CSS instead of javascript, only one redraw will be performed.


<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>

Avoid script blocking loading

When the browser parses regular script tags, it You need to wait for the script to be downloaded before parsing and executing, and the subsequent HTML code can only wait. CSS file introduction should be placed in the 93f0f5c25f18dab9d176bd4f6de5d30e header, because this is a necessary element for HTML rendering. In order to avoid blocking loading, the script should be placed at the end of the document, and the CSS needs to be placed at the head!


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

--Avoid deep-level nesting of nodes

Deep-level nested nodes often require more nodes during initialization and construction memory usage, and will be slower when traversing nodes. This is related to the browser's mechanism for building DOM documents. The browser stores the structure of the entire HTML document as a DOM "tree" structure. When the nesting level of document nodes is deeper, the level of the DOM tree constructed will be deeper.

The following code can completely remove one of the e388a4556c0f65e1904146cc1a846bee or 45a2772a6b6107b401db3c9b82c049c2 tags.


<p>
  <span>
    <label>嵌套</label>
  </span>
</p>


Page Cache

Usually when the cache is not set, the server will be re-read every time the page is refreshed files, and if the cache is set, all files can be obtained locally, which obviously greatly improves page efficiency.

We can define the page expiration time by setting expires in the page header. By setting the expiration time longer, we can achieve "permanent" caching.


<meta http-equiv="expires" content="Sunday 26 October 2099 01:00 GMT" />

Of course, if your project code changes, because the client caches the file, it will not get the latest file, which will inevitably cause a display error. The solution to this problem is to add a timestamp to the linked file. If the timestamp changes, the browser will think it is a new file and will request the latest file from the server.


<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>


Compress merged files

All files related to request data should be compressed as much as possible, such as Javascript files and css Documents and image files, especially image files, can be compressed before use if there is no high-definition requirement.

A small number of large files loads faster than a large number of small files, so sometimes you can consider merging multiple js files and multiple css files together.

In addition to reducing the size of HTML documents, you can also adopt the following methods:

①Delete spaces, blank lines and comments that have no impact on the execution results of HTM documents

②Avoid Table layout

③Use HTML5

--HTML+CSS3+Javascript perform their respective duties

Let the three elements perform their respective duties Make high-performance web pages: HTML is the foundation of the page and the source of content. With it, it can interact with CSS and Javascript; CSS3 can be said to be a master of presentation, and the increasingly powerful CSS can replace Javascript to do many dynamic things such as gradients. , mobile and other dynamic effects; Javascript is the king of dynamic data. Old browsers relied on js to complete the display of dynamic effects, but now CSS can also complete the work of js, so try to leave the work to css, which will achieve better performance . (This is a bit big)

--Image merging to implement CSS Sprites

Image merging is actually to integrate some background images in the web page into one image file. Then use the combination of CSS "background-image", "background-repeat" and "background-position" to position the background. Background-position can use numbers to accurately locate the position of the background image.

If a page needs to use multiple icons, you can merge multiple icons into one image. Then you only need to send an image request once and split the icons through CSS positioning.

--Avoid using Iframe

        使用iframe并不会增加同域名下的并行下载数,浏览器对同域名的连接总是共享浏览器级别的连接池,在页面加载过程中iframe元素还会阻塞父文档onload事件的触发。并且iframe是html标签中最消耗资源的标签,它的开销比p、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个差不多),多了可能造成不同服务器连接时间差异,反而影响速度。

--避免空链接属性

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

        另外9dba6f1f949f5e07bed667bf670fd9c45db79b134e9f6b82c0b36e0489ee08ed也不可取,最好的方式是在链接中加一个空的js代码af60cb7cd5eb3467eaa609628cdd0ba95db79b134e9f6b82c0b36e0489ee08ed

--使用图像的BASE64编码

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

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

--显式设置图片的宽高

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


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

--显式指定文档字符集

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


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

--渐进式增强设计

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

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


<p class="someClass"></p> 
.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机制

When a page is very large and has a lot of content, it can be returned to the page in parts in the form of flush. This can tell the user that I am working and displaying part of the content is much better than waiting for a long time with a blank screen. In Java Web technology, implementing Flush is very simple. Just call the flush method of the HttpServletResponse.getWriter output stream to write the loaded content back to the client.

This method is only suitable for situations where a large amount of data is returned and the request time is extremely long. For regular data, it is best to return all data in normal real-time. This implementation method will actually increase the browser rendering time and the overall user waiting time, but it will be better in terms of user experience.

  • Performance server optimization

--CDN mechanism

The so-called CDN is a A content distribution network that uses intelligent routing and traffic management technology to promptly discover the acceleration node that can provide the fastest response to visitors, and directs the visitor's request to the acceleration node, which provides content services.

To put it in layman’s terms, you purchase a product from a Beijing seller (server) in Chengdu (browser), and the Beijing seller sends the package via express delivery (CDN service). From Beijing to Chengdu, you can walk, take a car, or train. Or airplane, and express delivery using CND will choose direct airplane because this shipping method is the fastest.

Of course there are two things to note when using CDN:

1. CDN acceleration service is very expensive. If you think your website is worthy of acceleration, you can choose to purchase it;

2. CDN is not suitable for local websites. For example, your website is only accessible to a certain area or a local area network, because the regional network is already very close and does not require CDN acceleration.

--Rational use of HTTP protocol

The performance improvement brought by browser caching is well known to everyone, but many people do not know about browser caching Expiration time, cache deletion, which pages can be cached, etc. can all be controlled by our programmers. As long as you are familiar with the HTTP protocol, you can easily control the browser.

Extended reading: In-depth understanding of the HTTP protocol

--Separation of dynamic and static

The so-called separation of dynamic and static is to separate static and dynamic components in Web applications The content is placed on different web servers, and dynamic and static content are processed in a targeted manner to improve performance. We know that if an HTML has multiple domain names, requesting data files will increase.

Tomcat server is relatively weak in handling static and concurrency issues, so the way to separate dynamic and static in advance is generally Apache+Tomcat, Nginx+Tomcat, etc.

Taking Apache+Tomcat as an example, its operating mechanism is: the page request is first sent to Apache, and then Apache analyzes whether the requested information is static or dynamic. Static processing is done locally, and dynamic processing is handed over to Tomcat.

This is actually the prototype of load balancing. This implementation does not require developers to do any special development. An ad9fd35425518ae8aa6a6d6c2800cfa8 can be handed over to the server. As for this file, it is from Apache still gets it from Tomcat, so developers don't need to pay attention at all.

--HTTP persistent connection

Persistent connection (Keep-Alive) is also called a long connection. It is a TCP connection method. The connection will be processed by the browser and Cached by the server, the cached connection is reused the next time you connect to the same server. The statelessness of HTTP means that it does not belong to long connections, but HTTP/1.1 provides support for long connections (but this must rely on both the browser and the server to support the long connection function). The most common example of HTTP long connections is "Breakpoint Download".

The browser adds Connection:Keep-Alive in the header of the request to tell the server "I support long connections. If you support it, just establish a long connection with me." If the server does support long connections, Then add "Connection:Keep-Alive" to the response header to tell the browser "I do support it, so let's establish a long connection." The server can also tell the browser the long connection expiration time through the Keep-Alive:timeout=..., max=... header.

Configuring long connections usually requires server support settings. Test data shows that the performance comparison of using long connections and not using long connections shows that when Tomcat is configured with maxKeepAliveRequests of 50, the efficiency is increased by nearly 5 times. .

--GZIP compression technology

The HTTP protocol supports the GZIP compression format. When the HTML information header returned by the server contains Content-Encoding:gzip, it tells the browser browser, the return data of this response has been compressed into GZIP format. After the browser obtains the data, it must perform a decompression operation, which reduces the pressure on the server to transmit data to a certain extent.

        很多服务器已经支持通过配置来自动将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文件大小。

 

The above is the detailed content of Detailed explanation of performance optimization in HTML5. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn