javascript性能优化的几点建议

JavaScript性能优化实战(14):跨端JavaScript性能优化 在当今多端开发时代,JavaScript已广泛应用于移动应用、桌面应用和小程序等环境,但不同平台的运行时环境差异为性能优化带来了挑战。本文重点探讨了React Native的性能优化策略,包括架构认知、组件渲染优化、新架构技术(Fabric与Turbo Modules)以及状态管理优化。通过任务拆分、减少桥接通信、使用memo和PureComponent、优化大列表渲染、避免不必要的重新渲染等方法,可以有效提升React Native应用的性能。此外,新架构中的Fabric和Turbo Modules通过减 阅读详情

原文:javascript性能优化的几点建议

源代码下载地址:http://www.zuidaima.com/share/1575524777233408.htm

(1) 如何加载JS,JS文件应放在什么位置

外部JS的阻塞下载
    所有浏览器在下载JS的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。至到JS下载、解析、执行完毕后才开始继续并行下载其他资源并呈现内容。

    有人会问:为什么JS不能像CSS、image一样并行下载了?这里需要简单介绍一下浏览器构造页面的原理,
当 浏览器从服务器接收到了HTML文档,并把HTML在内存中转换成DOM树,在转换的过程中如果发现某个节点(node)上引用了CSS或 者 IMAGE,就会再发1个request去请求CSS或image,然后继续执行下面的转换,而不需要等待request的返回,当request返 回后,只需要把返回的内容放入到DOM树中对应的位置就OK。但当引用了JS的时候,浏览器发送1个js request就会一直等待该request的 返回。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使 用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改 DOM树,需要重新构建DOM树的情况,所以就会阻塞其他的下载和呈现.

嵌入JS是指直接写在HTML文档中的JS代码。上面说了引用外 部的JS会阻塞其后的资源下载和其后的内容呈现,哪嵌入的JS又会是怎样阻塞的了,拿两段代码运行后,对比。会发现代码1中,在前5秒中页面上是一篇空 白,5秒中后页面全部显示。 代码2中,前5秒中blogjava,csdn等先显示出来,5秒后MSN才显示出来。
    可以看出嵌入JS会阻塞所有内容的呈现,而外部JS只会阻塞其后内容的显示,2种方式都会阻塞其后资源的下载。

    根本原因:因为浏览器会维持html中css和js的顺序,样式表必须在嵌入的JS执行前先加载、解析完。而嵌入的JS会阻塞后面的资源加载,所以就会出现上面CSS阻塞下载的情况。
 
嵌入JS应该放在什么位置

   1、放在底部,虽然放在底部照样会阻塞所有呈现,但不会阻塞资源下载。
   
   2、如果嵌入JS放在head中,请把嵌入JS放在CSS头部。
   
   3、使用defer
   
   4、不要在嵌入的JS中调用运行时间较长的函数,如果一定要用,可以用setTimeout来调用



(2) 为什么要减少请求数,如何减少请求数!

http连接的开销

   相比request头部多余的数据,http连接的开销则更加严重。先看看从用户输入1个URL到下载内容到客户端需要经过哪些阶段:
   1. 域名解析
   2. 开启TCP连接 
   3. 发送请求 
   4. 等待(主要包括网络延迟和服务器处理时间)
   5. 下载资源
   
   可能很多人认为每次请求大部分时间都花在下载资源上,让我们看看blogjava资源下载瀑布图(每种颜色代表的阶段与上面5个阶段对应):

如何减少请求数
  
1、合并文件
     合并文件就是把很多JS文件合并成1个文件,很多CSS文件合并成1个文件,这种方法应该很多人用到过,这里不做详细介绍,
     只推荐1个合并的工具:yuiCompressor 这个工具yahoo提供的。 http://developer.yahoo.com/yui/compressor/
  
2、合并图片
     这是利用css sprite,通过控制背景图片的位置来显示不同的图片。这种技术也是大家都用过的,不做详细介绍,推荐1个在线合并图片的网站:http://csssprites.com/
     
3、把JS、CSS合并到1个文件
     上面第1种方法说的只是把几个JS文件合并成1个JS文件,几个CSS文件合并成1个CSS文件,哪如何把CSS和JS都合并到1个文件中.
     
4、使用Image maps
     Image maps 是把多个图片合并成1个图片,然后使用html中的<map>标签连接图片,并实现点击图片不同的区域执行不同的动作,image map在导航条中比较容易使用到。
     image map的使用方法见: http://www.w3.org/TR/html401/struct/objects.html#h-13.6
  
  5、data嵌入图片


项目中的处理方案:
      
    为了解决上面讨论过的问题,在下写了1个如下的组件,组件中根据我们自己的实际情况使用了文件大小来做为文件的版本号,虽然在文件修改很小(比如把字符a改成b),可能文件大小并没有变,导致版本号也不会变。

