信息谷 - ICITU

标题: 高性能JavcaScript(二) [打印本页]

作者: sxadmin    时间: 2021-10-25 10:26
标题: 高性能JavcaScript(二)
第五章、字符串和正则表达式

1、字符串连接四种方式:

+

+=

join

concat

合并大量字符串时,IE7及以前版本中,join快于+和+=;在IE8和其他浏览器中+和+=快于其他连接。使用concat烧鳗鱼+和+=,尤其在IE、chrome和opera中。

2、正则表达式优化(需要单独拿出一篇文章详细分析)

正则表达式工作原理:

a、编译

b、设置起始位置;

c、匹配每个正则表达式字元

d、匹配成功或失败

待续。。。

第六章、快速响应的用户界面

1、浏览器UI线程。浏览器限制:调用栈大小和长时间运行脚本限制。限制所有js任务在100ms或是更短的事件内完成。

2、使用定时器让出时间片段。让出UI线程的控制权,使得UI可以更新。

setTimeout():只执行一次

setTimeInterval():周期性重复执行。

都有两个参数,第一个参数为一个JS任务,第二个参数为时间,意味着让js引擎等一段时间后,将JS任务加入到UI队列中(不一定马上执行,这个JS任务会在UI队列中的所有任务执行完毕后才会执行)。

3、使用定时器处理数组代替循环

需满足两个条件:处理过程是否必须同步;数据是否按照顺序处理。

function processArray(items, process, callback){
  var todo = items.concat();
  setTimeout(function(){
    process(todo.shift());
    if(to.length > 0){
      setTimeout(argguments.callee,25);
    }else{
      callback(items);
    }
  },25);
}

processArray()接收三个参数:待处理的数组、对每一个数组项调用的函数和处理完成后运行的回调函数。
4、分割任务

function multistep(steps, args, callback){
  var tasks = steps.concat();
  setTimeout(function(){
    //执行下一个任务
    var task = tasks.shift();
    task.apply(null, args || []));
    //检查是否还有其他任务
    if(tasks.length > 0){
      setTimeout(arguments.callee);
    }else{
      callback();
    }
  },25);
}

5、记录代码运行时间
var start = new Date();
    stop;
someLongProcess();
stop = +new Date();

***********改进***处理数组代替循环*******************
function processArray(items, process, callback){
  var todo = items.concat();
  setTimeout(function(){
    var start = +new Date();

    do{
      process(todo.shift());
    }while(todo.length > 0 && (+new Date() - start < 50));
    if(to.length > 0){
      setTimeout(argguments.callee,25);
    }else{
      callback(items);
    }
  },25);
}
**********************************************************
过度使用定时器会对性能有影响。
6、Web Worker

Web Worker能使代码运行不占用浏览器UI时间。每个Web Worker都在自己的线程中运行代码。每个Web Worker都有自己的全局运行环境,和UI共用一个进程。

Web Worker运行环境:

***一个navigator对象,只包含四个属性,appName、appVersion、userAgent和platform。

***一个location对象(与window.location相同,不过所有属性都是只读的)。

***一个self对象,只想全局worker对象。

***一个importScript()方法,用来jiazaiWorker所用到的外部js文件

***所有ECMAScript对象

***XMLHttpRequest构造器

***setTimeout()和setInterval()

***一个close方法,他能立刻停止Worker运行。

无法从javascript代码中创建它,需要独立创建一个js文件,其中包含需要在Worker中运行的代码。

var worker = new Worker("code.js");

代码一旦执行,将为这个文件创建一个新的线程和一个新的Worker运行环境。该文件会异步下载,指导文件下载并执行完成后才会启动此Worker。
网页代码通过postMessage()方法给Worker传递数据,它接受一个参数:需要传递给Worker的数据。此外,Worker还有一个用来接收信息的onmessage事件处理器。

实例:

<!DOCTYPE html>
<html>
<body>

<p>Count numbers: <output id="result"></output></p>
<button οnclick="startWorker()">Start Worker</button>
<button οnclick="stopWorker()">Stop Worker</button>
<br /><br />

<script>
var w;

function startWorker()
{
if(typeof(Worker)!=="undefined")
{
  if(typeof(w)=="undefined")
    {
    w=new Worker("demo_workers.js");
    }
  w.onmessage = function (event) {
    document.getElementById("result").innerHTML=event.data;
  };
}
else
{
document.getElementById("result").innerHTML="Sorry, your browser
does not support Web Workers...";
}
}

function stopWorker()
{
w.terminate();
}
</script>

