您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > javascript

强力推荐几个编写高性能的JavaScript 的小建议

时间:2019-08-26 15:22:30  来源:  作者:



前言

随着计算机硬件的不断升级,开发者越发觉得JAVAScript性能优化的好不好对网页的执行效率影响不明显,所以一些性能方面的知识被很多开发者忽视。但在某些情况下,不优化的JavaScript代码必然会影响用户的体验。因此,即使在当前硬件性能已经大大提升的时代,在编写Javascript代码时,若能遵循Javascript规范和注意一些性能方面的知识,对于提升代码的可维护性和优化性能将大有好处。那么,接下来我们讨论几种能够提高JavaScript性能的方法。

1、js文件加载和执行

(1)将<script>标签放到<body>标签的底部

(2)可以合并多个js文件,减少页面中<script>标签改善性能

(3)使用 defer 属性,加载后续文档元素的过程将和script.js的加载并行进行,但是 script.js的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

(4)使用 async 属性,加载和渲染后续文档元素的过程将和script.js的加载与执行并行进行

(5)动态加载脚本元素,无论在何时启动瞎子,文件的下载和执行过程都不会阻塞页面其它进程

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'file.js';
document.getElementsByTagName('head')[0].AppendChild(script);

2、标识符所在的作用域链的位置越深

标识符所在的作用域链的位置越深,那么它的标识符解析的性能就越慢。所以一个好的性能提升的经验法则是:如果某个跨作用域的值在函数中被引用一次以上,那么就把它存储到局部变量里。

function fun1() { 
// 将全局变量的引用先存储在一个局部变量中,然后使用这个局部变量代替全局变量,从而提高 
// 性能;不然每次(3次)都要遍历整个作用域链找到
document var doc = document; 
 var bd = doc.body; 
 var links = doc.getElementsByTagName('a'); 
 doc.getElementById('btn').onclick = function(){ 
 console.log('btn'); 
 }
}

3、避免过长原型链继承

方法或属性在原型链中存在的位置越深,搜索它的性能也就越慢,所以要避免N多层原型链的写法。

4、对象成员嵌套过深

对象的嵌套成员,对象成员嵌套越深,读取速度也就越慢。所以好的经验法则是:如果在函数中需要多次读取一个对象属性,最佳做法是将该属性值保存在局部变量中,避免多次查找带来的性能开销。

function f() { 
 // 因为在以下函数中需要3次用到DOM对象属性,所以先将它存储在一个局部变量 
 // 中,然后使用这个局部变量代替它进行后续操作,从而提高性能 
var dom = YaHOO.util.Dom; 
if(Dom.hasClass(element,'selected')){ 
 Dom.removeClass(elemet,'selected'); 
}else{ 
 Dom.addClass(elemet,'selected'); 
 }
}

5、DOM操作

用js访问和操作DOM都会带来性能损失,可通过以下几点来减少性能损失:

(1)尽可能减少DOM访问次数;

(2)如果需要多次访问某个DOM节点,请使用局部变量存储它的引用;

(3)小心处理html集合,因为它实时连系着底层文档;我们可以把集合的长度缓存到一个变量中,并在迭代中使用它;

(4)下述情况会发生重排:

  • 添加或删除可见的DOM元素,请参阅JavaScript系统学习DOM系列文章之理解DOM节点关系
  • 元素位置改变;
  • 元素尺寸改变(包括:外边距、内边距、边框厚度、宽度、高度等属性);
  • 内容改变(例如:文本改变或图片被另一个不同尺寸的图片改变);
  • 页面渲染器初始化;
  • 浏览器窗口尺寸改变

可通过以下方式减少重排:

  • 留意上面会导致重排的操作,尽量避免;
  • 获取布局信息的操作会导致强制渲染队列重排,应该尽量避免使用以下获取布局信息的操作方法或属性或者缓存布局信息,例如:offsetTop,offsetLeft,offsetWidthoffsetHeight,``scrollTop,scrollLeft,scrollWidth,scrollHeight,clientTop,clientLeft,clientWidth,clientHeight,getComputedStyle()等;
  • 批量修改样式,推荐修改class来实现,例如使用:
function f() { 
 // 推荐使用以下操作 
 var el1 = document.getElementById('mydiv'); 
 el1.className = 'mydiv'; 
 // 不推荐使用以下操作 
 var el2 = document.getElementById('mydiv'); 
 el2.style.border = '1px'; 
 el2.style.padding = '2px'; 
 el2.style.margin = '3px';
}