但这种机率还是非常低的。当然如果你觉的使用文件修改时间作为版本号适合你,只需要修改一行代码就行,下面看下这个组件的处理流程(本来想用流程图表达,最后还是觉的文字来的直白写):

    1. 程序启动(contextInitialized)
 
    2. 搜索程序目录下的所有merge.txt文件,根据merge.txt文件的配置合并文件, merge.txt文件实例如下:

    # 文件合并配置文件,多个文件以|隔开,以/开头的表示从根目录开始, 
    # 空格之后的文件名表示合并之后的文件名

    # 把1,2,3合并到all文件中
    1.js|2.js|3.js all.js

    #合并CSS
    /css/mian.css|/css/common.css all.css


    3. 搜索程序目录下所有JS,CSS文件(包括合并后的),每个文件都压缩后生成对应的1个新文件。


    4. 搜索程序目录下所有JSP,html文件,把所有JS,css的引用代码改成压缩后并加了版本号的引用。

(3) 减少请求,响应的数据量


如何减少请求、响应的数据量(即在网络中传输的数据量),减少传输的数据量不仅仅可以加快页面加载速度,更可以节约服务器带宽,为你剩不少钱(好像很多机房托管都是按流量算钱的)。

GZIP压缩
    gzip是目前所有浏览器都支持的一种压缩格式,IE6需要SP1及以上才支持(别说你还在用IE5,~_~)。gzip可以说是最方便而且也是最大减少响应数据量的1种方法。

说它方便,是因为你不需要为它写任何额外的代码,只需要在http服务器上加上配置都行了,现在主流的http服务器都支持gzip,各种服务器的配置这里就不一一介绍(其实是我不知道怎么配),

别对图片启用gzip
   在知道了gzip强大的压缩能力后,你是否想对服务器上的所有文件启用gzip了,先让我们看看图片中启用gzip后会是什么情况。

比较适合启用gzip压缩的文件有如下这些:
    1. javascript
    2. CSS
    3. HTML,xml
    4、plain text


别乱用cookie
     现 在几乎没有哪个网站不使用cookie了,可是该怎么使用cookie比较合适了,cookie有几个重要的属性:path(路 径),domain(域),expires(过期时间)。浏览器就是根据这3个属性来判断在发送请求的时候是否需要带上这个cookie。
     cookie使用最好的方式,就是当请求的资源需要cookie的时候才带上该cookie。其他任何请求都不带上cookie。

妙用204状态
    http 中200,404,500状态大家都很清楚,但204状态大家可能用的比较少,204状态是指服务器成功处理了客户端请求,但服务器无返回内容。204是 HTTP中数据量最少的响应状态,204的响应中没有body,而且Content-Length=0。很多人在使用ajax提交一些数据给服务器,而不 需要服务器返回的时候,常常在服务端使用下面的代码:response.getWriter().print(""),这是返回1个空白的页面,是1个 200请求。它还是有body,而且Content-Length不会等于0。其实这个时候你完全可以直接返回1个204状 态 (response.setStatus(204))。


(4) 如何加载google-analytics(或其他第三方)的JS

     很 多网站为了获取用户访问网站的统计信息,使用了google-analytics或其他分析网站(下面的讨论中只提google- analytics, 简称ga)。注册ga后,ga就会生成一段js脚本,很多人直接把这段js复制到<body>的最后面就完事(包 括 博客园、优快云、BlogJava)。可是ga自动生成的这段JS真的就是最合理的吗?
     哪怎么样才算是合理,怎样才是不合理了?因ga只是1个分析工具,它的使用绝对不能影响到我们的程序,如果影响了,则是不合理的。不影响则是合理的。

使用document.write来加载JS,注意了,这样加载js是阻塞加载的,就是这个js没加载完,后面的所有资源和JS都不能下载和执行。可能你会觉的这段代码在body的最后面,后没已经没内容,没什么会阻塞的了。
     还 有一些你忽略了,相信很多人在写JS的时候需要在页面加载完毕后执行一些JS或AJAX,一般写在window.onload 事件,或者写入 jquery的$(document).ready()方法中。这些JS就会被阻塞。如果我们的页面上很多数据在 window.onload中使用 AJAX加载,而偏偏这个时候ga因为某些原因(和谐和谐)不能访问,或者访问很慢的时候。问题就来,我们自己的JS一直在等待ga的JS加载完,只有等 ga的js加载超时后才会执行我们的JS。

(5) 疯狂的HTML压缩

(6) 页面呈现、重绘、回流。

页面呈现流程

     在讨论页面重绘、回流之前。需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程。可能不同的浏览器略微会有些不同。但基本上都是类似的。


    1.  浏 览器把获取到的html代码解析成1个Dom树,html中的每个tag都是Dom树中的1个节点,根节点就是我们常用的document对 象 (<html> tag)。dom树就是我们用firebug或者IE Developer Toolbar等工具看到的html结构, 里面包含了所有的html tag,包括display:none隐藏,还有用JS动态添加的元素等。

     2. 浏览器把所有样式(主要包括css和浏览器的样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式,比如IE会去掉-moz开头的样式,而firefox会去掉_开头的样式。

     3、 dom tree和样式结构体结合后构建呈现树(render tree),render tree有点类似于dom tree,但其实区别有很 大,render tree能识别样式,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如 display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到 render tree中。注 意 visibility:hidden隐藏的元素还是会包含到render tree中的,因为visibility:hidden 会影响布局 (layout),会占有空间。根据css2的标准,render tree中的每个节点都称为box(Box dimensions),box所有属 性:width,height,margin,padding,left,top,border等。

    4. 一旦render tree构建完毕后,浏览器就可以根据render tree来绘制页面了。

回流与重绘

    1. 当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(其实我觉得叫重新布局更简单明了些)。每个页面至少需要一次回流,就是在页面第一次加载的时候。

    2. 当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

  注:从上面可以看出,回流必将引起重绘,而重绘不一定会引起回流。


什么操作会引起重绘、回流
   
    其实任何对render tree中元素的操作都会引起回流或者重绘,比如:

    1. 添加、删除元素(回流+重绘)

    2. 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)

    3. 移动元素,比如改变top,left(jquery的animate方法就是,改变top,left不一定会影响回流),或者移动元素到另外1个父元素中。(重绘+回流)

    4. 对style的操作(对不同的属性操作,影响不一样)

    5. 还有一种是用户的操作,比如改变浏览器大小,改变浏览器的字体大小等(回流+重绘)