</body>
</html>
第七章、ajax

1、五种技术向服务器请求数据:

**XMLHttpRequest(XHR)

**Dynamic script tag insertion

**iframes

**Comet

**Multipart XHR

2、XHR

允许一步发送和接收数据,能精确的控制发送和数据接收,在请求中添加任何头信息和参数,并且读取服务器返回所有的头信息,及响应文本。

缺点:不能用XHR从外部请求数据,而且低版本的IE不支持“流”,也不会提供readystate=3的状态。首选XHR。

3、动态脚本注入

克服XHR的最大限制:不能跨域请求数据。这是一个Hack,不需要实例化一个专用对象,而可使用JavaScript创建一个新的脚本标签,并设置它的src属性为不同域的URL。

但不能设置请求的头信息。参数传递也只能用get方式,不能设置请求的潮湿处理或者重试;事实上,就算请求失败了也不一定知道。必须等大爱所有数据都已返回,才可以

问。不能访问请求的头信息,也不能把整个响应消息作为字符串来处理。

4、MultipartXHR

允许客户端只用一个HTTP请求就可以从服务端向客户端传送多个资源。

实例:将三张图片请求发送到服务器:

var req = new XMLHttpRequest();
var getLatestPachetInterval, lastLength = 0;

req.open("GET","rollup_images.php",true);
req.onreadystatechange = readyStateHandler;
req.send(null);

function readyStateHandler(){

  if(req.readyState == 3 && getLatestPacketInterval == null){
      //开始轮询
    getLatestPacketInterval = window.setInterval(function(){
      getLatestPacket();
    },15);
    if(req.readyState == 4){
        //停止轮询
      clearInterval(getLatestPacketInterval);
        //获取最后一个数据包
      getLatestPacket();
    }
    //splitImages(req.responseTest);
  }
}
function getLatestPacket(){
  var length = req.responseTest.length;
  var packet = req.responseTest.substring(lastLength,length);

  processPacket(packet);
  lastLength = length;
}

function splitImages(imgString){
  var imageData = imgString.split("\u0001");
  var imageElement;
  for(var i = 0, len = imgString.length; i < len;++i){
    imageElement = document.crateElement('img');
    imageElement.src = 'data:image/jpeg:base64,' + imageData[i];
    document.getElementById("container").appendChild(imageElement);
  }
}
/*
*处理图片数据
*/
function handleImageData(data, mineType) {
  var img = document.createElement('img');
  img.src = 'data' + mineType + ';base64,' + data;
  return img;
}
/*
*处理css数据
*/
function handleCss(data) {
  var style = document.createElement('style');
  style.type = 'text/css';
  var node = document.createTextNode(data);
  style.appendChild(node);
  document.getElementByTagName['head'][0].appendChild(node);
}
/*
*处理javascript数据
*/
funtion handleJavaScript(data){
  eval(data);
}

服务端php文件rollup_images.php
<?php
$image = array("a.jpg","b.jpg","c.jpg");
foreach($images as $image){
  $image_fo = fopen($image,"r");
  $image_data = fread($image_fo,filesize($image));
  fclose($image_fo);
    $payloads[] = base64_encode($image_data);
}
$newline  = chr(1);
echo implode($newline,$payloads);
?>
最大的缺点是这种方式获得的资源不能被浏览器缓存;老版本的IE不支持readyState为3的状态和data:url。
在特定的情况下MXHR依然能显著提升页面的整体性能:

**页面包含大量其他地方用不到的资源(因此也无法缓存),尤其是图片

**网站已经在每个页面中使用一个独立打包的js或者css文件以减少http请求;因为对每个页面来说这些文件都是唯一的,所以并不需要从缓存中读取数据,除非重载页面。

5、发送数据的两种技术:

**********XHR************

function xhtPost(url, paras, callback) {
  var req = new XMLHttpRequest();
  req.onerror = function(){
    setTimeout(function(){
      xhrPost(url, params, callback);
    },1000);
  };
  req.onreadystatechange = function(){
    if(req.readyState == 4){
      if(callback && typeof callback == 'function'){
        callback();
      }
    }
  };
  req.open("POST", url, true);
  req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  req.setRequestHeader('Content-Length',params.length);
  req.send(params.join('&'));
}
当使用xhr发送数据时,get方式要更快,post适合发送大量数据。,IE对过长的url长度有限制(2048字符),不能使用过长的get请求。






欢迎光临 信息谷 - ICITU (https://icitu.com/) Powered by Discuz! X3.4