xml地图|网站地图|网站标签 [设为首页] [加入收藏]

正规赌博十大app排名

当前位置:网上十大正规赌博平台 > 正规赌博十大app排名 > Chrome开发者工具不完全指南,使用Canvas实时处理

Chrome开发者工具不完全指南,使用Canvas实时处理

来源:http://www.nb-machinery.com 作者:网上十大正规赌博平台 时间:2019-10-04 14:40

Chrome开发者工具不完全指南:(三、性能篇)

2015/06/29 · HTML5 · 2 评论 · Chrome

原文出处: 卖烧烤夫斯基   

卤煮在前面已经向大家介绍了Chrome开发者工具的一些功能面板,其中包括ElementsNetworkResources基础功能部分和Sources进阶功能部分,对于一般的网站项目来说,其实就是需要这几个面板功能就可以了(再加上console面板这个万精油)。它们的作用大多数情况下是帮助你进行功能开发的。然而在你开发应用级别的网站项目的时候,随着代码的增加,功能的增加,性能会逐渐成为你需要关注的部分。那么网站的性能问题具体是指什么呢?在卤煮看来,一个网站的性能主要关乎两项,一是加载性能、二是执行性能。第一项可以利用Network来分析,我以后会再次写一篇关于它的文章分享卤煮的提高加载速度的经验,不过在此之前,我强烈推荐你去阅读《web高性能开发指南》这本书中的十四条黄金建议,这是我阅读过的最精华的书籍之一,虽然只有短短的一百多页,但对你的帮助确实无法估量的。而第二项性能问题就体现在内存泄露上,这也是我们这篇文章探讨的问题——通过Timeline来分析你的网站内存泄露。

虽然浏览器日新月异,每一次网站版本的更新就意味着JavaScript、css的速度更加快速,然而作为一名前端人员,是很有必要去发现项目中的性能的鸡肋的。在众多性能优化中,内存泄露相比于其他性能缺陷(网络加载)不容易发现和解决,因为内存泄露设计到浏览器处理内存的一些机制并且同时涉及到到你的编写的代码质量。在一些小的项目中,当内存泄露还不足以让你重视,但随着项目复杂度的增加,内存问题就会暴露出来。首先内存占有过多导致你的网站响应速度(非ajax)变得慢,就感觉自己的网页卡死了一样;然后你会看到任务管理器的内存占用率飙升;到最后电脑感觉死了机一样。这种情况在小内存的设备上情况会更加严重。所以,找到内存泄露并且解决它是处理这类问题的关键。

在本文中,卤煮会通过个人和官方的例子,帮助诸位理解Timeline的使用方法和分析数据的方法。首先我们依然为该面板区分为四个区域,然后对它们里面的各个功能进行逐一介绍:

图片 1

虽然Timeline在执行它的任务时会显得花花绿绿让人眼花缭乱,不过不用担心,卤煮用一句话概括它的功能就是:描述你的网站在某些时候做的事情和呈现出的状态。我们看下区域1中的功能先:

图片 2

在区域1主题是一个从左到右的时间轴,在运行时它里面会呈现出各种颜色块(下文中会介绍)。顶部有一条工具栏,从左到右,一次表示:

1、开始运行Timeline检测网页。点亮圆点,Timline开始监听工作,在此熄灭圆点,Timeline展示出监听阶段网站的执行状态。

2、清除所有的监听信息。将Timeline复原。

3、查找和过滤监控信息。点击会弹出一个小框框,里面可以搜索或者显示隐藏你要找的信息。

4、手动回收你网站内内存垃圾。

5、View:监控信息的展示方式,目前有两种,柱状图和条状图,在展示的事例中,卤煮默认选择条状图。

6、在侦听过程中希望抓取的信息,js堆栈、内存、绘图等。。。。

区域2是区域1的完全版,虽然他们都是展示的信息视图,在在区域2种,图示会变得更加详细,更加精准。一般我们查看监控视图都在区域2种进行。

区域3是展示的是一些内存信息,总共会有四条曲线的变化。它们对应表示如下图所示:

图片 3

区域4中展示的是在区域2种某种行为的详细信息和图表信息。

在对功能做了简单的介绍之后我们用一个测试用例来了解一下Timeline的具体用法。

XHTML

