js设计模式(二)深入理解享元模式
享元模式的介绍
享元(flyweight)模式是一种用于性能优化的模式,“fly”在这里是苍蝇的意思,
意为蝇量级。享元模式的核心是运用共享技术来有效支持大量细粒度的对象。
如果系统中因为创建了大量类似的对象而导致内存占用过高,享元模式就非常有用了。在JavaScript中,浏览器特别是移动端的浏览器分配的内存并不算多,如何节省内存就成了一件非常有意义的事情。
生活中举例
比如100个人从同一个起点出去,去往同一个目的地。如果这100个人都独自开车去,则每个人需要花费100元。但是,如果这100个人选择乘坐一辆巴士去,则每个人只需花费5元。这其中就蕴含着享元模式的设计思想
js运用中举例
其实我们平常中这种模式我们用得还是很多的,只是没有去知道他是什么模式,比如列表回收,就是在做上拉加载的时候,假设有上万条数据,每次手往上滑,就会加载二十条,又往上滑,又会加载二十条,一直往上滑,那么估计页面就会存在上千条数据,DOM存在,尤其是移动端,会造成卡顿现象。因此我们可以做优化,每次页面只会显示那几十条,然后上拉,最上面的滑下来。那么页面就只会存在这几十条数据。
下面这段代码就是简单的运用了享元模式,假设服务端返回了一万条数据,在前端进行分页,如果前端一次性渲染出来,页面会造成卡顿,所以前端的思路是每次在页面只渲染10条dom,然后点击下一页也只会把那10条dom的内容给替换掉,极大的优化了性能,看下图,可以很直观的看到每次都是这几个元素变,并没有额外的新增加其他的元素

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul id="news"></ul>
<button id="nextPage" onclick="goNext()">下一页</button>
<script>
let list = []
for(let i=0;i<20;i++){
list.push(`新闻${i}`)
}
console.log(list)
let getLi = (function(){
let lis = [] // 我们只需要创建并保存5个li就可以了
return function(){
let element;
if(lis.length<5){
element = document.createElement("li")
lis.push(element)
}else{
element = lis.shift()
lis.push(element)
}
return element
}
})()
let pageNum = 0;
let pageSize = 5;
let news = document.getElementById("news")
function goNext(){
pageNum++;
let start = (pageNum-1)*pageSize
// debugger
for(let i=0;i<5;i++){
let element = getLi()
element.innerHTML = list[start+i]
news.appendChild(element)
}
}
goNext()
</script>
</body>
</html>
特点
- 共享内存,节约内存空间
- 相同的数据共享使用
- 主要还是对数据,方法共享分离,将数据的方法分为内部数据,内部方法和外部数据,外部方法
- 内部状态保存在对象内部,通常不会改变,可以共享
- 外部状态保存在对象外部,可以随场景改变,不可以共享
享元模式带来的好处很大程度上取决于如何使用以及何时使用,一般来说,以下情况发生时便可以使用享元模式。
- 一个程序中使用了大量的相似对象。
- 由于使用了大量对象,造成很大的内存开销。
- 对象的大多数状态都可以变为外部状态。
- 剥离出对象的外部状态之后,可以用相对较少的共享对象取代大量对象。
转载自:https://juejin.cn/post/6844903937384906765