从一开始接触Ext就看到有Ext.fly这个函数,当时觉得这个跟Ext.get没什么区别,加之当时对JS性能相关问题认识肤浅,也一直没有在意其区别,今日看learning extjs一书,看到了有专门对Ext.fly特别强调的一处:
This isn't exactly a speed tip, but is more about conserving memory by using
something called a "flyweight" to perform simple tasks, which results in higher speed
by not clogging up the browser's memory
大概意思也就是Ext.Fly采用flyweight模式使所有fly出来的元素共享内存,可以提高程序执行速度,减少内存占用。
这段话激起了我对这个函数的兴趣,毕竟近段时间一直在搞JS性能优化相关问题,对“内存”这个字眼非常敏感。大概看了下Ext源码对get和fly实现的部分,然后在网上查看了一些资料,终于对他们之间的异同有了个比较深入的认识。 Ext的官方开发人员给出了如下的解释:
Ext.Element wraps a lot of functionality around DOM element/node, for example functions like hide, show, all animation stuff, dimensions getting and setting function and a lot more.
Ext.Element keeps reference to DOM element it is wrapped around in dom property. Once you have an Ext.Element (e.g. you call Ext.get('some-id') it is an instance of Element class and you can work with it as such.
Now, imagine that you need to hide 1000 DOM nodes, you call 1000 times Ext.get('some-one-of-1000-id').hide() so you create 1000 instances of Element just to call one function: hide.
Ext.fly is one instance of Ext.Element with "replaceable" DOM node it is wrapped around. If you call 1000 times Ext.fly('some-one-of-1000-id').hide() you 1000 times replace dom property of one instance of Ext.Element.
Result: higher performance, lower memory usage.
You only need to keep in mind that you cannot keep Element returned by Ext.fly for later use as it's dom will sooner or later gets replaced by another one.
这段话中,大致的意思如下:
Ext.Element是Ext对Dom元素的一个强有力封装,它封装了很多方便对dom操作的接口(并通过Element的dom属性引用对应的dom元素),因此每创建一个Element元素都将消耗不少的内存(主要是大量的操作接口消耗),因此如果创建过多的Element元素必然导致内存占用的剧增和系统性能的下降。
Ext.get和Ext.fly返回的都是一个Element对象,但是Ext.get返回的是一个独立的Element,拥有自己独立的操作接口封装,可以将其返回值保存到变量中,以便以后调用操作等,这样为重用带来了方便。但是它的一个很大缺点就是内存消耗问题,假如调用Ext.get(id)1000次,则会在内存中创建1000个独立Element,其内存占用可想而知。但是很多时候我们可能仅仅只是对该dom元素执行一次很简单的操作,如隐藏(hide),这样如果每次都创建一个独立Element放在内存中,实在是对内存的巨大浪费,因此当我们在只需要执行一次操作或者一个很简单的操作时,采用Ext.get就显得很不合理。Ext.fly正是为了解决这个问题而出现,它通过使每次创建的Element共享内存中的一套操作接口来达到节省内存的效果。
下面来看Ext.fly的实现代码(我简单加了一些注释):
var flyFn = function(){};
flyFn.prototype = El.prototype;
var _cls = new flyFn(); //将Element的所有操作接口放在_cls中
// dom is optional
El.Flyweight = function(dom){
this.dom = dom;
}; //仅包含一个dom属性的Object
El.Flyweight.prototype = _cls; //将操作接口复制给Element实例对象
El.Flyweight.prototype.isFlyweight = true; //标志该Element是flyweight对象
El._flyweights = {}; //flyweight对象缓存容器
El.fly = function(el, named){
named = named || '_global';
el = Ext.getDom(el); //取得dom对象
if(!el){
return null;
}
if(!El._flyweights[named]){
El._flyweights[named] = new El.Flyweight(); //仅在第一次调用Ext.fly时创建一个Flyweight对象并缓存
}
El._flyweights[named].dom = el; //将flyweight对象的dom属性指向该el
return El._flyweights[named];
};
从上面的代码不难看出,仅在第一次调用Ext.fly时创建一个Flyweight对象(该对象包含了Element的所有操作接口)并将其缓存,之后的所有fly操作都只是修改该flyweight对象的dom属性,每次fly返回的结果都是共享的同一个flyweight对象。这样每次fly返回的Element相比Ext.get而言,减少了每次创建Element时对大量的操作接口的创建。所有fly的对象都共享一套Element操作接口,内存占用自然少了很多,而且执行速度也得到了提升。在大量的创建操作中效果会更加明显。
相关推荐
享元模式(Flyweight Pattern)是一种结构型设计模式,它能有效地减少系统中对象的数量,从而降低内存消耗,提高性能。这种模式通过共享大量相似对象的内部状态来达到这一目标,而只保留对象的外部状态在外部管理。...
享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少创建大量小对象所带来的内存开销。通过共享对象,享元模式能够有效地支持大量细粒度的对象,减少内存使用并提高性能。它常用于需要大量重复对象的场景...
享元模式是设计模式中的一种结构型模式,它主要通过共享已有对象来减少内存中对象的数量,从而提高系统性能。在C#编程中,享元模式尤其适用于那些创建大量相似对象且内存消耗较大的场景。本篇文章将深入探讨享元模式...
享元模式(Flyweight Pattern)是软件设计中的一种结构型设计模式,它通过共享技术来支持大量细粒度的对象,以此来降低内存中对象的数量。在PHP中实现享元模式,可以帮助我们优化程序性能,特别是在对象数目过多时,...
在“Flyweight”这个文件中,我们可以预期找到的是一个关于享元模式的代码实现。这个文件可能包含了一个享元接口,若干个实现了该接口的具体享元类,以及一个享元工厂类。享元接口定义了对外暴露的方法,这些方法...
享元模式是软件设计模式中的一种结构型模式,它的主要目的是通过共享大量细粒度对象来减少内存的使用,提高系统性能。在许多场景下,尤其是处理大量相似对象时,享元模式能显著减少内存开销。这个压缩包文件...
享元模式的核心是Flyweight类,它是需要被共享的对象,通常包含两个部分:内在状态(Intrinsic State)和外在状态(Extrinsic State)。内在状态是指对象内部不变的部分,可以在多个对象之间共享;外在状态是随环境...
享元模式是面向对象设计中的一种结构型模式,它的主要目的是通过共享大量相似对象来减少内存的使用,提高系统的性能。在C#编程语言中,我们可以利用享元模式来优化那些具有大量实例但大部分状态可以共享的对象。在这...
复合享元模式则引入了享元工厂(Flyweight Factory)来管理和创建享元对象。享元工厂负责管理享元对象池,并根据需要向客户端提供享元对象。当请求的对象不在池中时,工厂会创建新的享元对象;如果存在相同的内蕴...
C++设计模式之享元模式(Flyweight) C++设计模式之享元模式(Flyweight)是一种结构型设计模式,主要用于解决大量相似对象的创建和操作所带来的内存负载问题。该模式的主要设计目标是通过共享对象来减少内存负载,...
享元模式是软件工程中一种用于优化性能的设计模式,它通过共享相似对象的实例来减少内存使用或者计算的开销。在JavaScript编程中,尤其是处理DOM操作和大量相似对象时,享元模式的使用尤为关键。 享元模式的主要...
"Flyweight"(享元)设计模式是一种结构型模式,其核心目的是为了有效地支持大量细粒度对象的创建和使用,通过共享已经存在的对象来减少内存消耗,提高系统性能。在C#中,Flyweight模式尤其适用于那些内部状态可共享...
享元模式的核心是享元对象(Flyweight),它是一个可以被共享的类,通常包含一些共享状态(Static State)和不共享状态(External State)。共享状态是在所有享元对象之间共享的数据,它们不会因对象的不同而改变;...
在Java中实现享元模式时,通常会结合使用`Flyweight`接口和`Concrete Flyweight`类,以及一个`FlyweightFactory`类或方法。`FlyweightFactory`通常维护一个享元对象池,当客户端请求一个享元对象时,工厂首先检查...
享元模式是一种经典的设计模式,属于结构型模式,它的核心思想是通过共享已经存在的对象来减少内存中的对象数量,从而提高系统性能。在许多场景下,特别是计算机编程中,我们可能会遇到大量的相似对象,比如在图形...
享元模式(Flyweight Pattern)是设计模式中的一种优化模式,主要用于减少创建大量相似对象所需的内存消耗。在C++程序设计中,当系统中存在大量的相同或相似的对象时,使用享元模式可以有效地降低内存占用,提高系统...
在享元模式中可以共享的相同内容称为内部状态(Intrinsic State),而那些需要外部...在享元模式中通常会出现工厂模式,需要创建一个享元工厂来负责维护一个享元池(Flyweight Pool)用于存储具有相同内部状态的享元对象。
1. **抽象享元(Flyweight)**:这是享元模式的接口,定义了所有享元对象公共的行为。 2. **具体享元(Concrete Flyweight)**:实现了抽象享元接口,提供了具体的业务逻辑。这些对象是可以共享的,并且通常存储在一...