web移动开发最佳实践之js篇

一、js概述

  js即JavaScript,是被设计用来验证表单、检测浏览器、创建cookies、改进设计以及更多应用的网络脚本语言,它非常容易使用。在web应用中,它是主要的编程语言,主要用途是进行各种逻辑控制行为展现等。对于js的优化,对于整个应用的提升都是非常显著的。

二、使用字面量(literal notation)来声明对象和数组

  创建对象和数组的方法有很多,但是使用字面量是最简单的。传统的方法是使用内建的构造器声明:

//create an object
var obj = new Object();
obj.debug = false;
obj.lang = "en";

//create an array
var arr = new Array("one", "two", "three");

这种方式在技术上是没问题的,但是使用字面量声明会更快而且代码更少

//create an object
var obj = {debug: false, lang: "en"};

//create an array
var arr = ["one", "two", "three"];

三、避免使用全局变量和函数

  即把属性方法都绑定到一个命名空间对象里,这样不仅可以减少命名冲突,而且可以提升程序性能

  当两个区域的代码使用同一个全局变量名作不同用途时,就会产生命名冲突。在JavaScript里,函数外定义的变量或对象都是全局的,随着程序代码和库的增加,命名冲突的概率就越大。如果函数内或其他区域的代码引用了一个特定的全局变量,脚本引擎就必须遍历一遍作用域直到找到这个变量,局部变量则更容易找到。全局变量会在整个脚本的生命周期中存在,但是局部变量会及时被垃圾收集器回收。

例如以下使用全局的声明(不高效):

//define global variables
var lang = "en";
var debug = true;

//define global function
function setLang (arg) {
    lang = arg;
}

使用如下声明则更好

var myApp = {
    lang: "en",
    debug: true,
};

myApp.setLang = function (arg) {
    this.lang = arg;
}

四、高效的使用try catch语句

  你可以使用try-catch语句来拦截程序抛出的错误(在浏览器处理之前),这对于向用户隐藏错误或者为用户定制错误信息是很有用的。

  当try结构中发生错误时,程序会立即停止跳到catch结构(会提供错误对象)中。在catch结构中,错误对象会赋给一个新的变量,新的变量在catch结构中一直存在,直到catch语句结束。创建并处理这个新的运行时变量会影响到程序的性能,在关键功能循环中应避免使用try-catch结构。例如:

var object = [‘foo‘, ‘bar‘], i;
for (i = 0; i < object.length; i++) {
   try {
      // do something
   } catch (e) {
      // handle exception
   }
}

以上这段代码可能会抛出多个错误,这样写可能会更好

var object = [‘foo‘, ‘bar‘], i;
try {
    for (i = 0; i < object.length; i++) {
        // do something
    }
} catch (e) {
    // handle exception
}

五、使用赋值运算来连接字符串

  字符串连接是很常用的操作,也有很多种方式,比如:

//Using the concatenation (+) operator
str = "h" + "e";
//Using the shorthand assigment (+=) operator
str += "l";
//Using string.concat()
str = str.concat("l", "o");
//Using array.join()
str = ["h", "e", "l", "l", "o"].join("");    

如果你执行的连接操作次数较少,那么以上任何一种方式都可以。但是,当执行大量的连接操作时,就需要优化一下了:

//Slower: Concatenating strings with + operator
str += "x" + "y";

以上连接操作比较,它会按以下步骤执行(参见‘编译原理’):

  1. 创建一个临时变量
  2. 连接后的字符串xy被赋给这个临时变量
  3. 临时变量与str的当前值相加
  4. 结果赋给str变量

你可以使用如下的方式避免使用临时变量(减少内存的使用):

str += "x";
str += "y";

六、优化你的循环

  当你使用循环的时候,你可以通过减少每次迭代时工作量来优化循环的整体性能。例如:

for (var i = 0; i < arr.length; i++) {
    // length of arr is recalculated every time
}

在以上代码中,arr.length在每次循环中都被计算了一次,这是不必要的,可以声明一个局部变量len来缓存这个值,就会提高运行速度:

for (var i = 0, len = arr.length; i < len; i++) {
    // cache the length of the array
}

或者为了进一步优化,考虑反向的执行循环(如果不关心数组成员的顺序的话):

for (var i = arr.length; i--;) {
    // in reverse
}

