背景
之前有一個angular項目,頁面上表單不算多互纯,也就一百來個(這個不固定尚蝌,有的地方多迎变,有的地方少),但是再輸入的時候會造成輸入延遲飘言,反應不靈敏氏豌,對用戶體驗極其不好。還有一個功能就是拖拽功能(原生热凹,沒有使用官方中的拖拽功能)泵喘,從左邊拖到右邊區(qū)域,拖拽區(qū)域少的時候還挺流暢般妙,但一旦有幾百上千的時候反應極其的慢纪铺,佛系的人都要變暴躁。
原因(可能)
上面兩個問題其實都和angular的機制有關碟渺。一個雙向綁定一個拖拽歸根結底都是因為angular
的變化檢測
angular的雙向綁定主要是臟數(shù)據檢查鲜锚,如果大量的檢查,效率比較低苫拍。(雙向綁定時向zone掛載一個異步函數(shù)芜繁,對數(shù)據改變是做處理,及時將變化反饋顯示在頁面上)可能就會輸入延遲
拖拽(也是向zone掛載異步函數(shù))則是因為angular對每個可移動像素的元素進行檢測而且還可能涉及對dom的操作绒极,當拖拽區(qū)域數(shù)量較為多時骏令,綁定的函數(shù)就越多,angular需要檢測的元素區(qū)域就越來越多垄提,處理起來就越力不從心(即使元素隱藏也不代表不會進行變化檢測)
解決
對于雙向綁定造成的輸入延遲榔袋,停止使用雙向綁定,改用單向綁定
拖拽過程angular一直檢測頁面變化铡俐,所以頁面卡頓凰兑。我們需要做的就是設置對某些操作不跟蹤變化
this.ngZone.runOutsideAngular(() => {
this.dragEnter = this.rd.listen(spanDom, 'dragenter', this.dragenterHandler.bind(this));
this.dragOver = this.rd.listen(spanDom, 'dragover', (e) => {
e.preventDefault();
});
this.dragLeave = this.rd.listen(spanDom, 'dragleave', this.dragLeaveHandle.bind(this));
});
this.dragDrop = this.rd.listen(spanDom, 'drop', this.dropHandler.bind(this));
對頻繁的操作(如dragover)不去觸發(fā)變更檢測。使用NgZone
中的runOutsideAngular
方法审丘,angular不會對里面的變化進行跟蹤吏够。
總結
我對angular的變化檢測也似懂非懂 -_-
看到腳本之家還有別的地方有我這篇文章的內容。滩报。锅知。不過他后面自己加了一段PS的demo。但是我這個和他的demo可能是不兼容的露泊,他的demo是使用了別人封裝的拖拽組件喉镰,我這個是直接對dom上操作的旅择。(看到了的注意一下)