懶載入之intersection observer
聊聊intersection observer
二話不說先上連結
先說說為什麼最近在看這個
最近在做效能優化。每一個工程師程式碼量積累到一定程度之後總有一天會遇到這個問題,那就是效能問題。而我在寫了快一年半的前端之後,也自然而然遇到了效能問題。其實效能問題之前就有遇到,只不過當時工程量比較小,覺得應該要等到成熟一點再考慮這個事情(事實證明這個思路是正確的)。而效能優化真的是個大話題,關於效能優化其實我有非常多的心得,雖然現在還是處於摸索階段。
針對業務場景自然而然想到去用intersection observer
我們的業務場景會在首屏渲染非常多的東西,多到需要等待十幾秒才能看到頁面。而需要這麼多時間的根本原因是頁面需要渲染的東西過多。之前寫的時候不懂那麼多,就按著業務邏輯來,設計師估計也沒考慮這麼多好看就行。當突然某一天需要在首頁載入很大的資料量的時候就涼涼了。(現在老闆每次開啟首頁都得等個10幾秒,羞愧。。好在好像勉勉強強能接受)但是其實我們這個網頁和其他人的網頁都有個很大的共同點就是首屏資料並沒有特別多。我試了一下將其他地方用ngif注掉,只渲染首屏,除去後端初始化的資料,光渲染部分只需要不到1秒鐘。
查了很多資料,發現比較適合的有兩個方向,intersection observer和virtual scroll。翻譯過來就是響應式觀察和虛擬滾動。其實他們兩個的目的一樣,就是每次只渲染使用者看到的部分,當使用者滾動、切屏等操作想要看到新內容時,才會去渲染新內容。
其實也可以不用intersection observer,自己硬寫問題不大。原理其實還是比較簡單的,就是監聽使用者滾動操作,拿到當前的scrollTop和設定了滾動的元素的height,計算出可視範圍(viewport),然後在每個單元元件去檢視自己所屬的元素是否在這個可視範圍內,若是則渲染,不是則忽略。
然後就開始做起來了
上述思路雖然說起來容易,其實想要實現起來也很容易,但是若自己操作則需要考慮相容性問題、程式碼規範問題、測試問題等等,而intersection observer其實是幫我們將一系列操作包好,形成一系列響應式api,我們只需要結合rxjs就可以很輕易的用起來了。
我也可以簡單說一下我的思路。new一個全域性唯一的observer,引數需要傳想要監聽滾動的root元素,各子child元素與root元素交叉百分之多少則視為可視。我用的是angular,所以我寫了一個service來載入這個obsserver,寫了一個directive來繫結root元素,再寫一個directive來繫結想要懶載入的元素。service只暴露一個方法,即當前可視的元素都有哪些,再結合rxjs,就能實現了。
說一下該做法下懶載入的過程。當剛剛開啟頁面時,對於html來說其實所有元素還是載入了,只不過會根據intersection observer選擇性的只渲染最小單位,說白了就是隻要這個元素能有就行了,一些複雜的子元素,會很消耗效能的都ngif幹掉(ngif非同步小技巧,即如果繫結的變數是非同步的,比如有個變數為const sub$= new Subject()
,那可以這麼寫(ngIf=‘sub$ | async’),angular ngif的內部實現會幫你去subscribe該變數,且還能幫你在元件銷燬時unsubscribe該變數,非常方便)。而對於js來說,也可以將很多耗時的程式碼都放到subscribe當中。視覺上來說,在滾動時,看起來像流水一樣,不停嘩啦啦載入出東西。
結局
感覺自己並沒有吃透,因為一頓操作之後重新計時,發現也就快了200ms。對於整體的10幾秒鐘來說感覺像沒優化過一樣。也有可能是我沒敢大張旗鼓地去重構我們的程式碼,很多消耗效能的程式碼沒去優化。但是至少我覺得這個思路應該是正確的,剩下的就是一點點去摳哪裡消耗效能,然後用intersection observer對它作懶載入。還是比較有信心能達到想要的效果的。
再說說虛擬滾動
虛擬滾動也是另一個特別好的思路。我們的業務場景不是特別適合,但是給了我一個新的思路就是我也不一定要死摳技術實現,有時候設計師只要在設計上動點腦子,把我這個需求也考慮進去,說不定就可以很簡單的實現了。我已經在孜孜不倦洗腦設計師能儘快出下一版,然後把我這個思路考慮進去,使得我可以更方便做懶載入頁面。
關於懶載入
關於懶載入我目前覺得最好的思路還是vscode。我有看過原始碼,雖然還沒花大量時間去摳細節,但是vscode跳轉(就是在vscode可以跳轉引用,應該很多ide都有,只不過我目前只看過vscode)的思路就是它能精確計算出需要跳轉到的元素在哪個位置,即哪個目錄,哪個檔案,滾動多少畫素。只有將頁面元素結構規劃好,並用計算的方式去拿到各個元素,才能從根本上去做懶載入。
最後再說說效能優化
我最近對前端的效能優化真的特別有興趣,csr,ssr,懶載入,cdn等等都有在看。希望能和更多人交流。
相關文章
- 使用Intersection Observer API建立無限載入元件ServerAPI元件
- 使用Intersection Observer API建立無限載入元件.mdServerAPI元件
- Hibernate 之 懶載入
- 精讀《react-intersection-observer 原始碼》ReactServer原始碼
- Intersection observer檢測元素是否在視窗內Server
- 懶載入
- 前端曝光資料埋點——Intersection Observer+vue指令前端ServerVue
- 前端優化之圖片懶載入前端優化
- 懶載入和預載入
- Ribbon - 懶載入
- VUE系列之效能最佳化--懶載入Vue
- 【實戰】用原生的 JavaScript Intersection Observer API 實現 Lazy LoadingJavaScriptServerAPI
- 【譯】懶載入元件元件
- 圖片懶載入
- vue路由懶載入Vue路由
- Vue元件懶載入Vue元件
- Vue 的懶載入Vue
- 圖片預載入和懶載入
- Vue 路由按需載入(路由懶載入)Vue路由
- Vue圖片懶載入之lazyload外掛使用Vue
- 前端效能優化 --- 懶載入&預載入前端優化
- 圖片懶載入(IntersectionObserver)Server
- 關於懶載入原理
- Fragment 懶載入實踐Fragment
- 圖片懶載入原理
- vue(18)路由懶載入Vue路由
- 我的前端筆記之 懶載入 與 節流前端筆記
- 手把手實現圖片懶載入+封裝vue懶載入元件封裝Vue元件
- [譯] React 16.6 懶載入(與預載入)元件React元件
- 圖片懶載入踩坑
- 圖片懶載入大白話
- Android優化--Fragment懶載入Android優化Fragment
- Js圖片懶載入(lazyload)JS
- 單張圖片懶載入
- 圖片懶載入實現
- dva中元件的懶載入元件
- DCL懶載入單例模式單例模式
- Laravel Eloquent中的 懶載入VS即時載入Laravel