七、避免使用eval()方法

  eval()方法可以执行一段JavaScript代码,应该避免使用的原因:

  • 性能较差,它必须调用编译器来传递其参数,然后执行
  • 安全问题,因为它会执行传递给它的任何代码,所以容易受各种注入攻击,特别是在来源未知的时候
  • 不利于调试,eval的参数是动态产生的,调试起来不方便,可读性也较差
//Incorrect usage: Using eval to set a value
eval("myValue = myObject." + myKey + ";");

//Correct usage: Using subscript notation to set a value
myValue = myObject[myKey];

另外timeout函数中的setTimeout()和setInterval()也可以接受字符串参数,然后执行,因此表现跟eval()一样。应该避免传递字符串,如下:

// Incorrect usage: Passing a string to setInterval()
var oElement = null;
setInterval(‘oElement = document.getElementById("pepe");‘, 0);

// Correct usage: Passing a function to setInterval()
var oElement = null;
setInterval(function() {
    oElement = document.getElementById("pepe");
}, 0);

八、使用事件委托

  在处理DOM事件的时候,你可以仅对一个父元素绑定一个事件而不是每一个子元素。这种技术即事件委托,它利用事件冒泡来分配事件处理程序,可以提高脚本的性能。比如,一个div元素下面有10个按钮,你可以给div绑定一个监听事件,而不是给10个按钮分别绑定一个事件。传统的声明方式:

<a href="javascript:handleClick();">Click</a>
<button id="btn1" onclick="handleClick();">One</button>
<button id="btn2" onclick="handleClick();">Two</button>

为了提高代码的性能,我们可以加一个div父元素,事件会向上冒泡,直到被处理。事件对象是触发事件的元素,我们可以根据它的id属性来判断是哪一个元素触发了事件:

<div id="btngroup">
  <button id="btn1">One</button>
  <button id="btn2">Two</button>
</div>
document.getElementById("btngroup").addEventListener("click", function (event) {
  switch (event.srcElement.id) {  //firefox 下为 event.target.id
  case "btn1":
    handleClick();
    break;
  default:
    handleClick();
  }
}, false); // type, listener, useCapture (true=beginning, false=end)

九、尽量减少DOM操作

  DOM是一个包含了很多信息的复杂的API,因此即使是很小的操作可能会花费较长的时间执行(如果要重绘页面的话)。为了提高程序性能,应尽量减少DOM操作,这里有一些建议:

1.减少DOM的数目

DOM节点的数目会影响与它相关的所有操作,要尽量使DOM树小一些:

  • 避免多余的标记和嵌套的表格
  • 元素数尽量控制在500个以内(document.getElementsByTagName(‘*‘).length)

2.缓存已经访问过的节点

当访问过一个DOM元素后,就应该把它缓存起来,因为你的程序往往要重复访问某个对象的,例如:

for (var i = 0; i < document.images.length; i++) {
    document.images[i].src = "blank.gif";
}

以上例子中,docum.images对象被访问了多次,这并不高效,因为每一次循环中,浏览器都要查找这个元素两次:第一次读取它的长度,第二次改变相应的src值。更好的做法是先把这个对象存储起来:

var imgs = document.images;
for (var i = 0; i < imgs.length; i++) {  //当然也可以把 imgs.length 提前算出来,这里不是重点
    imgs[i].src = "blank.gif";
}

十、减少页面重绘

  在控制DOM元素数目的同时,你还可以通过减少修改元素(减少页面的重绘)的方法来提高性能。重绘有两种方式:repaintreflow

1.repaint,也叫redraw,即改变了元素的视觉效果,但是不影响它的排版(比如改变背景颜色)

2.reflow,会影响部分或者全部页面的排版,浏览器不仅要计算该元素的位置,还要计算它影响到的周围的元素位置

当你要改变页面布局的时候,reflow就发生了,主要有如下情况:

  • 增加或删除DOM节点
  • 改变元素的位置
  • 改变元素的尺寸(如margin,padding,border,font,width,height等)
  • 调整浏览器窗口的尺寸
  • 增加或删除css
  • 改变内容(如用户输入表单)
  • 命中css选择器(如hover)
  • 更改了class属性
  • 利用脚本更改了DOM
  • 检索一个必须被计算的尺寸(如offsetWidth,offsetHeight)
  • 设置了一个css属性

这里有一些减少页面重绘的建议:

