JavaWeb基础(四)JavaScript进阶 上

1、无论当前的js代码是内嵌还是包含在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成,在这个过程中渲染和用户交互是完全被阻塞的。

2、现在浏览器允许script标签允许并行下载JS文件但其他资源下载时仍会阻塞。

3、因为每个script标签初始化下载时会阻塞页面渲染,所以要尽量减少script标签的数量并将脚本放在body标签结束前

如:

<script type="text/javascript" src="https://lpzz.me?xxx1.js&xxx2.js"></script>

4、尽管单个较大的js文件只产生一次http请求,却会死锁浏览器一大段时间,所以要向页面逐步加载js文件,defer同步确保执行顺序async异步执行,非按顺序

如:

<script type="text/javascript" src="xxx1.js" defer></script>

5、动态脚本元素无论在何时启动下载,文件的下载和执行过程不会阻塞页面其他进程。

var script=document.creatElement("script");

script.type="text/javascript";

script.src="xxx.js";

document.getElementByTagName("head")[0].appendChild(script);

兼容写法:

//url:js文件;callback:完成加载后的回调函数
function loadScript(url,callback){
  var script=document.createElement("script");
  script.type="text/javascript";
  if(script.readyState){
    script.onreadstatechange=function(){
      if(script.readyState=="loaded"||script.readyState=="complete"){
        script.onreadystatechange=null;
        callback();
      }
    };
  }else{
  script.onload=function(){
    calllback();
    };
  }
  script.src=url;
  document.getElementsByTagName("head")[0].appendChild(script);
}
//如:确保加载顺序
loadScript("xxx1.js",function(){
  loadScript("xxx2.js",function(){
    loadScript("xxx3.js",function(){
      alert("全部加载完毕!");
    });
  });
});

6、XHR【XMLHttpRequest】对象也可以获取脚本并注入页面,可以下载但不立即执行,但文件须与请求的页面出于相同的域,不能从CDN下载,大型web应用通常不采用此技术。

7、大量添加js代码时推荐无阻塞模式做法:先添加动态加载所需要的代码,尽量精简,再加载初始化页面所需要的剩下的代码。

8、尽量使用字面变量和局部变量,减少数组项和对象成员的使用

9、在执行环境的作用域链中,一个标识符所存的位置越深,读写速度越慢,如果某个跨作用域的值在函数中被引用一次以上,就考虑把它存在局部变量里

10、with语句,try-catch中的catch子句和包含eval的函数都被认为是动态作用域,无法通过静态分析检测出来,经过优化的js引擎,尝试通过分析代码来确定哪些变量可以在特定时候被访问,但当涉及动态作用域时,这种优化方式就失效了。

11、使用闭包可能导致性能问题。

12、js中的对象是基于原型的,一旦创建了一个内置对象的实例,就会拥有一个Object实例作为原型,即对象有两种成员类型:实例成员和原型对象。原型链中位置越深,找到它越慢,性能消耗越大。

13、点操作符越多,嵌套越深,读取也越慢。不要在同一个函数中查找同一个对象成员,除非它的值改变了。

14、DOM天生就慢,运算尽量不要放在这一部分,如:

//优化前:
function innerHTMLLoop(){
  for(var count = 0; count < 15000; count++){
    document.getElementById('here').innerHTML += 'a';
}
}
//优化后:
function innerHTMLLoop2(){
  var content = ' ';
  for(var count = 0; count < 15000; count++){
    content +='a';
}
document.getElementById('here').innerHTML += content;
}

15、在对性能有苛刻要求时一般使用innerHTML而不是DOM方法,但大多数日常操作相差不大

​
//使用innerHTML生成1000行2列的表格,第一列显示行数,第二列奇列显示yes偶列显示no
function tableTnnerHTML(){
  var i,h=['<table border="1" width="100%">'];
  h.push('<thead>');
  h.push('<tr><th>id<\/th><th>yes?<\/th><\/tr>');
  h.push('<\/thead>');
  h.push('<tbody>');
  for(var i=1;i<=1000;i++){
    h.push('<tr><td>');
    h.pust(i);
    h.push('<\/td><td>');
    h.push(i%2?'yes':'no');//有余数是yes,没余数是no
    h.push('<\/td>');
    h.push('<\/tr>');
  }
  h.push('<\/tbody>');
  h.push('<\/table>');
  
  documentElementById('here').innerHTML=h.join('');
};

