星空之旅

我就是我,我就是那天边的一颗孤星,发出与众不同的光芒

第五届D2前端论坛

上午场:科学松鼠会

收藏下视频地址

http://v.youku.com/v_show/id_XMjMyNjQ0OTQ4.html

第五届D2前端技术论坛作品交流秀

去年在杭州D2论坛上的交流视频

收藏一下地址 

http://v.youku.com/v_show/id_XMjMyNzU1ODQ0.html

[转] Repaint & Reflow

 

1. 什么是 repaint 和 reflow

一个页面由两部分组成:

  • DOM : 描述该页面的结构
  • render : 描述 DOM 节点 (nodes) 在页面上如何呈现

当 DOM 元素的属性发生变化 (如 color) 时, 浏览器会通知 render 重新描绘相应的元素, 此过程称为 repaint.
如果该次变化涉及元素布局 (如 width), 浏览器则抛弃原有属性, 重新计算并把结果传递给 render 以重新描绘页面元素, 此过程称为 reflow.
这两个过程是很耗费浏览器性能的, 从 IE 系列和 Chrome 渲染页面速度上的差距即可看出渲染引擎计算对应值和呈现并不一定高效, 而每次对元素的操作都会发生 repaints 或 reflow, 因此编写 DOM 交互时如果不注意就会导致页面性能低下.

2. Reflow

当发生以下情况的时候, 会引发 reflow:

  • 可见元素的增删
  • 元素的位置, 大小, 内容的改变
  • 页面第一次渲染
  • 改变浏览器窗口的大小

幸运地, 浏览器对 reflow 的处理是和 PHP 的 Output Control 相似的 — 把 reflow 放进一个队列, 达到一定程度或时限就进行 flush. 但不幸的是, 这个过程可能会被我们强制提前执行 — 只要使用下面所列的任一个都会迫使浏览器 flush, 因此产生 reflow:

  • offsetTop, offsetXXX…
  • scrollTop, scrollXXX…
  • clientTop, clientXXX…
  • getComputedStyle / currentStyle

3. 怎么优化

首先是减少对 DOM 中有关布局的操作, 假设我们要动态改变一个元素的大小为 100*100px:

 

 

var el = document.getElementById("id");
el.style.width = 100px;
el.style.height = 100px;
// suppose there are two els : el2, el3
el2.style.width = el.style.width * 1.5;
el3.style.width = el.style.width * 2;
 
写成这样会有更好的性能:
 
el.style.cssText = "width: 100px; height: 100px;";
// or el.className = "square";
var width = el.style.width;
el2.style.width = width * 1.5;
el3.style.width = width * 2;

 

 

        操作 DOM 时尽量使用 DocumentFragment 和 cloneNode:

    // DocumentFragment

var fm = document.createDocumentFragment();
var a;
for(var i = 0; i < 20; i++){
    a = document.createElement("a");
    a.href = i + ".html";
    a.innerHTML = "page " + i;
    fm.appendChild(a);
}
document.getElementById("tar").appendChild(fm);
 
// cloneNode
var ul = document.getElementById("ul");
var clone = ul.cloneNode(true); // true = deep copy
var li;
for(var i = 0; i < 20; i++){
    li = document.createElement("li");
    li.appendChild(document.createTextNode(i));
    clone.appendChild(li);
}
ul.parentNode.replaceChild(clone, ul);

 大致优化思路如下:

 

  1. 把元素从 DOM 流中剥离 (clone, fragment, position: absolute, 绝对定位对动画或拖曳对象尤为有用)
  2. 在被剥离的的元素上进行各种操作
  3. 把被剥离的元素恢复到 DOM 流

注意:

  1. IE lte 8 有一个 bug — :hover, 大量出现使用该选择器的元素的话会降低页面响应速度
  2. 在不鸟 older browsers 的情况下, 可以大量使用 firstElementChild(),querySelectorAll() 等 API, 可实现的功能和 jQuery 等库的 CSS 选择器和遍历函数相差不大
  3. 此外对事件的绑定上尽可能使用 delegation, 也就是合理利用 event 的冒泡特性, 我认为这对 repaint & reflow 的影响是比较小的, 不过对于代码优化, 复用性和灵活性都有很大的帮助, 有空再继续

 

 经过网友提醒

偶发现在程序里忽略了linux服务器对于文件大小写的敏感问题

导致服务器是linux的无法正常运行游戏

在此表示抱歉

偶会尽快修正程序里的大小写问题并且重新打包上传

linux服务器用户可以到时重新下载代码上传服务器

windows服务器用户不受影响。

 

一个网友问偶:

我要获得 一个格子的八个方向的格子坐标,怎么获得,有合适的算法没?

我现在是这样的:

 

 

偶看了一下这个写法有几个问题:

1.代码累赘,篇幅过多

2.这么多个if...elseif...还不如直接用switch

3.每次获取代码都要进行判断,其实可以不需要

4.没有使用变量缓存属性,每次都是再次查找属性

 

简单的考虑了一下

偶觉得可以改进一下direction,也就是方向的数据格式

就可以很好的提高效率和精简代码

一个滑动展示的小代码

一个写给别人的小代码

顺便也贴上来

这是一个滑动展示用的小容器

通过鼠标移动和离开触发滑动效果

目前程序中用于判断客户端信息的对象

需求不高所以比较简单不一定精确

游戏中一般只需要判断是否IE、是否IE6、是否手机这三个功能

该对象可判断客户端的操作系统类型、浏览器类型、客户机器是电脑还是手机类、访问协议是HTTP还是FILE

这里偶只简单的使用判断当非windows、Mac、Unix这三个系统就是手机

当判断是手机后默认游戏自动拾取阳光

switch等值比较的写法改进

这个写法是专用于取代switch里相等值比较的

通常来说比较等值的每次比较都需要重复判断

通过自定义函数的使用避免了重复判断提高了效率

原理很简单即使用对象定位需要范围的值

该返回值可以是个变量也可以是数组、函数等

LoadImage是单张图片载入函数

如果要再某张图片成功载入后执行某函数就用一个LoadImage即可

在JSPVZ里的多张图片是每个关卡单独载入一次

在首页出现的时候

游戏的公用图片已经载入完毕

之后每关只载入本关所需要用到的图片

所以要使用到多图载入进度条

原理是要先知道到底要载入哪些图片

然后把所有需要载入的图片url放入一个数组

载入图片时循环读取数组url

每读取一个就执行一个LoadImage

而回调函数都是执行CheckImg来检查是否载入了所有图片

载入所有图片后就开始执行下一个任务

JSPVZ里一个自定义的核心系统对象

最近正在改进游戏程序的执行效率

整合所有的计时器

以一个初步的自定义系统对象控制整个游戏流程的进行

/*系统对象 
结构:一个setInterval计时器作为自定义系统时间,10毫秒累加1,1秒即为100 
一个setTimeout作为定时执行任务的计时器 
一个任务队列,存储着{},格式为 
{T:任务执行的系统时间,时间为自定义非JS自带 
...

分页:[«][1][2]3[»]
« 2013年2月 »
Sun Mon Tue Wed Thu Fri Sat
12
3456789
10111213141516
17181920212223
2425262728

文章归档

广告位