css的建议:

  • 改变class属性时应尽量少的影响到周围的元素节点
  • 避免声明多个内联的样式(把多个样式放在一个外部文件里)
  • 有动画的元素使用绝对定位,这样不会影响其他元素
  • 避免使用table来排版,如果需要使用保存数据,那么要固定排版(table-layout:fixed)

js的建议:

  • 缓存计算过的样式
  • 对于固定的样式,改变class的名词而不是样式;对于动态的样式,改变cssText属性:

    // bad - changing the stle - accessing DOM multiple times
    var myElement = document.getElementById(‘mydiv‘);
    myElement.style.borderLeft = ‘2px‘;
    myElement.style.borderRight = ‘3px‘;
    myElement.style.padding = ‘5px‘;
    
    // good - use cssText and modify DOM once
    var myElement = document.getElementById(‘mydiv‘);
    myElement.style.cssText = ‘border-left: 2px; border-right: 3px; padding: 5px;‘;

  • 当你要对一个DOM元素做出很多修改时,可以先进行一些‘预处理’,批量修改后再替换原始的元素

    • 创建一个副本(cloneNode()),对这个副本进行更新,然后替代原来的节点

      // slower - multiple reflows
      var list = [‘foo‘, ‘bar‘, ‘baz‘], elem, contents;
      for (var i = 0; i < list.length; i++) {
          elem = document.createElement(‘div‘);
          content = document.createTextNode(list[i]);
          elem.appendChild(content);
          document.body.appendChild(elem); // multiple reflows
      }
      
      // faster - create a copy
      var orig = document.getElementById(‘container‘),
          clone = orig.cloneNode(true), // create a copy
          list = [‘foo‘, ‘bar‘, ‘baz‘], elem, contents;
      clone.setAttribute(‘width‘, ‘50%‘);

    • 修改一个不可见的元素,可以先让其不可见(display:none),修改完成后,再恢复其可见(display:block),这样就会减少reflow的次数

      // slower
      var subElem = document.createElement(‘div‘),
          elem = document.getElementById(‘animated‘);
      elem.appendChild(subElem);
      elem.style.width = ‘320px‘;
      
      // faster
      var subElem = document.createElement(‘div‘),
          elem = document.getElementById(‘animated‘);
      elem.style.display = ‘none‘; // will not be repainted
      elem.appendChild(subElem);
      elem.style.width = ‘320px‘;
      elem.style.display = ‘block‘;

    • 创建一个文档片段(使用DocumentFragment()),修改完成后,再把它追加到原始文档中

      // slower
      var list = [‘foo‘, ‘bar‘, ‘baz‘], elem, contents;
      for (var i = 0; i < list.length; i++) {
          elem = document.createElement(‘div‘);
          content = document.createTextNode(list[i]);
          elem.appendChild(content);
          document.body.appendChild(elem); // multiple reflows
      }
      
      // faster
      var fragment = document.createDocumentFragment(),
          list = [‘foo‘, ‘bar‘, ‘baz‘], elem, contents;
      for (var i = 0; i < list.length; i++) {
          elem = document.createElement(‘div‘);
          content = document.createTextNode(list[i]);
          fragment.appendChild(content);
      }
      document.body.appendChild(fragment); // one reflow

时间: 2024-12-05 17:02:42

web移动开发最佳实践之js篇的相关文章

web移动开发最佳实践之 css篇

web移动开发最佳实践之 css篇 一.css概述 css即层叠样式表(Cascading Style Sheets),它的作用主要是控制页面元素的样式,包括布局.颜色.字体.字号.空白.边框.属性等等.css的出现使得html的内容和样式分离,极大的提高了工作效率. 目前最新的标准是css3,下面几节将介绍在使用css过程中应遵循的最佳实践方案. 二.使用高效的css选择器 欲创建一个高效的web应用,你要了解浏览器是如何读取你的web页面并呈现出来的.当浏览器读取你的html文档时,它首先对

web移动开发最佳实践之 css篇 ——转

 web移动开发最佳实践之 css篇 一.css概述 css即层叠样式表(Cascading Style Sheets),它的作用主要是控制页面元素的样式,包括布局.颜色.字体.字号.空白.边框.属性等等.css的出现使得html的内容和样式分离,极大的提高了工作效率. 目前最新的标准是css3,下面几节将介绍在使用css过程中应遵循的最佳实践方案. 二.使用高效的css选择器 欲创建一个高效的web应用,你要了解浏览器是如何读取你的web页面并呈现出来的.当浏览器读取你的html文档时,它首先