如何减少回流、重绘

    减少回流、重绘其实就是需要减少对render tree的操作,并减少对一些style信息的请求,尽量利用好浏览器的优化策略。具体方法有:

    1. 不要1个1个改变元素的样式属性,最好直接改变className,但className是预先定义好的样式,不是动态的,如果你要动态改变一些样式,则使用cssText来改变

2. 让要操作的元素进行"离线处理",处理完后一起更新,这里所谓的"离线处理"即让元素不存在于render tree中,比如:
        a) 使用documentFragment或div等元素进行缓存操作,这个主要用于添加元素的时候,大家应该都用过,就是先把所有要添加到元素添加到1个div(这个div也是新加的),
            最后才把这个div append到body中。
        b) 先display:none 隐藏元素,然后对该元素进行所有的操作,最后再显示该元素。因对display:none的元素进行操作不会引起回流、重绘。所以只要操作只会有2次回流。

   3 不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,就先读取到变量中进行缓存,以后用的时候直接读取变量就可以了

4. 考虑你的操作会影响到render tree中的多少节点以及影响的方式,影响越多,花费肯定就越多。

(6) 了解CSS的查找匹配原理,让CSS更简洁、高效

匹配原理:

     浏览器CSS匹配不是从左到右进行查找,而是从右到左进行查找。比如之前说的 DIV#divBox p span.red{color:red;},浏览器的查找顺序如下:

先查找html中所有class='red'的span元素,找到后,再查找其父辈元素中是否有p元素,再判断p的父元素中是否有id为divBox的div元素,如果都存在则匹配上。

