react+redux+webpack移動端項目總結

前言

距離我進新公司也有一個多月,這一個月的事件使用react寫了一個項目,期間斷斷續續重構了兩三次,目前已經完成第一階段測試,也總結分享一些使用react的一些坑。

react

先啰嗦幾句講一下react原理,新人可以認真看下,老鳥可跳過。

react并沒有像其他如vue,ng一樣采用MVVM模式,所謂MVVM模式,狹義來說就是將模板與數據綁定在一起,當數據發生改變時,模板自動更新,這是中間的VM,最左邊的M可以理解為我們看到的頁面,而最右邊的M可以理解為原始數據(例如數據庫數據)。
其實要知道,這些框架模式歸根結底的目的希望使代碼更容易開發和維護。當你寫一個小頁面你不覺得什么,但是當你的頁面越來越龐大,越來越復雜,開發人員走了一批又一批的時候,你就會明白了。而如何解決,現在比較公認的理念一個是組件化,將頁面拆分成一個個組件,其實拆分成組件的目的并不全是為了復用,我覺得更多是為了維護;一個就是希望讓應用層的編程能更專注于業務邏輯,那么這些框架都去做了處理,減少了大量DOM操作,讓業務開發更加專注。

那么我們看看react采用的是什么原理。其實react采用的方法簡單粗暴:它并沒有對模板做數據綁定,而是每當數據變化時,就重新渲染模板。這有一個很大的好處就是每當數據變化時,對頁面來說只有一次IO操作,而單純的雙向綁定更新DOM會有很多次;但有一個問題,如果只改變了一個dom的數據,整個模板都會重新渲染。那react解決的方法是每當數據改變時,就進行對比。

那么該如何對比呢,最簡單的方法是每當數據改變,就去頁面獲取相應的DOM信息,然后與現在的DOM信息做比較。這個方法有個致命的缺點就是每次有DOM改變,就會有許多讀取操作,IO操作太多,很影響性能。那么可以通過空間換時間的方法,將DOM信息保存起來,就避免了去頁面獲取信息的IO操作。那么我們看看一個真實DOM有多少數據

domproperty.png

虛擬DOM

如果我們把所有原生DOM緩存起來進行比較顯然內存會爆炸,而我們所需要的僅僅是幾個為數不多的狀態信息(例如style啊這些),這時虛擬DOM應運而生,如果說原生DOM是一塊豬肉,那么虛擬DOM就是這塊豬肉中多精肉,他剔除了那些對我們來說沒有太多意義相反還占內存的狀態信息,而只將我們所需要的內容留了下來。那虛擬DOM該如何比較呢,就涉及到了虛擬DOM的diff算法。

diff算法

簡單來說兩個模板就像兩棵樹一樣,傳統的樹對比的時間復雜度是O^3,也就是說要整棵樹遍歷三次,那react根據DOM的特點:跨層級的操作較少。什么叫跨層級,舉個例子一個組件有三個層級關系(嵌套三層),把第二層的div放到第三層就屬于跨層級操作。這種操作其實還是比較少的,react官方也不推薦這么寫。那么利用這個特點,react只diff同層級的DOM。這里涉及以下幾種情況

  1. tag變化(標簽變化)
  2. 屬性變化

第二種沒什么好說,就是進行同層級對比。這里詳細說一下第一種變化,react的方法是當前層級往下全部刪除替換,簡單暴力。在業務開發來看,你同層級類型都不同了,比如div變成了input,那么你的子組件相同的幾率也較小,因此不如整個替換簡單暴力。同時這也說明為什么列表需要key屬性,因為列表很多的刪除操作對于react來說是不知道的,它需要一個key來了解到底誰是誰。

踩過的一些坑

state

作為前端,拿到原型第一件事就是要與你的產品充分溝通,評估該項目是否需要引入redux,那么如何確定需要引入redux呢,這邊有幾點:

  1. 頁面之間組件之間通信較多,且是跨層級的;
  2. 頁面的交互邏輯較復雜,且經常引起多處組件變化。