移动端WEB前端开发最佳实践

移动端WEB前端开发最佳实践 Safari,Android Browser,Chrome都是以WebKit为核心的 移动设备和PC之间的页面现实存在差异(Safari中定义了viewport) 在移动设备和桌面端WEB前端开发中,事件绑定存在差异(移动触点) 页面控件设计存差异(点触不灵敏,虚拟键盘弹出框) 移动设备的网络带宽普遍比PC慢,移动页面要设置更简洁 PC页面兼容移动设备 使用流式布局 借助CSS Media queries(媒体查询)技术 使用合适的图片显示兼容方案 保持页面简洁,不

入门书籍 web前端开发最佳实践

高效web前端开发  book PageSpeed  出自google公司  是一款  免费的工具  性能分析 Timeline网页交互  和渲染  所要花费的时间 Profile谁  可以查看网页cpu以及内存占有的情况报告 Audits  中提供了各种资源及配置的优化建议和未使用的css规则的列表 代码的压缩 文本服务器开启Gzip压缩. UglifyJs  不仅仅是一个压缩工具,同事具有JS语法分析和代码美化工能 图片压缩工具  以在线工具居多  TinyPNG  压缩  PNG格式图片.

&lt;读书笔记&gt;《Web前端开发最佳实践》

P77 P89 CSS Reset P94 给CSS样式定义排序    排序工具:CSScomb P97 什么是CSS的权重?权重是指选择符的优先级 P100 工具:Sass Less P101 框架:YUI.ExtJS P102 hack代码,不易理解且维护困难 P103 条件注释 P104 em px % 2016.3.8 P110 CSS的匹配原理和我们习惯的匹配过程是相反的,它是从右到左进行匹配的. P111 CSS选择器定义的最佳实践(四个避免): 1.* { } 2.referenc

WEB前端开发最佳实践(2)

样式和结构分离 HTML页面链接一个CSS(最优),提高加载速度 HTML内嵌CSS(单一页面最佳,减少加载CSS样式文件的请求数目,加快加载速度 内联CSS样式,可以使用JS动态来统一修改,很少使用,JQ中使用其实现动画效果 在CSS样式文件中引用CSS文件,避免使用 添加JS禁用提示信息 使用noscrpt,HTML4只在body中起作用,HTML5中可以出现在head中,支持HTML,不支持XHTML 最好使用noscript,采用渐进增强的模式,平稳降级 添加必要的meta的标签 met

【WEB前端开发最佳实践系列】JavaScript篇

一.养成良好的编码习惯,提高可维护性 1.避免定义全局变量和函数,解决全局变量而导致的代码"污染"最简单的额方法就是把变量和方法封装在一个变量对象上,使其变成对象的属性: 1 var myCurrentAction = { 2 length : 0 , 3 init : function(){}, 4 action : function(){} 5 } 还可以将全局的变量包含在一个局部作用域中,然后在这个作用域中完成这些变量的定义以及变量使用的逻辑: 1 (function(){ 2

WEB前端开发最佳实践(3)

选择器注意 尽量不使用ID选择器 减少子选择器的层级(less和Sass的滥用) 使用组合CSS类选择器 兼容IE浏览器 兼容旧浏览器的代码,被称为hack代码 熟悉IE浏览器中常见的兼容样式 分离样式兼容代码 em,px,% px:相对尺寸,但由于同环境,又是绝对尺寸 em:应用元素上字体大小的两倍,%:相对于父元素的百分比 尽量设置相对尺寸 只有在可预知元素尺寸的情况下才使用绝对尺寸 使用em设置字体的大小 使用高效的CSS选择器 匹配原理:从右到左 避免使用通配符 避免使用标签和单个属性选

《web前端开发最佳实践》党建 摘要

1. 各种调试工具.ie dev toolbar. chrome developer tools. firebug .fiddler 2. 压缩合并工具 3. fis 4. 性能工具yslow.  pagespeed 5. 压缩 gzip js压缩 uglifyjs. yui compressor.  closoure compiler. webstorm file watcher css 压缩   css compressor 6. 规范 层级id 公开函数首字母大写 $前缀 输入框的tab顺