​
//使用DOM方法生成1000行2列的表格,第一列是一个以i命名的链接,第二列是一个链接列表
function tableDOM(){

  var i,table,thead,tbody,tr,th,td,a,ul,li;

  thead=document.createElement('thead');
  tr=document.createElement('tr');
  th=document.createElement('th');
  th.appendChild(document.createTextNode('URL'));
  tr.appendChild(th);//
  th=document.createElement('th');
  th.appendChild(document.createTextNode('ACTION'));
  tr.appendChild(th);//
  thead.appendChild(tr);

  tbody=document.createElement('tbody');
  for(i=1;i<=1000;i++){
    tr=document.createElement('tr');

    a=document.createElement('a');
    a.setAttribute('href','https://lpzz.me/'+i+'.html');
    a.appendChild(document.createTextNode('https://lpzz.me/'+i+'.html'));

    td=document.createElement('td');
    td.appendChild(a);
    tr.appendChild(td);
    
    ul=document.createElement('ul');

    a=document.createElement('a');
    a.setAttribute('href','https://lpzz.me/edit.html?id='+i);
    a.appendChild(document.createTextNode('edit'));
    li=document.createElement('li');
    li.appendChild(a);
    ul.appendChild(li);

    a=document.createElement('a');
    a.setAttribute('href','https://lpzz.me/delete.html?id='+i);
    a.appendChild(document.createTextNode('delete'));
    li=document.createElement('li');
    li.appendChild(a);
    ul.appendChild(li);
     
    td=document.createElement('td');
    td.appendChild(ul);
    tr.appendChild(td);

    tbody.apppendChild(tr);
    
  }
  
  table=document.createElement('table');
  table.setAttribute('border',1);
  table.setAttribute('width','100%');
  table.appendChild(thead);
  table.appendChild(tbody);

document.getElementById('here').appendChild(table);
};

16、DOM更新还可以采用节点克隆的方法,e.cloneNode()而不是document.createElement()。

17、HTML集合包括document.image/links/forms/forms[0]【第一个表单】以及document.getElementsByName('')/getElementsByClassName('')/getElementsByTagName('')/getElementsByName('')。在需要对同一个集合多次遍历操作时,建议将一个集合复制到一个数组,并使用局部变量存储集合属性。同时,nextSibling【返回相邻元素】在某些条件下要比childNodes【返回集合】快。

//nextSubling
function testNextSubling(){
  var e=document.getElementById('mydiv'),
      ch=e.firstChild,
      name='';
  do{
     name=ch.nodeName;
  }while(ch=ch.nextSibling);

  return name;
};

//childNodes
function testChildNodes(){
  var e=document.getElementById('mydiv'),
      ch=e.childNodes,
      len=ch.length,//务必缓存属性,防止迭代更新
      name='';
  for(var count=0;count<len;count++){
    name=ch[count].nodeName;
  }

  return name;
};

18、使用CSS选择器来定位节点,如:document.querySelectorAll("#menu a");或者document.querySelectorAll(".claname");

19、浏览器下载完页面所有的组件之后,会解析并生成两个内部数据结构,dom树【页面结构】渲染树【dom节点如何显示】,一旦两个树构建完成就开始绘制页面元素。当dom变化影响了元素的集合属性,浏览器会使渲染树受到影响的部分失效并重新构造渲染树【重排】,浏览器重新绘制受到影响的部分到屏幕【重绘】,所以要尽量减少这类过程的发生。

20、合并多次DOM对样式的修改,再一次性处理掉

var e=documment.getElementById('mydiv');
e.style.cssText='border-left:1px;padding:5px;';//覆盖
e.style.cssText+=';border-right:1px;';

21、尽量减少布局信息的获取次数

22、不要大量使用:hover

23、多使用事件委托技术

24、元素属性值修改更新减少重排的优化方法。如:

var data=[
  {
    "url":"xx1.html",
    "name":"xxx1"
  },{
    "url":"xx2.html",
    "name":"xxx2"
  }
];

//添加数据
function appendDataToElement(appendElement,data){
  var a,li;
  for(var i=0,max=data.length;i<max;i++){
    a=document.createElement('a');
    a.href=data[i].url;
    a.appendChild(document.createTextNode(data[i].name));
    li=document.createElement('li');
    li.appendChild(a);

  appendElement.appendChild(li);
  }
};

//调用方法1
var ul=document.getElementById('mylist');
ul.style.display="none";
appendDataToElement(ul,data);
ul.style.display="block";

//调用方法2
var fragment=documment.createDocumentFragment();
appendDataToElement(fragment,data);
document.getElementById('mylist').appendChild(fragment);

//调用方法3
var old=document.getElementById('mylist');
var clone=old.cloneNode(true);
appendDataToElement(clone,data);
old.parentNode.replaceChild(clone,old);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值