简洁、高效的CSS:
      所谓高效的CSS就是让浏览器在查找style匹配的元素的时候尽量进行少的查找,下面列出一些我们常见的写CSS犯一些低效错误(也是我以前常常犯的错误,还老以为这样写才是高效的):
   
  1.不要在ID选择器前使用标签名
 一般写法:DIV#divBox
 更好写法:#divBox
 解释: 因为ID选择器是唯一的,加上div反而增加不必要的匹配。
  
  2.不要再class选择器前使用标签名
 一般写法:span.red
 更好写法:.red
 解释: 同第一条,但如果你定义了多个.red,而且在不同的元素下是样式不一样,则不能去掉,比如你css文件中定义如下:
     p.red{color:red;}
     span.red{color:#ff00ff}
     如果是这样定义的就不要去掉,去掉后就会混淆,不过建议最好不要这样写
  3.尽量少使用层级关系
 一般写法:#divBox p .red{color:red;}      
 更好写法:.red{..}
  
  4.使用class代替层级关系
 一般写法:#divBox ul li a{display:block;}      

 更好写法:.block{display:block;}

 


(1) 如何加载JS,JS文件应放在什么位置

外部JS的阻塞下载
    所有浏览器在下载JS的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。至到JS下载、解析、执行完毕后才开始继续并行下载其他资源并呈现内容。

    有人会问:为什么JS不能像CSS、image一样并行下载了?这里需要简单介绍一下浏览器构造页面的原理,
当 浏览器从服务器接收到了HTML文档,并把HTML在内存中转换成DOM树,在转换的过程中如果发现某个节点(node)上引用了CSS或 者 IMAGE,就会再发1个request去请求CSS或image,然后继续执行下面的转换,而不需要等待request的返回,当request返 回后,只需要把返回的内容放入到DOM树中对应的位置就OK。但当引用了JS的时候,浏览器发送1个js request就会一直等待该request的 返回。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使 用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改 DOM树,需要重新构建DOM树的情况,所以就会阻塞其他的下载和呈现.

嵌入JS是指直接写在HTML文档中的JS代码。上面说了引用外 部的JS会阻塞其后的资源下载和其后的内容呈现,哪嵌入的JS又会是怎样阻塞的了,拿两段代码运行后,对比。会发现代码1中,在前5秒中页面上是一篇空 白,5秒中后页面全部显示。 代码2中,前5秒中blogjava,csdn等先显示出来,5秒后MSN才显示出来。
    可以看出嵌入JS会阻塞所有内容的呈现,而外部JS只会阻塞其后内容的显示,2种方式都会阻塞其后资源的下载。

    根本原因:因为浏览器会维持html中css和js的顺序,样式表必须在嵌入的JS执行前先加载、解析完。而嵌入的JS会阻塞后面的资源加载,所以就会出现上面CSS阻塞下载的情况。
 
嵌入JS应该放在什么位置

   1、放在底部,虽然放在底部照样会阻塞所有呈现,但不会阻塞资源下载。
   
   2、如果嵌入JS放在head中,请把嵌入JS放在CSS头部。
   
   3、使用defer
   
   4、不要在嵌入的JS中调用运行时间较长的函数,如果一定要用,可以用setTimeout来调用



(2) 为什么要减少请求数,如何减少请求数!

http连接的开销

   相比request头部多余的数据,http连接的开销则更加严重。先看看从用户输入1个URL到下载内容到客户端需要经过哪些阶段:
   1. 域名解析
   2. 开启TCP连接 
   3. 发送请求 
   4. 等待(主要包括网络延迟和服务器处理时间)
   5. 下载资源
   
   可能很多人认为每次请求大部分时间都花在下载资源上,让我们看看blogjava资源下载瀑布图(每种颜色代表的阶段与上面5个阶段对应):

如何减少请求数
  
1、合并文件
     合并文件就是把很多JS文件合并成1个文件,很多CSS文件合并成1个文件,这种方法应该很多人用到过,这里不做详细介绍,
     只推荐1个合并的工具:yuiCompressor 这个工具yahoo提供的。 http://developer.yahoo.com/yui/compressor/
  
2、合并图片
     这是利用css sprite,通过控制背景图片的位置来显示不同的图片。这种技术也是大家都用过的,不做详细介绍,推荐1个在线合并图片的网站:http://csssprites.com/
     
3、把JS、CSS合并到1个文件
     上面第1种方法说的只是把几个JS文件合并成1个JS文件,几个CSS文件合并成1个CSS文件,哪如何把CSS和JS都合并到1个文件中.
     
4、使用Image maps
     Image maps 是把多个图片合并成1个图片,然后使用html中的<map>标签连接图片,并实现点击图片不同的区域执行不同的动作,image map在导航条中比较容易使用到。
     image map的使用方法见: http://www.w3.org/TR/html401/struct/objects.html#h-13.6
  
  5、data嵌入图片


项目中的处理方案:
      
    为了解决上面讨论过的问题,在下写了1个如下的组件,组件中根据我们自己的实际情况使用了文件大小来做为文件的版本号,虽然在文件修改很小(比如把字符a改成b),可能文件大小并没有变,导致版本号也不会变。

但这种机率还是非常低的。当然如果你觉的使用文件修改时间作为版本号适合你,只需要修改一行代码就行,下面看下这个组件的处理流程(本来想用流程图表达,最后还是觉的文字来的直白写):

    1. 程序启动(contextInitialized)
 
    2. 搜索程序目录下的所有merge.txt文件,根据merge.txt文件的配置合并文件, merge.txt文件实例如下:

    # 文件合并配置文件,多个文件以|隔开,以/开头的表示从根目录开始, 
    # 空格之后的文件名表示合并之后的文件名

    # 把1,2,3合并到all文件中
    1.js|2.js|3.js all.js

    #合并CSS
    /css/mian.css|/css/common.css all.css


    3. 搜索程序目录下所有JS,CSS文件(包括合并后的),每个文件都压缩后生成对应的1个新文件。


    4. 搜索程序目录下所有JSP,html文件,把所有JS,css的引用代码改成压缩后并加了版本号的引用。

(3) 减少请求,响应的数据量


如何减少请求、响应的数据量(即在网络中传输的数据量),减少传输的数据量不仅仅可以加快页面加载速度,更可以节约服务器带宽,为你剩不少钱(好像很多机房托管都是按流量算钱的)。

GZIP压缩
    gzip是目前所有浏览器都支持的一种压缩格式,IE6需要SP1及以上才支持(别说你还在用IE5,~_~)。gzip可以说是最方便而且也是最大减少响应数据量的1种方法。

说它方便,是因为你不需要为它写任何额外的代码,只需要在http服务器上加上配置都行了,现在主流的http服务器都支持gzip,各种服务器的配置这里就不一一介绍(其实是我不知道怎么配),

别对图片启用gzip
   在知道了gzip强大的压缩能力后,你是否想对服务器上的所有文件启用gzip了,先让我们看看图片中启用gzip后会是什么情况。

比较适合启用gzip压缩的文件有如下这些:
    1. javascript
    2. CSS
    3. HTML,xml
    4、plain text


别乱用cookie
     现 在几乎没有哪个网站不使用cookie了,可是该怎么使用cookie比较合适了,cookie有几个重要的属性:path(路 径),domain(域),expires(过期时间)。浏览器就是根据这3个属性来判断在发送请求的时候是否需要带上这个cookie。
     cookie使用最好的方式,就是当请求的资源需要cookie的时候才带上该cookie。其他任何请求都不带上cookie。

妙用204状态
    http 中200,404,500状态大家都很清楚,但204状态大家可能用的比较少,204状态是指服务器成功处理了客户端请求,但服务器无返回内容。204是 HTTP中数据量最少的响应状态,204的响应中没有body,而且Content-Length=0。很多人在使用ajax提交一些数据给服务器,而不 需要服务器返回的时候,常常在服务端使用下面的代码:response.getWriter().print(""),这是返回1个空白的页面,是1个 200请求。它还是有body,而且Content-Length不会等于0。其实这个时候你完全可以直接返回1个204状 态 (response.setStatus(204))。


(4) 如何加载google-analytics(或其他第三方)的JS

     很 多网站为了获取用户访问网站的统计信息,使用了google-analytics或其他分析网站(下面的讨论中只提google- analytics, 简称ga)。注册ga后,ga就会生成一段js脚本,很多人直接把这段js复制到<body>的最后面就完事(包 括 博客园、优快云、BlogJava)。可是ga自动生成的这段JS真的就是最合理的吗?
     哪怎么样才算是合理,怎样才是不合理了?因ga只是1个分析工具,它的使用绝对不能影响到我们的程序,如果影响了,则是不合理的。不影响则是合理的。

使用document.write来加载JS,注意了,这样加载js是阻塞加载的,就是这个js没加载完,后面的所有资源和JS都不能下载和执行。可能你会觉的这段代码在body的最后面,后没已经没内容,没什么会阻塞的了。
     还 有一些你忽略了,相信很多人在写JS的时候需要在页面加载完毕后执行一些JS或AJAX,一般写在window.onload 事件,或者写入 jquery的$(document).ready()方法中。这些JS就会被阻塞。如果我们的页面上很多数据在 window.onload中使用 AJAX加载,而偏偏这个时候ga因为某些原因(和谐和谐)不能访问,或者访问很慢的时候。问题就来,我们自己的JS一直在等待ga的JS加载完,只有等 ga的js加载超时后才会执行我们的JS。

(5) 疯狂的HTML压缩

(6) 页面呈现、重绘、回流。

页面呈现流程

     在讨论页面重绘、回流之前。需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程。可能不同的浏览器略微会有些不同。但基本上都是类似的。


    1.  浏 览器把获取到的html代码解析成1个Dom树,html中的每个tag都是Dom树中的1个节点,根节点就是我们常用的document对 象 (<html> tag)。dom树就是我们用firebug或者IE Developer Toolbar等工具看到的html结构, 里面包含了所有的html tag,包括display:none隐藏,还有用JS动态添加的元素等。

     2. 浏览器把所有样式(主要包括css和浏览器的样式设置)解析成样式结构体,在解析的过程中会去掉浏览器不能识别的样式,比如IE会去掉-moz开头的样式,而firefox会去掉_开头的样式。

     3、 dom tree和样式结构体结合后构建呈现树(render tree),render tree有点类似于dom tree,但其实区别有很 大,render tree能识别样式,render tree中每个node都有自己的style,而且render tree不包含隐藏的节点(比如 display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现的,所以就不会包含到 render tree中。注 意 visibility:hidden隐藏的元素还是会包含到render tree中的,因为visibility:hidden 会影响布局 (layout),会占有空间。根据css2的标准,render tree中的每个节点都称为box(Box dimensions),box所有属 性:width,height,margin,padding,left,top,border等。

    4. 一旦render tree构建完毕后,浏览器就可以根据render tree来绘制页面了。

回流与重绘

    1. 当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(其实我觉得叫重新布局更简单明了些)。每个页面至少需要一次回流,就是在页面第一次加载的时候。

    2. 当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

  注:从上面可以看出,回流必将引起重绘,而重绘不一定会引起回流。


什么操作会引起重绘、回流
   
    其实任何对render tree中元素的操作都会引起回流或者重绘,比如:

    1. 添加、删除元素(回流+重绘)

    2. 隐藏元素,display:none(回流+重绘),visibility:hidden(只重绘,不回流)

    3. 移动元素,比如改变top,left(jquery的animate方法就是,改变top,left不一定会影响回流),或者移动元素到另外1个父元素中。(重绘+回流)

    4. 对style的操作(对不同的属性操作,影响不一样)

    5. 还有一种是用户的操作,比如改变浏览器大小,改变浏览器的字体大小等(回流+重绘)


如何减少回流、重绘

    减少回流、重绘其实就是需要减少对render tree的操作,并减少对一些style信息的请求,尽量利用好浏览器的优化策略。具体方法有:

    1. 不要1个1个改变元素的样式属性,最好直接改变className,但className是预先定义好的样式,不是动态的,如果你要动态改变一些样式,则使用cssText来改变

2. 让要操作的元素进行"离线处理",处理完后一起更新,这里所谓的"离线处理"即让元素不存在于render tree中,比如:
        a) 使用documentFragment或div等元素进行缓存操作,这个主要用于添加元素的时候,大家应该都用过,就是先把所有要添加到元素添加到1个div(这个div也是新加的),
            最后才把这个div append到body中。
        b) 先display:none 隐藏元素,然后对该元素进行所有的操作,最后再显示该元素。因对display:none的元素进行操作不会引起回流、重绘。所以只要操作只会有2次回流。

   3 不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,就先读取到变量中进行缓存,以后用的时候直接读取变量就可以了

