解析篇 - 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 和源碼去看看是否能解決你的問題,若是解決不了,歡迎及時提問,有時間的話我會回覆的

還有你們別隻看代碼不去測試,有時候你看到想到的,不必定和實際效果同樣

相關文章
相關標籤/搜索