HTML5触摸界面设计与开发--笔记--javaScript性能优化
来源:互联网 发布:mac破折号 编辑:程序博客网 时间:2024/06/05 21:49
一 : 本文中使用的性能优化策略
1 只写入DOM,因为DOM交互式相当慢的
测试:
console.time('test'); var test=document.getElementById('index-bn').title ; console.timeEnd('test'); test: 0.091ms var cache=['111']; console.time('test'); var test=cache[0]; console.timeEnd('test'); test: 0.021ms ```
1.1 显然不可能完全避免从DOM中读取数据,但我们可以使用缓存数据来减少读取的频率,如果你认为会再次使用某个DOM,你可以将它储存在一个变量中。1.2 DOM操作是阻塞的,当一个DOM操作在运行时,其他的什么都不能做。
2 给用户反馈的优先级是最高的
2.1 输出
浏览器中的javaScript是单线程,这意味着同一时间javaScript引擎在同一时间只能做一件事情,这个线程通常被称为UI线程,并行是通过将所有任务推到一个队列中来实现的,队列中的任务会在线程变得空闲时执行,如果一个缓慢的DOM操作在执行,传入的时间必须排队等候,直到DOM操作完成处理,如一个缓慢的DOM读取在执行,此时用户与页面进行交互,那么事件将不会马上被处理。
2.2 延迟执行
如果浏览器正忙着给用户返回,而你需要处理AJAX响应这种成本比较大的操作,你可以延迟执行。
例 –无限滚动
<div id="wrapper"></div><script id="slide" type="text/x-handlebars"> <div class="slide"> <p class="logo"></p> <div class="imgholder"> <a title="by {{ownername}} on Flickr" target="_blank" href="http://www.flickr.com/photos/{{owner}}/{{id}}"><img class="img" data-src="{{url_n}}"></a> <p>{{title}}</p> </div> </div></script>
样式
body { margin: 0; padding: 0; text-align: center;}.slide { width: 300px; padding: 20px; margin: 10px auto 10px auto; height: 250px; background: #f6f6ed; position: relative; text-align: center;}.slide p { width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-family: sans-serif;}.slide .img { max-width: 100%; max-height: 210px; text-align: center; opacity: 1; display: inline; -webkit-transition: opacity 0.25s ease-in-out; -moz-transition: opacity 0.25s ease-in-out; -o-transition: opacity 0.25s ease-in-out; transition: opacity 0.25s ease-in-out;}.imgholder { width: 100%; text-align: center;}
无限滚动脚本
function handleScroll(e) { if(window.scrollY + window.innerHeight + 1000 > document.body.offsetHeight) { fetchBirds();//请求数据 } handleDefer(); //判断是否可见} window.addEventListener('scroll', handleScroll);
获取包含很多图片的内容时,当他们被插入到页面中是,浏览器就开始获取图像,这意味着同时下载,浏览器的下载通道被占满,使用户看的图片显示更慢,同时,由于内容先于用户加载,可能下载永远无法被看到的图像,在这里可以使用延迟加载,当图像被看到时才下载加载图像,使页面更快,还可以节省用户的流量。
延迟加载图像
function isVisible(node) {//判断是否可见 //get the dimensions we need var scrollTop = window.scrollY, offTop = node.offsetTop, offsetHeight = node.offsetHeight, innerHeight = window.innerHeight, topViewPort = scrollTop, bottomViewPort = scrollTop + innerHeight; //figure out if it is in the viewport or not return offTop + offsetHeight > topViewPort && offTop < bottomViewPort;}function handleDefer() {//可见就加载图片 //find all the slides, I'm fetching the container //rather than the image because I don't know the image //heights yet var list = document.querySelectorAll('.slide'); for (var i=0, len = list.length; i < len; i++) { thisImg = list[i].querySelector('.img'); if(thisImg.src) { continue; } //if they are visible, update the src if(isVisible(list[i])) { var src = thisImg.getAttribute('data-src'); if(src) { thisImg.src = src; thisImg.removeAttribute('data-src'); } } }}
现在图像使延迟加载的,但加载时会看到图像空白,体验并不是很好,我们可以加上动画效果并优化延迟加载效果
.slide .img{ transition:opacity .25s ease-in-out;}function handleDefer() { console.time('defer'); var i, list, thisImg, deferSrc, img, handler, //the slide cache is populated by the function that //loads the data so that the defer code doesn't need //to keep querying the dom. list = slideCache, len = listLength; for (i=0; i < len; i++) { thisImg = list[i].img var deferSrc = list[i].src; if(isVisible(list[i].id)) { //create a closure for for simple preload stuff handler = function() { var node, src; node = thisImg; src = deferSrc; return function () { node.src = src; node.style.opacity = 1; loaded[deferSrc] = true; } }(); //申明一个image,然后将src赋给改image的src,等待图像下载完成后再讲路径替换(此时图像已经下载到本地了,并使用动画效果显示) var img = new Image(); img.onload = handler; img.src = list[i].src; } } console.timeEnd('defer');}
现在加上了动画效果,在感知的性能上的提升是显著的。
可能你已经注意到了,我们是从slideCache而不是从DOM得到的幻灯片信息,这是应用了“只写入DOM”策略。DOM只有在添加新内容时才会被修改。数据会使用updateSlideCache函数来缓存。
var slideCache;function updateSlideCache(node) { //在插入数据时调用此函数 var list = node.querySelectorAll('.slide'), len = list.length obj; slideCache = []; for (var i=0; i < len; i++) { obj = { node:list[i], id:list[i].getAttribute('data-id'), img:list[i].querySelector('.img') } obj.src = obj.img.getAttribute('data-src'); slideCache.push(obj); }}
这里的node是一个只包含新添加的数据的节点。
另一个减低速度的是isVisible()函数, isVisible()函数需要大量的DOM读取和检查来执行它的运算。
使用缓存来快速检查元素的可见性
var slideMap = {};//to simplify look up this now takes a photo id,//which is the same as a slide id.function isVisible(id) { var offTop, offsetHeight, data; //if the slide is cached we can get the //values from there if(slideMap[id]){ offTop = slideMap[id].offTop; offsetHeight = slideMap[id].offsetHeight; //if the slide is not cached, update the cache }else { node = document.getElementById('s-' + id); offsetHeight = parseInt(node.offsetHeight); offTop = parseInt(node.offsetTop); data = { node:node, offTop:offTop, offsetHeight:offsetHeight }; slideMap[id] = data; } //in the cached case this is just math, no DOM inspection at all if(offTop + offsetHeight > topViewPort && offTop < bottomViewPort) { return true; } else { return false; }}
- HTML5触摸界面设计与开发--笔记--javaScript性能优化
- HTML5触屏界面设计与开发
- HTML5性能优化与分析
- OCUI界面设计:触摸与手势
- Javascript性能优化学习笔记
- Javascript性能优化阅读笔记
- iOS开发笔记-触摸事件与手势
- 《iOS开发笔记-触摸事件与手势》
- DOM性能瓶颈与Javascript性能优化
- DOM性能瓶颈与Javascript性能优化
- DOM性能瓶颈与Javascript性能优化
- DOM性能瓶颈与Javascript性能优化
- DOM性能瓶颈与Javascript性能优化
- DB2开发与性能优化
- Javascript性能优化学习笔记1
- JavaScript笔记(3)---编程性能优化
- HTML5的性能优化
- 记录HTML5性能优化
- Android四大组件学习之BroadcastReceiver
- Java Socket close和Shutdown的区别
- systick定时器
- mysql一些常用的语句
- 云计算终将被边缘计算取代
- HTML5触摸界面设计与开发--笔记--javaScript性能优化
- android中的索引列表
- 使用Mingw-w64编译FreeImage
- CommentListTextView 一个TextView实现朋友圈的评论列表
- mysql 存储过程
- Android体系介绍
- springboot websocket
- openwrt移植到pb44---第一章(遗留问题)
- 快速搭建Spring Boot项目