.mydiv {
 border: 1px;
 padding: 2px;
 margin: 3px;
}
  • 当需要批量修改DOM时,可以通过以下步骤减少重绘和重排的次数:
  • 使元素脱离文档流(隐藏元素、拷贝元素、DocumentFragment 请参考JavaScript系统学习DOM系列文章之DocumentFragment
  • 对其应用多重改变;
  • 把元素带回文档中
  • 使用事件委托(事件逐层冒泡并能被父级元素捕获,使用事件代理,只需给外层元素绑定一个处理器,就可以处理其子元素上触发的所用事件),因为给DOM元素绑定事件以及浏览器需要跟踪每个事件处理器都需要消耗性能。

6、字符串连接

str += 'one'+'two';
str= str+'one'+'two';

后者方式会比前者少在内存中创建一个临时字符串,所以性能有相应的提升,所以,所以推荐后者的写法。

7、直接使用字面量

创建对象和数组推荐使用字面量,因为这不仅是性能最优也有助于节省代码量。

var obj = { 
 name:'tom', 
 age:15, 
 sex:'男'
}

8、数组长度缓存

如果需要遍历数组,应该先缓存数组长度,将数组长度放入局部变量中,避免多次查询数组长度。

for(let i = 0, len = arr.lenght; i < len; i++) {
 ...
}

9、循环比较

JS提供了三种循环:for(;;)、while()、for(in)。在这三种循环中 for(in)的效率最差,因为它需要查询Hash键,因此应尽量少用for(in)循环,for(;;)、while()循环的性能基本持平。

10、少用eval

尽量少使用eval,每次使用eval需要消耗大量时间,这时候使用JS所支持的闭包可以实现函数模板。

11、字符串转换

当需要将数字转换成字符时,采用如下方式:"" + 1。从性能上来看,将数字转换成字符时,有如下公式:("" +) > String() > .toString() > new String()。String()属于内部函数,所以速度很快。而.toString()要查询原型中的函数,所以速度逊色一些,new String()需要重新创建一个字符串对象,速度最慢。

12、浮点数转换整形

当需要将浮点数转换成整型时,应该使用Math.floor()或者Math.round()。而不是使用parseInt(),该方法用于将字符串转换成数字。而且Math是内部对象,所以Math.floor()其实并没有多少查询方法和调用时间,速度是最快的。

后记

暂时只记录了这么多,大家如果有好的建议,欢迎在评论区备注,我会将大家是建议补充进文章中,方便我们在工作和面试中避免采坑

参考文章:

https://github.com/fengshi123/blog/issues/6



Tags:JavaScript   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1、通过条件判断给变量赋值布尔值的正确姿势// badif (a === &#39;a&#39;) { b = true} else { b = false}// goodb = a === &#39;a&#39;2、在if中判断数组长度不为零...【详细内容】
2021-12-24  Tags: JavaScript  点击:(6)  评论:(0)  加入收藏
给新手朋友分享我收藏的前端必备javascript已经写好的封装好的方法函数,直接可用。方法函数总计:41个;以下给大家介绍有35个,需要整体文档的朋友私信我,1、输入一个值,将其返回数...【详细内容】
2021-12-15  Tags: JavaScript  点击:(20)  评论:(0)  加入收藏
作者:一川来源:前端万有引力 1 写在前面Javascript中的apply、call、bind方法是前端代码开发中相当重要的概念,并且与this的指向密切相关。本篇文章我们将深入探讨这个关键词的...【详细内容】
2021-12-06  Tags: JavaScript  点击:(19)  评论:(0)  加入收藏
概述DOM全称Document Object Model,即文档对象模型。是HTML和XML文档的编程接口,DOM将文档(HTML或XML)描绘成一个多节点构成的结构。使用JavaScript可以改变文档的结构、样式和...【详细内容】
2021-11-16  Tags: JavaScript  点击:(35)  评论:(0)  加入收藏
一、判断是否IE浏览器(支持判断IE11与edge)function IEVersion() {var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串var isIE = userAgent.indexOf("comp...【详细内容】
2021-11-02  Tags: JavaScript  点击:(40)  评论:(0)  加入收藏
Null、Undefined、空检查普通写法: if (username1 !== null || username1 !== undefined || username1 !== &#39;&#39;) { let username = username1; }优化后...【详细内容】
2021-10-28  Tags: JavaScript  点击:(51)  评论:(0)  加入收藏
1、前言async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法。async和await关键字让我们可以用一种更简...【详细内容】
2021-09-17  Tags: JavaScript  点击:(61)  评论:(0)  加入收藏
为什么要使用 debugger这篇文章将介绍如何使用断点来进行 JavaScript 调试。在读这篇文章之前,需要问一个问题:为什么要使用断点来进行调试?我们首先需要认可使用断点的是必要...【详细内容】
2021-08-26  Tags: JavaScript  点击:(66)  评论:(0)  加入收藏
JavaScript 可以做很多好玩的事, 从复杂的框架到处理API,有太多的东西需要学习。但是,它也能让我们只用一行就能做一些了不起的事情。1. 获得一个随机的布尔值(true/false)该函数...【详细内容】
2021-08-19  Tags: JavaScript  点击:(77)  评论:(0)  加入收藏
JavaScript 提供了大量不同的处理数组的方法,这里花几分钟时间介绍 8 个项目中可以用到的数组方法。1. Array.map()使用.map() 方法,可以创建一个基于原始数组的修订版数组。....【详细内容】
2021-08-19  Tags: JavaScript  点击:(95)  评论:(0)  加入收藏
▌简易百科推荐
1、通过条件判断给变量赋值布尔值的正确姿势// badif (a === &#39;a&#39;) { b = true} else { b = false}// goodb = a === &#39;a&#39;2、在if中判断数组长度不为零...【详细内容】
2021-12-24  Mason程    Tags:JavaScript   点击:(6)  评论:(0)  加入收藏
给新手朋友分享我收藏的前端必备javascript已经写好的封装好的方法函数,直接可用。方法函数总计:41个;以下给大家介绍有35个,需要整体文档的朋友私信我,1、输入一个值,将其返回数...【详细内容】
2021-12-15  未来讲IT    Tags:JavaScript   点击:(20)  评论:(0)  加入收藏
1. 检测一个对象是不是纯对象,检测数据类型// 检测数据类型的方法封装(function () { var getProto = Object.getPrototypeOf; // 获取实列的原型对象。 var class2type =...【详细内容】
2021-12-08  前端明明    Tags:js   点击:(23)  评论:(0)  加入收藏
作者:一川来源:前端万有引力 1 写在前面Javascript中的apply、call、bind方法是前端代码开发中相当重要的概念,并且与this的指向密切相关。本篇文章我们将深入探讨这个关键词的...【详细内容】
2021-12-06  Nodejs开发    Tags:Javascript   点击:(19)  评论:(0)  加入收藏
概述DOM全称Document Object Model,即文档对象模型。是HTML和XML文档的编程接口,DOM将文档(HTML或XML)描绘成一个多节点构成的结构。使用JavaScript可以改变文档的结构、样式和...【详细内容】
2021-11-16  海人为记    Tags:DOM模型   点击:(35)  评论:(0)  加入收藏
入口函数 /*js加载完成事件*/ window.onload=function(){ console.log("页面和资源完全加载完毕"); } /*jQuery的ready函数*/ $(document).ready(function(){ co...【详细内容】
2021-11-12  codercyh的开发日记    Tags:jQuery   点击:(36)  评论:(0)  加入收藏
一、判断是否IE浏览器(支持判断IE11与edge)function IEVersion() {var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串var isIE = userAgent.indexOf("comp...【详细内容】
2021-11-02  V面包V    Tags:Javascript   点击:(40)  评论:(0)  加入收藏
Null、Undefined、空检查普通写法: if (username1 !== null || username1 !== undefined || username1 !== &#39;&#39;) { let username = username1; }优化后...【详细内容】
2021-10-28  前端掘金    Tags:JavaScript   点击:(51)  评论:(0)  加入收藏
今天我们将尝试下花 1 分钟的时间简单地了解下什么是 JS 代理对象(proxies)?我们可以这样理解,JS 代理就相当于在对象的外层加了一层拦截,在拦截方法里我们可以自定义一些个性化...【详细内容】
2021-10-18  前端达人    Tags:JS   点击:(51)  评论:(0)  加入收藏
带有多个条件的 if 语句把多个值放在一个数组中,然后调用数组的 includes 方法。// bad if (x === "abc" || x === "def" || x === "ghi" || x === "jkl") { //logic } // be...【详细内容】
2021-09-27  羲和时代    Tags:JS   点击:(58)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条