ng-style 的坑 - 对性能的影响
本文地址:http://www.cnblogs.com/jying/p/5633203.html
熟悉 angular 的前端对ng-style 一定不陌生,这个家伙可以绑定一个函数,使得我们可以在函数中根据不同的参数返回不同的样式,如下是一个简单的实例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body onselectstart='return false'>
<div ng-app="myApp" ng-controller="myCtrl" style="overflow-wrap:break-word;">
<span ng-repeat="idx in data" ng-style="setStyle(idx)">
{{idx+','}}
</span>
</div> <script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.data = [];
for(var i=1;i<=10000;i++){
$scope.data.push(i);
} $scope.setStyle = function(idx){
switch(idx%4){
case 1:return {"color":"red"};
case 2: return {"color":"chartreuse"};
case 3:return {"color":"yellow"};
case 0:return {"color":"blue"};
default : return {};
}
} });
</script>
</body>
</html>
ng-style 绑定文字颜色
在该实例中,我们通过 $index 绑定不同的文字颜色,是不是感觉很方便呢,程序猿和代码其乐融融,相处的很好嘛O(∩_∩)O
直到有一天......业务提出这么一个需求:在成千上万的 span 上拖动鼠标选择区域设置背景色!
拖动鼠标嘛,简单!我们有 ng-mouseenter、ng-mouseleave、ng-mousemove、ng-mouseup 、ng-mousedown!挽起袖子搞起!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body onselectstart='return false' style="-moz-user-select:none;">
<div ng-app="myApp" ng-controller="myCtrl" style="overflow-wrap:break-word;">
<span ng-repeat="idx in data" ng-style="setStyle(idx)"
ng-mousedown="mousedown($event)" ng-mouseup="mouseup($event)" ng-mouseenter="mouseenter($event)">
{{idx+','}}
</span>
</div> <script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.data = [];
for(var i=1;i<=10000;i++){
$scope.data.push(i);
} $scope.setStyle = function(idx){
switch(idx%4){
case 1:return {"color":"red"};
case 2: return {"color":"chartreuse"};
case 3:return {"color":"yellow"};
case 0:return {"color":"blue"};
default : return {};
}
} //识别鼠标是否按下
$scope.isdown = false;
//鼠标按下
$scope.mousedown = function(e){
$scope.isdown = true;
}
//鼠标抬起
$scope.mouseup = function(e){
$scope.isdown = false;
}
//鼠标进入
$scope.mouseenter = function(e){
if($scope.isdown){
console.log(e.target.style.backgroundColor = "#eeeeee");
}
}
});
</script>
</body>
</html>
ng-mouse 事件拖动鼠标绑定背景色
好像也没有什么问题嘛 →.→ 其实业务给的需求场景比这个复杂的多,这里只是举例说明所以目前没有感觉出现问题,那么ng-style 是在什么时候绑定控件的 style 样式呢?于是给$scope.setStyle 添加输出:console.log(idx); 结果刚才较流畅的界面卡出翔了 ←.←
好吧,我们把数字改小点看看效果 ↓ . ↓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body onselectstart='return false' style="-moz-user-select:none;">
<div ng-app="myApp" ng-controller="myCtrl" style="overflow-wrap:break-word;background-color: #dddddd;">
<span ng-repeat="idx in data" ng-style="setStyle(idx)"
ng-mousedown="mousedown($event)" ng-mouseup="mouseup($event)" ng-mouseenter="mouseenter($event)">
{{idx+','}}
</span>
</div> <script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.data = [];
for(var i=1;i<=100;i++){
$scope.data.push(i);
} $scope.setStyle = function(idx){
console.log(idx + " -- "+ (new Date()).getMilliseconds());
switch(idx%4){
case 1:return {"color":"red"};
case 2: return {"color":"chartreuse"};
case 3:return {"color":"yellow"};
case 0:return {"color":"blue"};
default : return {};
}
} //识别鼠标是否按下
$scope.isdown = false;
//鼠标按下
$scope.mousedown = function(e){
$scope.isdown = true;
}
//鼠标抬起
$scope.mouseup = function(e){
$scope.isdown = false;
}
//鼠标进入
$scope.mouseenter = function(e){
if($scope.isdown){
console.log(e.target.style.backgroundColor = "red");
}
}
});
</script>
</body>
</html>
ng-style 函数中写入console.log
按下 F12 查看控制台 ,鼠标移入数字区,可以看到console.log 不停的输出,也就是说此时 ng-style 是不停的重复绑定的,这显然是耗费资源的,在某些实时要求高的界面就会导致卡顿现象,为了避免这种重复的资料消耗决定换个方式绑定style,且要只绑定一次,想来想去决定还是用 for 遍历控件绑定
$scope.data = [];
for(var i=1;i<=100;i++){
$scope.data.push(i);
}
var spans = document.querySelectorAll("span");
for(var j=0;j<spans.length;j++){
var span = spans[j];
console.log(span);
}
然而这样获取到 spans 为[] ,因为此时ng-repeat 还没有渲染完 span ,根据js单线程原理,此时应该用$timeout(function(){},0); 原理请阅读:setTimeout 的黑魔法
看来以后要弃用 ng-style 的使用了。
全部实现代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body onselectstart='return false' style="-moz-user-select:none;">
<div ng-app="myApp" ng-controller="myCtrl" style="overflow-wrap:break-word;background-color: #dddddd;">
<!--<span ng-repeat="idx in data" ng-style="setStyle(idx)"
ng-mousedown="mousedown($event)" ng-mouseup="mouseup($event)" ng-mouseenter="mouseenter($event)">
{{idx+','}}
</span>--> <span ng-repeat="idx in data" test-index ={{idx}}
ng-mousedown="mousedown($event)" ng-mouseup="mouseup($event)" ng-mouseenter="mouseenter($event)">
{{idx+','}}
</span>
</div> <script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope,$timeout) {
$scope.data = [];
for(var i=1;i<=100;i++){
$scope.data.push(i);
}
$timeout(function(){
var spans = document.querySelectorAll("span");
for(var j=0;j<spans.length;j++){
var span = spans[j];
console.log(span.style.color =$scope.setStyle(span.attributes["test-index"].value));
}
},0); $scope.setStyle = function(idx){
console.log(idx + " -- "+ (new Date()).getMilliseconds());
switch(idx%4){
case 1:return "red";
case 2: return "chartreuse";
case 3:return "yellow";
case 0:return "blue";
default : return "#fff";
}
} //识别鼠标是否按下
$scope.isdown = false;
//鼠标按下
$scope.mousedown = function(e){
$scope.isdown = true;
}
//鼠标抬起
$scope.mouseup = function(e){
$scope.isdown = false;
}
//鼠标进入
$scope.mouseenter = function(e){
if($scope.isdown){
console.log(e.target.style.backgroundColor = "red");
}
}
});
</script>
</body>
</html>
弃用 ng-style
ng-style 的坑 - 对性能的影响的更多相关文章
- css的!important规则对性能有影响吗
最近在做项目中发现很多CSS代码里面都使用!important去覆盖原有高优先级的样式.按照常理来说,越是灵活的东西,需要做的工作就会更多.所以想当然的认为像!important这样灵活.方便的规则如 ...
- <style scoped >中使用深度选择器影响子组件
摘自:https://blog.csdn.net/zhouzuoluo/article/details/95593143 <style scoped >中使用深度选择器影响子组件 在< ...
- 高性能JavaScript-JS脚本加载与执行对性能的影响
在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 脚本位置对性能的影响 优化页面加载性能的原则之一是将scri ...
- JAVA 异常对于性能的影响
陶炳哲 - MAY 12, 2015 在对OneAPM的客户做技术支持时,我们常常会看到很多客户根本没意识到的异常.在消除了这些异常之后,代码运行速度与以前相比大幅提升.这让我们产生一种猜测,就是在代 ...
- HTTP/2 对 Web 性能的影响(下)
一.前言 我们在 HTTP/2 对 Web 性能的影响(上)已经和大家分享了一些关于 Http2 的二项制帧.多用复路以及 APM 工具等,本文作为姊妹篇,主要从 http2 对 Web 性能的影响. ...
- smarty对网页性能的影响--开启opcache
在上一篇<smarty对网页性能的影响>中,默认没有开启opcache,于是我安装了一下zend opcache扩展,重新实验了一下,结果如下: 有smarty 用apache的ab命令进 ...
- C++ 性能剖析 (四):Inheritance 对性能的影响
(这个editor今天有毛病,把我的format全搞乱了,抱歉!) Inheritance 是OOP 的一个重要特征.虽然业界有许多同行不喜欢inheritance,但是正确地使用inheritanc ...
- List是线程安全的吗?如果不是该怎么办呢?安全的List对性能的影响有多大呢?
测试条件: 开启2个并行执行任务,往同一个list对象写入值 测试代码: ; static List<int> list = new List<int>(); static v ...
- JS脚本加载与执行对性能的影响
高性能JavaScript-JS脚本加载与执行对性能的影响 在web产品优化准则中,很重要的一条是针对js脚本的加载和执行方式的优化.本篇文章简单描述一下其中的优化准则. 1. 脚本加载优化 1.1 ...
随机推荐
- a new blog from MarsEdit
终于在网上找到了一款mac 下的blog写作和发布工具了. 先测试一下.
- mysql grant命令错误:ERROR 1044 (42000): Access denied for 'root' With All Privileges
http://stackoverflow.com/questions/21714869/error-1044-42000-access-denied-for-root-with-all-privile ...
- shell中bc expr [ ] (( ))的使用方法
http://blog.chinaunix.net/uid-20671208-id-3552751.html
- [SQL]查询表里的字段名
Select Name from syscolumns Where ID=OBJECT_ID('表名') select * from information_schema.tables WHERE T ...
- 使用delphi+intraweb进行微信开发5—准备实现微信API,先从获取AccessToken开始
在前4讲中我们已经使iw开发的应用成功和微信进行了对接,再接下来的章节中我们开始逐一尝试和实现微信的各个API,开始前先来点准备工作 首先需要明确的是,微信的API都是通过https调用实现的,分为p ...
- Google Developing for Android 三 - Performance最佳实践
Google Developing for Android 三 - Performance最佳实践 发表于 2015-06-07 | 分类于 Android最佳实践 原文 Developing ...
- get_list_or_404(klass, *args, **kwargs)和get_object_or_404(klass, *args, **kwargs)区别
get_object_or_404() 是通过调用get()方法从model管理器上获取数据, 如果对象不存在,它会报Http404的异常,而不是model的 DoseNotExist异常. get_ ...
- delphi.thread.同步
注意:此文只是讲线程间的同步,其它同步不涉及. 线程同步是个好话题,因为写线程经常会遇到,所以就写写自己知道的东西. D里面,同步(特指线程同步)从线程的角度来分,有几种情况: 1:主线程与工作线程的 ...
- delphi.位操作
位操作网上有很多介绍,请上网google/baidu,比如: 位操作技巧实例大全: http://blog.csdn.net/g_spider/article/details/5750665 位操作基 ...
- windows python文件拷贝到linux上执行问题
之前在Windows下写好了一个Python脚本,运行没问题,今天在Linux下,脚本开头的注释行已经指明了解释器的路径,也用chmod给了执行权限,但就是不能直接运行脚本. 1 问题1: 报错:: ...