再然后就是對state的設計。對于后臺的返回的數據,你并不知道到底哪些是有用的,哪些可能現在沒用以后有用,因此我的建議是對于每個api都將它存在一個object里。那么組件該如何去獲取,首先不能全部通過頂部container獲取依次往下傳,也不能粒度很細的去一個個connect,我的建議是對于一個object,可以用一個container去connect,粒度把握主要看你的業務需求。

還有一個要不要全局都使用redux。我的觀點是否定的,我認為對于局部一個組件內的狀態完全可以通過setState來滿足。

圖片處理

首先將圖片做一些劃分。例如以500k作為分界,小于500k為小圖片,否則是大圖片。對于小圖片,我們需要做如下判斷:

  1. 頁面是否重復使用?是就用雪碧圖,否則轉base64.
  2. 對于大圖片,可以進行壓縮后使用。

base64可以用webpack的url-loader替換。
舉個例子

require('url?limit=250!./xxx.png')
//這里就會使用url-loader,假如圖片小于250,就會轉為base64

移動端適配

對于適配,我所知比較好的方法是利用rem作為單位,將頁面寬度等分成10個rem,根據頁面動態的用js去改變font-size,達到適配不同瀏覽器的目的。例如愛瘋寬320px,那么font-size設置為32px。那么10rem就是等于整個屏幕的寬度。但是有一個特例就是高清屏,一般高清屏的物理像素是實際像素的2倍,那么當你想顯示一個寬度為1的邊框時,在普通屏幕是1px,在高清屏可以有0.5px(問題是很多瀏覽器不支持,為將0.5px認為是0)。雖然都使用1px在兩者屏幕上實際上是一樣的,但是高清屏里的1px在射雞師眼里是無法達到他對于1的要求的。于是就有一些解決方案,比較簡單是是使用transform:scale(0.5)。那么還有一種解決方案就是阿里的移動端解決方案,原理是將頁面整體scale縮小,然后放大font-size,來保證rem為單位的布局不變,但是px為單位的會被縮小。

性能提升

首先先確定需求,確實有這個需求的時候再談。

懶加載

webpack其實會幫我們做第三方依賴的懶加載處理,那么針對react,我們可以通過現成的庫來實現懶加載react-lazyload,或者使用webpack現成的

require.ensure([],()=>{
require('public.js')
})

來實現。

shouldComponentUpdate

其實這個鉤子可以極大的幫助我們去提升性能,由于它的存在,我們可以自己判斷哪些是我們組件需要的state,哪些是不需要的,那么這就可以阻止react進行不必要diff。但是有一個問題就是對于對象我們很難去判斷他們是否相等,那么可以通過immutableJs的fromJS和is方法來解決這個問題。其實immutableJs的好處遠不止于此,目前我也尚在填坑中。

使用不可變數據,可以更好的達到函數式編程,不僅利于單元測試,也更有利于后期維護整個大的state。因為他的不可變特點,我們不會在不經意見不小心改變了state,而引起不必要的問題。

創建組件的痛點

為了使組件中的css作用域相互獨立,一般采用Css Module,那么為了使組件看上去更像組件,并且易于后期維護,一般我們會這樣結構化組件文件:

folder.png

那么對于每一個初始的jsx,我們大多會這樣初始化

import s from './App.scss'
import{Component} from 'react';//得到組件方法

class App extends Component{
  
  render(){
    return (
      <div className={s.container}>
      </div>
    )
  } 
}
export default App;


不難發現,對于每一個組件,我都需要去手動的創建這些文件和文件夾,而這些操作其實是重復且無意義的勞動,于是我造了一個小輪子,一個命令行小工具,來解決這個痛點。
react-component-maker,歡迎猛戳點star!

結語

困了,本寶寶要睡覺了,還有的內容下次再說吧,再見。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容