<!DOCTYPE html> <html> <head> <title></title> <style type="text/css"> div{ height: 20px; widows: 20px; font-size: 26px; font-weight: bold; } </style> </head> <body> <div id="div1"> HELLO WORLD0 </div> <div id="div2"> HELLO WORLD2 </div> <div id="div3"> HELLO WORLD3 </div> <div id="div4"> HELLO WORLD4 </div> <div id="div5"> HELLO WORLD5 </div> <div id="div6"> HELLO WORLD6 </div> <div id="div7"> HELLO WORLD7 </div> <button id="btn">click me</button> <script type="text/javascript"> var k = 0; function x() { if(k >= 7) return; document.getElementById('div' ( k)).innerHTML = 'hello world' } document.getElementById('btn').addEventListener('click', x); </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        div{
            height: 20px;
            widows: 20px;
            font-size: 26px;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div id="div1">
        HELLO WORLD0
    </div>
    <div id="div2">
        HELLO WORLD2
    </div>
    <div id="div3">
        HELLO WORLD3
    </div>
    <div id="div4">
        HELLO WORLD4
    </div>
    <div id="div5">
        HELLO WORLD5
    </div>
    <div id="div6">
        HELLO WORLD6
    </div>
    <div id="div7">
        HELLO WORLD7
    </div>
    <button id="btn">click me</button>
    <script type="text/javascript">
        var k = 0;
        function x() {
            if(k >= 7) return;
            document.getElementById('div' ( k)).innerHTML = 'hello world'
        }
        document.getElementById('btn').addEventListener('click', x);
    
    </script>
</body>
</html>

新建一个html项目,然后再Chrome中打开它,接着按F12切换到开发者模式,选择Timeline面板,点亮区域1左上角的那个小圆圈,你可以看到它变成了红色,然后开始操作界面。连续按下button执行我们的js程序,等待所有div的内容都变成hello world的时候再次点击小圆圈,熄灭它,这时候你就可以看到Timeline中的图表信息了,如下图所示:

图片 4

在区域1中,左下角有一组数字2.0MB-2.1MB,它的意思是在你刚刚操作界面这段时间内,内存增长了0.1MB。底部那块浅蓝色的区域是内存变化的示意图。从左到右,我们可以看到刚刚浏览器监听了4000ms左右的行为动作,从0~4000ms内区域1中列出了所有的状态。接下来我们来仔细分析一下这些状态的具体信息。在区域2种,滚动鼠标的滚轮,你会看到时间轴会放大缩小,现在我们随着滚轮不断缩小时间轴的范围,我们可以看到一些各个颜色的横条:

图片 5

在操作界面时,我们点击了一次button,它耗费了大约1ms的时间完成了从响应事件到重绘节目的一些列动作,上图就是在789.6ms-790.6ms中完成的这次click事件所发生的浏览器行为,其他的事件行为你同样可以通过滑动滑轮缩小区域来观察他们的情况。在区域2种,每一种颜色的横条其实都代表了它自己的独特的意义:

图片 6

每次点击都回到了上面的图一样执行若干事件,所以我们操作界面时发生的事情可以做一个大致的了解,我们滑动滚轮把时间轴恢复到原始尺寸做个总体分析:

图片 7

可以看到,每一次点击事件都伴随着一些列的变化:html的重新渲染,界面重新布局,视图重绘。很多情况下,每个事件的发生都会引起一系列的变化。在区域2种,我们可以通过点击某一个横条,然后在区域4种更加详细地观察它的具体信息。我们以执行函数x为例观察它的执行期的状态。

图片 8

随着在事件发生的,除了dom的渲染和绘制等事件的发生之外,相应地内存也会发生变化,而这种变化我们可以从区域3种看到:

图片 9

在上文中已经向大家做过区域3的介绍,我们可以看到js堆在视图中不断地再增长,这时因为由事件导致的界面绘制和dom重新渲染会导致内存的增加,所以每一次点击,导致了内存相应地增长。同样的,如果区域3种其他曲线的变化会引起蓝色线条的变化,这是因为其他(绿色代表的dom节点数、黄色代表的事件数)也会占有内存。因此,你可以通过蓝色曲线的变化形势来确定其他个数的变化,当然最直观的方式就是观察括号中的数字变化。js内存的变化曲线是比较复杂的,里面参杂了很多因素。我们所列出来的例子实际上是很简单的。目前相信你对Timeline的使用有了一定的认识,下面我们通过一些Google浏览器官方的实例来更好的了解它的作用(因为观看示例都必须FQ,所以卤煮把js代码copy出来,至于简单的html代码你可以自己写。如果可以FQ的同学就无所谓了!)

(官方测试用例一) 查看内存增长,代码如下:

JavaScript

var x = []; function createSomeNodes() { var div, i = 100, frag = document.createDocumentFragment(); for (;i > 0; i--) { div = document.createElement("div"); div.appendChild(document.createTextNode(i

  • " - " new Date().toTimeString())); frag.appendChild(div); } document.getElementById("nodes").appendChild(frag); } function grow() { x.push(new Array(1000000).join('x')); createSomeNodes();//不停地在界面创建div元素 setTimeout(grow,1000); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var x = [];
 
function createSomeNodes() {
    var div,
        i = 100,
        frag = document.createDocumentFragment();
    for (;i > 0; i--) {
        div = document.createElement("div");
        div.appendChild(document.createTextNode(i " - " new Date().toTimeString()));
        frag.appendChild(div);
    }
    document.getElementById("nodes").appendChild(frag);
}
function grow() {
    x.push(new Array(1000000).join('x'));
    createSomeNodes();//不停地在界面创建div元素
    setTimeout(grow,1000);
}

通过多次执行grow函数,我们在Timeline中看到了一张内存变化的图:

图片 10

通过上图可以看出js堆随着dom节点增加而增长,通过点击区域1中顶部的垃圾箱,可以手动回收一些内存。正常的内存分析图示锯齿形状(高低起伏,最终回归于初始阶段的水平位置)而不是像上图那样阶梯式增长,如果你看到蓝色线条没有回落的情况,并且DOM节点数没有返回到开始时的数目,你就可以怀疑有内存泄露了。

下面是一个用异常手段展示的正常例子,说明了内存被创建了又如何被回收。你可以看到曲线是锯齿型的上下起伏状态,在最后js内存回到了初始的状态。(官方示例二)   js代码如下:

JavaScript

var intervalId = null, params; function createChunks() { var div, foo, i, str; for (i = 0; i < 20; i ) { div = document.createElement("div"); str = new Array(1000000).join('x'); foo = { str: str, div: div }; div.foo = foo; } } function start() { if (intervalId) { return; } intervalId = setInterval(createChunks, 1000); } function stop() { if (intervalId) { clearInterval(intervalId); } intervalId = null; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var intervalId = null, params;
 
function createChunks() {
    var div, foo, i, str;
    for (i = 0; i < 20; i ) {
        div = document.createElement("div");
        str = new Array(1000000).join('x');
        foo = {
            str: str,
            div: div
        };
        div.foo = foo;
    }
}
 
function start() {
    if (intervalId) {
        return;
    }
    intervalId = setInterval(createChunks, 1000);
}
 
function stop() {
    if (intervalId) {
        clearInterval(intervalId);
    }
    intervalId = null;
}

执行start函数若干次,然后执行stop函数,可以生成一张内存剧烈变化的图:

图片 11

还有很多官方实例,你可以通过它们来观察各种情况下内存的变化曲线,在这里我们不一一列出。在这里卤煮选择试图的形式是条状图,你可以在区域1中选择其他的显示方式,这个全靠个人的爱好了。总而言之,Timeline可以帮助我们分析内存变化状态(Timeline直译就是时间轴的意思吧),通过对它的观察来确定我的项目是否存在着内存泄露以及是什么地方引起的泄露。图表在展示上虽然很直观但是缺少数字的精确,通过示图曲线的变化我们可以了解浏览器上发生的事件,最主要的是了解内存变化的趋势。而如果你希望进一步分析这些内存状态,那么接下来你就可以打开Profiles来干活了。这将是我们这个系列的下一篇文章要介绍的。

1 赞 9 收藏 2 评论

图片 12

七、window.requestAnimationFrame()

有一些JavaScript方法可以调节重新渲染,大幅提高网页性能。

其中最重要的,就是 window.requestAnimationFrame() 方法。它可以将某些代码放到下一次重新渲染时执行。

JavaScript

function doubleHeight(element) { var currentHeight = element.clientHeight; element.style.height = (currentHeight * 2) 'px'; } elements.forEach(doubleHeight);

1
2
3
4
5
function doubleHeight(element) {
  var currentHeight = element.clientHeight;
  element.style.height = (currentHeight * 2) 'px';
}
elements.forEach(doubleHeight);

上面的代码使用循环操作,将每个元素的高度都增加一倍。可是,每次循环都是,读操作后面跟着一个写操作。这会在短时间内触发大量的重新渲染,显然对于网页性能很不利。

我们可以使用window.requestAnimationFrame(),让读操作和写操作分离,把所有的写操作放到下一次重新渲染。

JavaScript

function doubleHeight(element) { var currentHeight = element.clientHeight; window.requestAnimationFrame(function () { element.style.height = (currentHeight * 2) 'px'; }); } elements.forEach(doubleHeight);

1
2
3
4
5
6
7
function doubleHeight(element) {
  var currentHeight = element.clientHeight;
  window.requestAnimationFrame(function () {
    element.style.height = (currentHeight * 2) 'px';
  });
}
elements.forEach(doubleHeight);

页面滚动事件(scroll)的监听函数,就很适合用 window.requestAnimationFrame() ,推迟到下一次重新渲染。

JavaScript

$(window).on('scroll', function() { window.requestAnimationFrame(scrollHandler); });

1
2
3
$(window).on('scroll', function() {
   window.requestAnimationFrame(scrollHandler);
});

当然,最适用的场合还是网页动画。下面是一个旋转动画的例子,元素每一帧旋转1度。

JavaScript

var rAF = window.requestAnimationFrame; var degrees = 0; function update() { div.style.transform = "rotate(" degrees "deg)"; console.log('updated to degrees ' degrees); degrees = degrees 1; rAF(update); } rAF(update);

1
2
3
4
5
6
7
8
9
10
var rAF = window.requestAnimationFrame;
 
var degrees = 0;
function update() {
  div.style.transform = "rotate(" degrees "deg)";
  console.log('updated to degrees ' degrees);
  degrees = degrees 1;
  rAF(update);
}
rAF(update);

关于作者:cucr

图片 13

新浪微博:@hop_ping 个人主页 · 我的文章 · 17

图片 14

五、刷新率

很多时候,密集的重新渲染是无法避免的,比如scroll事件的回调函数和网页动画。

网页动画的每一帧(frame)都是一次重新渲染。每秒低于24帧的动画,人眼就能感受到停顿。一般的网页动画,需要达到每秒30帧到60帧的频率,才能比较流畅。如果能达到每秒70帧甚至80帧,就会极其流畅。

图片 15

大多数显示器的刷新频率是60Hz,为了与系统一致,以及节省电力,浏览器会自动按照这个频率,刷新动画(如果可以做到的话)。

图片 16

所以,如果网页动画能够做到每秒60帧,就会跟显示器同步刷新,达到最佳的视觉效果。这意味着,一秒之内进行60次重新渲染,每次重新渲染的时间不能超过16.66毫秒。

图片 17

一秒之间能够完成多少次重新渲染,这个指标就被称为”刷新率”,英文为FPS(frame per second)。60次重新渲染,就是60FPS。

初始化chroma-key

doLoad()方法在XHTML文档初始加载时调用。这个方法的作用是为chroma-key处理代码准备所需的变量,设置一个事件侦听器,当用户开始播放视频时我们能检测到。

JavaScript

doLoad: function() { this.video = document.getElementById("video"); this.c1 = document.getElementById("c1"); this.ctx1 = this.c1.getContext("2d"); this.c2 = document.getElementById("c2"); this.ctx2 = this.c2.getContext("2d"); let self = this; this.video.addEventListener("play", function() { self.width = self.video.videoWidth / 2; self.height = self.video.videoHeight / 2; self.timerCallback(); }, false); },

1
2
3
4
5
6
7
8
9
10
11
12
13
doLoad: function() {
    this.video = document.getElementById("video");
    this.c1 = document.getElementById("c1");
    this.ctx1 = this.c1.getContext("2d");
    this.c2 = document.getElementById("c2");
    this.ctx2 = this.c2.getContext("2d");
    let self = this;
    this.video.addEventListener("play", function() {
        self.width = self.video.videoWidth / 2;
        self.height = self.video.videoHeight / 2;
        self.timerCallback();
      }, false);
  },

这段代码获取XHTML文档中video元素和两个canvas元素的引用,还获取了两个canvas的图形上下文的引用。这些将在我们实现chroma-keying特效时使用。

addEventListener()监听video元素,当用户按下视频上的播放按钮时被调用。为了应对用户回放,这段代码获取视频的宽度和高度,并且减半(我们将在执行chroma-keying效果时将视频的大小减半),然后调用timerCallback()方法来启动视频捕捉和视觉效果计算。

九、参考链接

  • Domenico De Felice, How browsers work
  • Stoyan Stefanov, Rendering: repaint, reflow/relayout, restyle
  • Addy Osmani, Improving Web App Performance With the Chrome DevTools Timeline and Profiles
  • Tom Wiltzius, Jank Busting for Better Rendering Performance
  • Paul Lewis, Using requestIdleCallback

(完)

1 赞 3 收藏 评论

图片 18

处理视频帧数据

computeFrame()方法,如下所示,实际上负责抓取每一帧的数据和执行chroma-keying特效。

JavaScript

computeFrame: function() { this.ctx1.drawImage(this.video, 0, 0, this.width, this.height); let frame = this.ctx1.getImageData(0, 0, this.width, this.height); let l = frame.data.length / 4; for (let i = 0; i < l; i ) { let r = frame.data[i * 4 0]; let g = frame.data[i * 4 1]; let b = frame.data[i * 4 2]; if (g > 100 && r > 100 && b < 43) frame.data[i * 4 3] = 0; } this.ctx2.putImageData(frame, 0, 0); return; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
computeFrame: function() {
    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
    let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
    let l = frame.data.length / 4;
 
    for (let i = 0; i < l; i ) {
      let r = frame.data[i * 4 0];
      let g = frame.data[i * 4 1];
      let b = frame.data[i * 4 2];
      if (g > 100 && r > 100 && b < 43)
        frame.data[i * 4 3] = 0;
    }
    this.ctx2.putImageData(frame, 0, 0);
    return;
  }

当它被调用后,video元素将显示最近的视频帧数据,如下所示:

图片 19

在第2行,视频帧被复制到第一个canvas ctx1的图形上下文中,高度和宽度值指定为我们之前保存的帧大小的一半。注意,您可以通过传递video元素到绘图上下文的drawImage()方法来绘制当前视频帧。其结果是:

图片 20

第3行代码通过调用第一个canvas上下文的getImageData()方法,来获取原始图像数据当前视频帧的一个副本。它提供了原始的32位像素图像数据,这样我们就能够进行操作。第4行代码通过将帧图像数据的总长度除以4,来计算图像的总像素数。

第6行代码循环扫描所有像素,获取每个像素的红、绿、蓝值,同时和预定义的背景色进行比较,这些背景色将用foo.png中导入的背景图像替换。

被检测成背景的每一个像素,将它的alpha值替换为零,表明该像素是完全透明的。结果,最终的图像背景部分是100%透明的,这样在第13行代码,把它被绘制到目标的上下文中时,效果是内容叠加到静态背景上。

由此产生的图像看起来像这样:

图片 21

在视频播放时反复这样做,这样一帧接一帧处理,呈现出chroma-key的特效。

请看这个实例。

1 赞 1 收藏 评论

四、提高性能的九个技巧

有一些技巧,可以降低浏览器重新渲染的频率和成本。

第一条是上一节说到的,DOM 的多个读操作(或多个写操作),应该放在一起。不要两个读操作之间,加入一个写操作。

第二条,如果某个样式是通过重排得到的,那么最好缓存结果。避免下一次用到的时候,浏览器又要重排。

第三条,不要一条条地改变样式,而要通过改变class,或者csstext属性,一次性地改变样式。

JavaScript

// bad var left = 10; var top = 10; el.style.left = left "px"; el.style.top = top "px"; // good el.className = " theclassname"; // good el.style.cssText = "; left: " left "px; top: " top "px;";

1
2
3
4
5
6
7
8
9
10
11
// bad
var left = 10;
var top = 10;
el.style.left = left "px";
el.style.top  = top   "px";
 
// good
el.className = " theclassname";
 
// good
el.style.cssText = "; left: " left "px; top: " top "px;";

第四条,尽量使用离线DOM,而不是真实的网面DOM,来改变元素样式。比如,操作Document Fragment对象,完成后再把这个对象加入DOM。再比如,使用 cloneNode() 方法,在克隆的节点上进行操作,然后再用克隆的节点替换原始节点。

第五条,先将元素设为 display: none (需要1次重排和重绘),然后对这个节点进行100次操作,最后再恢复显示(需要1次重排和重绘)。这样一来,你就用两次重新渲染,取代了可能高达100次的重新渲染。

第六条,position属性为absolute或fixed的元素,重排的开销会比较小,因为不用考虑它对其他元素的影响。

第七条,只在必要的时候,才将元素的display属性为可见,因为不可见的元素不影响重排和重绘。另外,visibility : hidden 的元素只对重排有影响,不影响重绘。

第八条,使用虚拟DOM的脚本库,比如React等。

第九条,使用 window.requestAnimationFrame()、window.requestIdleCallback() 这两个方法调节重新渲染(详见后文)。

JavaScript代码

main.js中的JS代码包含三个方法。

本文由网上十大正规赌博平台发布于正规赌博十大app排名,转载请注明出处:Chrome开发者工具不完全指南,使用Canvas实时处理

关键词: AG游戏平台