解析篇 - Task-slice实现淘宝移动端方式加载

前言

继上一篇文章发布以后,因为你们的支持,被顶上了掘金热搜榜第一,这里先感谢你们对个人支持javascript

固然,也有一些大佬,发现了其中的一些问题,在 git 里面也给我提了相应的 issues,感谢大家,你们针对的疑问比较多,并且都但愿有一个 demo 能够作演示,看见实际效果,在这里呢,我会拿我实际项目按照你们的疑问去调整,看看是否是真的是有大家考虑的问题css

若是有朋友仍是不怎么了解 Performance ,那就能够看一下这里,看下面的图就会比较容易了:性能优化篇 - Performance(工具 & api)vue

工具 git

git地址: task-slice 任务切片java

你们若是以为该文章对你们有必定的帮助的话,还但愿你们帮忙多点点 stargit

问题

疑问一:是否会空转

这个会空转,也确实会空转,可是空转是有做用的,两个 while 配合 generator 才能够达到 任务切片 的效果,这个待会 demo 给你们演示github

空转产生的效果就是 空间换时间 的过程api

疑问二:没有提速效果,反而代码量增长

在这里呢,我须要强调一下上一章说过的一个特色,就是 响应 ,咱们提高的,不仅是总体的速度,咱们可能总体的渲染速度下来,和以前不会有太大的差异数组

可是,咱们提高了 响应 速度,意味着什么,意味着用户能够在最短期内对访问咱们网站的行为作出最快的反应性能优化

举个例子:app

以前:咱们要加载一个网站,前面的加载资源 2s,渲染须要 500ms(5个组件),那就意味着,咱们在 2500ms 之后,才能够进行绘制,也就是说,用户要在 2500ms 之后才能够看到内容

如今:一样的资源加载时间 2s,一样的的渲染时间 500ms,一样的5个组件,可是使用了任务切片后,咱们每个组件都是独立渲染绘制的,也就是说,咱们在 2100ms 的时候,就可让用户看见咱们的第一块内容

整体问题

总体来讲,你们最主要的问题,都是在为何要使用 while 去循环那么多遍 yield,而不使用 if,经过 performance 你们其实能够看得出来,只有经过 while 才能够完成切片,这是重点,这也是为何我要使用 while ,而不使用 if 的缘由了

完整 demo

你们等了好久,我已经把 demo 放到了 github 上了,框架使用的是 vue,写了一个很简单的 demo,能够知足你们了解该工具的需求

以前咱们处理数据的方式

在以前,咱们要实现一个作数据更新,是这样的:

// before
var arr = [0,1,2,3,4,5,6,7,8,9] //模仿接口请求返回的数据
this.arr = arr
复制代码

咱们拿到数据之后呢,直接就把数据更新到对应的响应式数组里面,而后 vue 内部会直接把一整个数组进行遍历和渲染

根据下图,咱们就能够看得出来,在以前咱们渲染的方式,其实这是一个很是简单的 demo,咱们的实际项目,不会只有这么简单的布局,也不会只有这么简单的内容

使用任务切片后咱们处理数据的方式

// after
TaskSlice.init({
  sliceList: 10,
  callback: i => {
    this.arr.push(i)
  }
})
复制代码

咱们能够很直观的感觉到,对于内容得渲染绘制,有了很大的区别

Main 放大之后,咱们就能够看得出来,咱们把每个任务都给切开了,而后计算了样式,直接完成了绘制,把 dom 直接放在了页面上,让用户在第一时间看见了内容

如何作到真正的性能优化

有些性能优化,其实真的和想象当中,不同

对于性能优化的误解

不少人,对于性能优化来讲,都知道减小请求,快速渲染等等,固然,这个没有任何问题

可是,在当下的互联网市场需求来看,咱们有不少事情要作,不必定如今这样的方法是最好的,咱们要作必定的改变才能作到真正的优化

举个例子

var count = 5
for (var i = 0; i < count; ++i) {
    var div = document.createElement('div')
    document.body.appendChild(div)
}
复制代码

假设咱们要作性能优化的时候,就会发现这个样子写,是很差的,由于这样会不断的重绘和回流,性能确定不是最好的,因此不少人想到了一个 api:document.createDocumentFragment

使用 document.createDocumentFragment 咱们能够建立一个文档碎片,把全部的 div 都放到一个文档碎片内,而后在最后去执行 bodyappendChild

var count = 5
var fragment = document.createDocumentFragment()
for (var i = 0; i < count; ++i) {
    var div = document.createElement('div')
    fragment.appendChild(div)
}
document.body.appendChild(fragment)
复制代码

不少人一看会以为这样很好,没问题,这样咱们就不须要不断的去重绘和回流了,并且咱们使用建立文档碎片的方式,也不会建立多余的 dom

告诉你们,经过 performance 能够知道,这样的总体的 渲染速度 是没有直接去建立快的!!!

其实对于一些简单的需求,这种想法是没有问题的,由于原本内容就少,界面就简单,咱们就不须要作任务切片,也不须要作什么太过于复杂的处理,直接的渲染反而会更快

那么问题来了,若是咱们要是有 1000 个 dom (包括层级的 dom),而后还有很复杂的样式,还有不少的界面处理,那么这个方法好吗?

直接告诉你,不仅是很差,并且仍是很很差,这样咱们要等 css treedom tree 所有加载完毕,而后合并,计算完样式,最后才能绘制到页面上,很慢很慢,若是要是使用任务切片,假设咱们确实有这么多的 dom,咱们也会把他们切开,在一个时间段内,去渲染一部分,这样就可让用户在最短期内,看到 dom,仍是那个重点:咱们提高的是针对用户的响应速度,而不是总体的渲染速度

总结

这篇文章主要是给你们解答一下疑惑,让你们去更好的去了解这个工具,并帮助你们运用到实际项目当中

若是你们有疑问,请仔细看一下这篇文章以及 实战篇 - 如何实现和淘宝移动端同样的模块化加载 (task-silce),并结合 demo 和源码去看看是否能解决你的问题,若是解决不了,欢迎及时提问,有时间的话我会回复的

还有你们别只看代码不去测试,有时候你看到想到的,不必定和实际效果同样

相关文章
相关标签/搜索