4. 考虑你的操作会影响到render tree中的多少节点以及影响的方式,影响越多,花费肯定就越多。

(6) 了解CSS的查找匹配原理,让CSS更简洁、高效

匹配原理:

     浏览器CSS匹配不是从左到右进行查找,而是从右到左进行查找。比如之前说的 DIV#divBox p span.red{color:red;},浏览器的查找顺序如下:

先查找html中所有class='red'的span元素,找到后,再查找其父辈元素中是否有p元素,再判断p的父元素中是否有id为divBox的div元素,如果都存在则匹配上。

简洁、高效的CSS:
      所谓高效的CSS就是让浏览器在查找style匹配的元素的时候尽量进行少的查找,下面列出一些我们常见的写CSS犯一些低效错误(也是我以前常常犯的错误,还老以为这样写才是高效的):
   
  1.不要在ID选择器前使用标签名
 一般写法:DIV#divBox
 更好写法:#divBox
 解释: 因为ID选择器是唯一的,加上div反而增加不必要的匹配。
  
  2.不要再class选择器前使用标签名
 一般写法:span.red
 更好写法:.red
 解释: 同第一条,但如果你定义了多个.red,而且在不同的元素下是样式不一样,则不能去掉,比如你css文件中定义如下:
     p.red{color:red;}
     span.red{color:#ff00ff}
     如果是这样定义的就不要去掉,去掉后就会混淆,不过建议最好不要这样写
  3.尽量少使用层级关系
 一般写法:#divBox p .red{color:red;}      
 更好写法:.red{..}
  
  4.使用class代替层级关系
 一般写法:#divBox ul li a{display:block;}      

 更好写法:.block{display:block;}

 

深入掌握JavaScript Node.js开发 本文还有配套的精品资源,点击获取 简介:JavaScript是前端开发中的主导语言,在Node.js环境下的服务器端编程中也显示出重要性。Node.js是一个基于V8引擎的跨平台JavaScript运行环境,具有事件驱动和非阻塞I/O特性,适用于构建高性能的并发服务器。该压缩包文件可能包含有关Node.js核心概念和模块的资料,比如模块化设计、文件系统操作、HTTP服务器创... 阅读详情

相关推荐

人工智能渗透测试:自动化安全评估

渗透测试认证的价值包括提高可信度和技能水平,并帮助客户确保由经过认证的个人对其系统进行全面的手动调查。B2B 交互变得越来越复杂,特别是功能丰富的超级应用程序,需要采取强有力的安全预防措施,而自动化渗透测试应用程序则是一种未被发现的武器。渗透测试中的人工智能通过提高效率、自动收集信息、发现隐藏的漏洞、开发个性化攻击和减少误报来提高 B2B 集成的安全性。这包括风险简报、补救建议和战略建议。渗透测试由五个阶段组成,是网络安全中的关键防御措施,它模拟现实世界的攻击,以识别系统缺陷并在漏洞被利用之前解决它们。

weixin_48967543的博客 2367

【前端词典】8 个提高 JS 性能的方法

前言在一些年以前性能问题,我们前端开发能做的还是很有限的;不过随着 JavaScript 应用越来越复杂,优化 JavaScript 性能的重要性就越发的凸显出来了。这里...

小生方勤 1218

FTViewSE利用VB脚本制作简易日报表

罗克韦尔SE用VB做的简单的报表

z0800656的博客 3024

javascript性能优化

GC算法是什么 GC是一种机制,垃圾回收器完成的具体的工作 工作的内容就是查找垃圾释放空间、回收空间 算法就是工作时查找和回收所遵循的规则 常见的GC算法 引用计数 标记清除 标记整理 分代回收 引用计数算法实现原理 核心思想:设置引用数,判断当前引用数是否为0 引用计数器 引用关系改变时修改引用数字 引用数字为0时立即回收 引用计数算法优点 发现垃圾时立即回收 最大限度减少程序的暂停 引用计数算法的缺点 无法回收循环引用对象 时间开销大 funcion fn() { const

woyebuzhidao321的博客 1188

Linux之GTK系列教程

00、背上行囊1——程序员学习之道 01、背上行囊2——为什么要学习GTK 02、背上行囊3——GUI概述 03、背上行囊4——GTK简介 04、背上行囊5——GTK环境搭建( Linux ) 05、背上行囊6——GTK环境搭建( windows ) 06、踏上旅途1——一个简单的空白窗口 07、踏上旅途2——控件的添加 08、踏上旅途3——布局容器之水平布局 09、踏上旅途

每天积累一点点 2万+

FPGA实战:手把手教你用Verilog驱动4.3寸RGB触摸屏(附完整代码)

本文详细介绍了如何使用Verilog语言在FPGA上驱动4.3寸RGB触摸屏,包括时序设计、信号交互原理及完整代码实现。通过双计数器引擎设计和参数化模块,开发者可以高效构建800*480分辨率的显示驱动,并解决工程实践中的信号完整性和时序收敛问题。

rice5的博客 706

Web前端性能优化的实用技巧汇总

今天小编要跟大家分享关于Web前端性能优化的实用技巧汇总。 javascript在浏览器中运行的性能,可以认为是开发者所面临的最严重的可用性问题。这个问题因为javascript的阻塞性而变得复杂,事实上,多数浏览器使用单一进程来处理用户界面和js脚本执行,所以同一时刻只能做一件事。js执行过程耗时越久,浏览器等待响应的时间越长。 一.提高加载性能 1.IE8,FF,3.5,Safari 4和Chrome都允许并行下载js文件,当script下载资源时不会阻塞其他script的下载。但是js下载仍然会阻塞其

qf2019的博客 770

Tushare Pro的安装使用——“抱歉,您没有访问该接口的权限,权限的具体详情访问:https://tushare.pro/document/1?doc_id=108”问题

最近做毕设关于量化交易的, 因此一直使用tushare作数据源,但是过程中到一些问题,因此这里写篇文章,供大家一起交流下。 Tushare简介 Tushare是一个免费、开源的python财经数据接口包。拥有如股票、基金、期货等行情数据,公司财务、基金经理等基本面数据,以及债券、外汇、行业、大数据、区块链。Tushare返回的绝大部分的数据格式都是pandas DataFrame类型,因此非常方便...

sinat_40875078的博客 1万+

JavaScript中的性能优化

如果我们在服务器上启用了缓存,那么浏览器可以将这些文件存储在本地缓存中,并在下一次访问时使用本地缓存,而不是从服务器重新下载文件。因此,在Web应用程序的开发过程中,必须考虑如何优化JavaScript的性能,以提高应用程序的响应速度和用户体验。同时,我们还将讨论一些常见的性能问题,并提供一些实际应用的优化技巧,以帮助读者更好地理解如何在实际项目中进行JavaScript性能优化。合并是将多个文件合并为一个文件的过程。如果我们将它们合并为一个文件,那么可以减少文件的数量,从而提高Web应用程序的性能。

tyxjolin的专栏 1922

静态分析工具COBOT与Testbed对比

Testbed为规则检查工具的代表,市场占有量非常大,但随着时间的推移,大家从规则匹配转向了用静态分析工具检查Bug,所以规则检查型工具占有量比开始时候已经减少,但仍有一些比较落后的单位还在继续采购此类工具。3、通过对开源工程的测试,进行误漏报率的对比,发现COBOT(库博)的误漏报率相比Testbed较低,因COBOT主打国内市场,在众多军工单位进行大量试用及使用,吸取了众多单位的意见和建议,更加符合国内军工单位的使用习惯及测试要求。4、此外库博在功能上还可以进行计划任务,检测队列,检测并发的功能支持。

chengoodflower的博客 2062

PyTorch实战(12)——图神经网络(Graph Neural Network,GNN)

在本节中,我们首先简要概述了图神经网络 (Graph Neural Network, GNN) 的核心概念与应用,GNN 通过构建计算图分层聚合节点特征,解决了传统神经网络处理图数据时的四大局限:信息深度不足、节点顺序敏感、动态扩展困难和特征稀疏性问题。了解了不同类型的图学习任务(包括节点级、边级和图级三大类)。接着我们研究了几种流行的 GNN 模型,包括:GCN (通过权重共享实现图卷积)、GAT (引入注意力机制区分邻居重要性)和 GraphSAGE (采用随机采样应对大规模图)。

盼小辉丶的博客 3707

JS性能优化

文章目录性能优化介绍内存管理 Memory ManagementJavaScript 中的垃圾回收GC算法介绍引用计数算法实现原理引用计数算法优缺点标记清除算法实现原理标记清除算法优缺点标记整理算法实现原理常见GC算法总结认识V8V8垃圾回收策略V8如何回收新生代对象 性能优化介绍 性能优化是不可避免的 哪些内容可以看做是性能优化 无处不在的前端性能优化 内存管理 垃圾回收与常见 GC 算法 V8 引擎的垃圾回收 Performance 工具 代码优化实例 内存管理 Memory Management

weixin_44581964的博客 1168

052、联发科Imagiq HyperEngine架构适配:天玑9000/9200的ISP多核并行调度与Tuning Toolkit调优案例

摘要: 项目组在适配联发科天玑9200的Imagiq 890 ISP架构时,遇到多摄预览功耗过高、帧率不稳等问题。通过分析多核调度机制,调整辅核QoS通道、优化AI-ISP协同模式(采用FREERUN+运动补偿),并利用Tuning Toolkit的Pipeline Viewer动态分配负载,最终降低功耗30mA、提升画质。关键经验包括:避免多核带宽冲突、合理配置动态时钟策略,以及统一校准参数版本管理。天玑9000/9200的HyperEngine架构需优先理解多核协同逻辑,再针对性调优,否则易引发场景兼容

zzfmlxs的博客 38

javascript性能优化的几点建议 (转)

javascript性能优化的几点建议 (转) (1) 如何加载JS,JS文件应放在什么位置 外部JS的阻塞下载     所有浏览器在下载JS的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。至到JS下载、解析、执行完毕后才开始继续并行下载其他资源并呈现内容。     有人会问:为什么JS不能像CSS、image一样并行下载了?这里需要简单介绍一下浏览器构造页面

haiyanliu119的专栏 606

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

关于 JavaScript 中 this 的详细总结,关于前端性能优化的几点建议

技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。CodeChina开源项目:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】、实战项目、讲解视频,并且后续会持续更新**如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)[外链图片转存中…(img-hPblvZjz-1712062052980)]

m0_60634964的博客 773

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

javascript性能优化的几点建议 (转)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34221036的博客 91

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

JavaScript性能优化几点小窍门

因为这样会大大增加 HTML 文件的大小,无益于代码的压缩和缓存的使用。避免在if和while语句的条件部分进行赋值,如if (a = b),应该写成if (a == b),但是在比较是否相等的情况下,最好使用全等运行符,也就是使用===和!==操作符会相对于==和!和函数类似 ,with语句会创建自己的作用域,因此会增加其中执行的代码的作用域链的长度,由于额外的作用域链的查找,在with语句中执行的代码肯定会比外面执行的代码要慢,在能不使用with语句的时候尽量不要使用with语句。

qq_35876316的博客 1085

无依赖JavaScript插件:PriorityNavigation.js性能优化技巧

PriorityNavigation.js是一款纯JavaScript插件,能在菜单项不适合其父容器时自动移动它们,实现Priority+ Navigation功能且无任何依赖。它为网站导航提供了智能解决方案,尤其适合需要响应式设计的现代网站。 ## 为什么选择PriorityNavigation.js? 这款插件具有多项优势,使其在众多导航解决方案中脱颖而出: - **零依赖**:采用纯J

gitblog_00780的博客 939

Node.js和前端JavaScript有什么区别?

Node.js 和前端 JavaScript 在语法上基本相同,但它们的运行环境、用途、模块系统以及性能优化策略有着显著的区别。前端 JavaScript 专注于浏览器端的交互和界面逻辑,而 Node.js 扩展了 JavaScript 的应用范围,使其能够在服务器端运行,处理文件、网络和数据流等任务。了解这些区别对于选择合适的工具和策略来构建高效、可维护的应用程序至关重要。最后问候亲爱的朋友们,并邀请你们阅读我的全新著作书籍详情。

有我更精彩的博客 1508

JavaScript学习的12条建议

不管是前端开发技术还是后端开发技术,在学习中,我们或多或少都会接触到JavaScript。因此,JavaScript正在成长为开发人员必学的编程语言之一。但互联网技术更新迭代如此快的今天,我们如何才能更好的学习、掌握JavaScript技术呢?下面小编就为大家分享下2015年学习JavaScript的12条建议,希望对大家的学习有帮助。   1. JS应该放到 .js 文件中        

ydmaizi的博客 505

分享几点JS性能优化技巧

转载自品略图书馆http://www.pinlue.com/article/2019/04/1806/188712824359.html 下面是一些关于客户端JS性能的一些优化的小技巧: 1.关于JS的循环,循环是一种常用的流程控制。JS提供了三种循环:for(;;)、while()、for(in)。在这三种循环中for(in)的效率最差,因为它需要查询Hash键,因此应尽量少用for(in)循环,for(;;)、while()循环的性能基本持平。当然,推荐使用for循环,如果循环变量递增或递减..

yihuliunian的博客 204

css js 性能优化,JavaScript前端性能优化

JS性能优化的知识非常庞杂,这里我们来介绍几种常用的性能优化方式。一、JS中的前端性能优化原则:多使用内存、缓存等方法减少CPU计算、减少网络请求二、针对上述两项原则,我们可以从两个方向入手来进行前端的性能优化。1、加载资源优化静态资源的压缩合并我们可以利用webpack等打包工具进行资源的合并与压缩操作,可以大大减小资源的大小,实现页面更快的加载。静态资源缓存当浏览器发送请求时,可以检测该资源的...

weixin_33487811的博客 509

js大量数据计算性能优化

js大量数据计算性能优化测试相关内容1. forEach和for循环2. `indexOf`的效率问题3. 遍历时的浅拷贝4. filter和for的性能比较15. filter和for的性能比较26. 数据去重问题1 (数组去重)7. 数据去重问题2 (数组对象去重) 测试相关内容 浏览器版本:Chrome 89.0+ ECMAScript: ES5+ 测试结果:多次测试随机取值 数据量:100万或1000万 –备注– 由于是做大量数据计算的性能优化,基本不考虑百万级数据以下的计算。 本次测试是为了检

qq_36990322的博客 6593

Three.js性能优化和实践建议

Three.js 是一个功能强大的 3D 引擎,当场景足够大的时候,就会出现卡顿的现象,首先要保证电脑的性能够用,然后看看下面方法,帮助你提高应用的运行效率。

mad970906的博客 2516

JavaScript性能优化实战

本文摘要:性能优化聚焦减少加载时间、内存消耗和提升执行效率,涵盖代码、数据算法、渲染网络等层面。建议减少DOM操作、使用事件委托、避免全局变量、优化数组处理、应用防抖节流等技术。工具方面推荐Chrome DevTools的Performance和Memory面板分析性能瓶颈,Lighthouse审计核心指标。典型场景如电商列表卡顿可通过IntersectionObserver和requestAnimationFrame优化。建议建立性能基准,结合自动化监控持续改进,可实现40%+加载时间减少和60%+JS耗

Made In SQL 1157

2024年前端最全用源码解析Vue2,关于前端性能优化的几点建议

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。前端面试题汇总// 存在,则直接返回现有的观察者实例。

2401_84617772的博客 792
上一篇: 一个站长常用的类似于获取关键词排名的工具类
下一篇: 【maven+junit】 java生成指定为位数的随机密码
springmvc_springdata
博客等级 码龄12年 197粉丝 389原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值