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 ...
随机推荐
- 微信开发之移动手机WEB页面(HTML5)Javascript实现一键拨号及短信发送功能
在做一个微信的微网站中的一个便民服务电话功能的应用,用到移动web页面中列出的电话号码,点击需要实现调用通讯录,网页一键拨号的拨打电话功能. 如果需要在移动浏览器中实现拨打电话,发送email,美国服 ...
- git 命令记录
git log 配置 git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -% ...
- MODBUS-RTU通讯协议简介
MODBUS-RTU通讯协议简介 什么是MODBUS? MODBUS 是MODICON公司最先倡导的一种软的通讯规约,经过大多数公司 的实际应用,逐渐被认可,成为一种标准的通讯规约,只要按照这种规 ...
- UNIX网络编程-Select模型学习
1.相关接口介绍 1.1 select ---------------------------------------------------------------------- #include ...
- C++快速入门系列教程
C++ 60分钟入门教程:http://see.xidian.edu.cn/cpp/biancheng/view/2755.html
- python 中变量的命名方法
从网上找到django中python的命名规范 Python 规范 代码的布局 编码 所有的Python脚本文件都应在文件头标上“# -*- coding:utf-8 -*-”. 缩进 4个空格 ...
- Access数据库的模糊查询到底是用*还是%
今天被用了一下Access数据库,结果被它的模糊查询给折腾了一上午,到底是用*还是%?特此记下来 事情是这样的,我用C#写了个小的窗体程序,访问Access数据库进行一个模糊查询,我先手工往Acces ...
- Happy New Year
今年的元旦能明显感觉到节日的狂欢.一方面,论文的事情,压抑了好久,另一方面,把自己融入节日之中.所以才有了节日的深度参与. 早上还是按时的起床,看了朋友圈,内心却能专注于平静.因为见到了优秀的人,才发 ...
- 启动kafka出现找不到或无法加载主类
首先确认下环境变量配置是否成功. 如果配置成功<javac,javah>都没有问题,那就有可能是你安装了两个版本的jdk导致的,都卸载了,然后换一个目录按照一个jdk 在配置环境变量试下!
- javascript 取整,取余数
1.丢弃小数部分,保留整数部分 parseInt(5/2) 2 2.向上取整,有小数,则整数部分加1 Math.ceil(5/2) 3 3.四舍五入 Math.round(5/2) 3 4.向下取整 ...