特贊·苑永志——React Native in Tezign


苑永志 ? 特贊前端總監(jiān)猜惋,技術(shù)愛好廣泛丸氛,做過Java,寫過頁面著摔,正在搞Node.js缓窜。目前負責(zé)特贊前端團隊的人才培養(yǎng)和特贊服務(wù)網(wǎng)關(guān)的開發(fā)、維護谍咆。喜歡羽毛球禾锤、籃球等各種球類運動。


這是苑永志老師在7.8日iTechPlus前端大會上講的內(nèi)容摹察,整理如下:

特贊是從2016年末才開始著手APP的開發(fā)恩掷。記得那是距離過年還有一個月不到的時候,產(chǎn)品突然提出一個需求說港粱,咱們要不做一個iOS應(yīng)用吧螃成,快過年了,給設(shè)計師一個新年禮物吧查坪。當(dāng)時我的內(nèi)心其實是拒絕的寸宏,于是我面帶微笑著說:“好啊,我們盡量吧偿曙。氮凝。⊥洌”罩阵。iOS工程師是不指望了,既然是大前端启摄,那就得什么都能搞……于是稿壁,我們開始調(diào)研蘋果應(yīng)用的審核發(fā)布流程,熱更新歉备,具體的實現(xiàn)細節(jié)傅是。為了趕上蘋果的審核,兩周的時候蕾羊,我們發(fā)布了我們的第一個初始版本喧笔,剩下的2周時間,我們完成了剩余所有功能的開發(fā)龟再,并通過熱更新發(fā)布到了線上书闸。我們用不到一個月的時間,完成了特贊原生iOS的開發(fā)利凑。

好浆劲,來感受一下嫌术,我們做出來的一些成果。第一幅是項目列表頁梳侨,然后是項目列表蛉威,報價列表,報價詳情(看到上面的金額沒有走哺,在特贊做設(shè)計師還是很是賺頭的哦 :) )蚯嫌。這個是對話也,通過這個丙躏,設(shè)計師和客戶可以進行實時的溝通择示,這也是我們APP的一個亮點功能。

可能前端的同學(xué)都知道晒旅,使用React的話栅盲,我們是通過聲明式的方式定義組件,而后通過虛擬DOM在瀏覽器環(huán)境下废恋,進行UI的渲染和數(shù)據(jù)的加載谈秫。React的使用已經(jīng)應(yīng)用到了PC頁面,移動頁面鱼鼓,甚至服務(wù)端渲染等場景下拟烫。隨著React Native的推出,我們前端的同學(xué)通過React更是擁有了開發(fā)iOS和Android應(yīng)用的能力迄本。記住硕淑,這真的是,真的原生應(yīng)用嘉赎!還記的React的官方slogan嗎置媳?Learn once, write anywhere. 翻譯成中文就是,一次學(xué)習(xí)公条,到處挖坑 : ) 先挖好坑拇囊,至于誰去填,這就是后話了 : )

至于為什么選擇React Native呢靶橱?首先呢寂拆,剛才提到過,通過RN開發(fā)的應(yīng)用抓韩,只要優(yōu)化得當(dāng),幾乎是可以無限接近Native應(yīng)用的交互操作體驗的鬓长,所以說谒拴,手感非常絲滑,讓人愛不釋手涉波。然后就是英上,RN開發(fā)出來的應(yīng)用炭序,他的功能和性能都是很不錯的。還有一點苍日,對我們前端開發(fā)人員來說惭聂,真的是一個福音,那就是相恃,RN可以直接通過Chrome進行調(diào)試辜纲,分分鐘讓你欲罷不能。退一步說拦耐,因為我們團隊本身是React技術(shù)棧耕腾,所以選擇RN是一個很自然的過程,適應(yīng)的過程也非常的短暫杀糯。最后扫俺,也是影響我們抉擇的一個因素就是,RN除了可以像WEB一樣進行開發(fā)固翰,還可以擁有WEB一樣的發(fā)布能力狼纬,只要通過熱更新就可以簡單的做到,后面的部門我們會著重提到這個特性骂际。

本次的分享呢疗琉,主要圍繞RN開發(fā)前后我們涉及到的方方面進行探討。包括開發(fā)前我們會重點考慮的調(diào)試方援、路由没炒、數(shù)據(jù)管理、組件選型等問題犯戏;開發(fā)過程中送火,我們則是要解決動畫、緩存先匪、手勢种吸、支付等問題;業(yè)務(wù)功能開發(fā)完畢之后呀非,則要關(guān)注消息推送坚俗、異常監(jiān)控、熱更新岸裙、性能優(yōu)化這些可能更加重要的話題猖败。好,那我們就一一展開來討論這些東西降允。

相信前端的同學(xué)看到這個圖都會感覺的很親切恩闻,當(dāng)調(diào)試工作能夠通過Chrome的DevTools進行是,一切都似乎變得簡單起來了剧董。我們可以進行熟悉的斷點調(diào)試幢尚,變量審查破停;我們還可以結(jié)合React、Redux的Chrome插件直觀的查看組件結(jié)構(gòu)和整個工程的數(shù)據(jù)變化尉剩。盡管如此真慢,還是有2個小坑值得一提,一旦應(yīng)用live reload之后理茎,斷點調(diào)試就會失效黑界,要重新reload應(yīng)用才能恢復(fù);另外一個就是調(diào)試過程中保證DevTools所在TAB在最前面功蜓,否則APP會瞬間變得卡頓园爷。

React在WEB上可以通過react-router來管理路由,不夠在RN中式撼,路由管理變得更簡單童社。通過Navigator組件,我們把所有的Scene著隆、場景扰楼、或者頁面通過一個堆棧管理起來,頁面的操作就是簡單的出棧入棧操作美浦。比如最初我們處于home頁弦赖,接著我們push到對話列表頁,再push到對話詳情浦辨、項目列表頁蹬竖,然后我們又可以pop回對話詳情頁。當(dāng)然實際情況可能還要復(fù)雜一點流酬,

比如往回跳多個頁面币厕,跳回到指定頁面等等,這一切都是針對一個堆棧來進行操作的芽腾。所有這一切我們都可以用類似下面的一行代碼來實現(xiàn):

通過Navigator組件對象的引用旦装,我們可以跳轉(zhuǎn)到對話列表(chat)頁面,與此同時摊滔,我們帶上項目ID阴绢,設(shè)計師ID等參數(shù),這些參數(shù)我們在chat頁面中很容易獲得艰躺。

使用React做過Web開發(fā)的同學(xué)知道呻袭,我們往往通過Redux把數(shù)據(jù)集中管理起來。在RN中腺兴,不同的點在于棒妨,我們希望數(shù)據(jù)能夠被持久化,以免每次應(yīng)用重啟之后,所有數(shù)據(jù)又要重新加載券腔。AsyncStorage能夠很方便跟Redux集成到一起,后面會講到AsyncStorage的具體應(yīng)用拘泞,這里先不展開來說了纷纫。

OK,下面是組件部分陪腌。組件也是我們是否選擇一個前端框架的重要因素辱魁。RN框架本身給我們提供很多實用的組件,像列表诗鸭、觸摸操作染簇、導(dǎo)航、圖片等强岸,這些還遠遠不夠锻弓。所幸的RN社區(qū)是異常活躍的蝌箍,真是只有我們想不到青灼,沒有做不到的組件 : ) 大家可以簡單瀏覽一下,像輪播妓盲、側(cè)滑杂拨、文件上傳…… 我們直接拿來主義就可以了。

以上的部分悯衬,我們都是在一些準(zhǔn)備調(diào)研弹沽,真正的挑戰(zhàn)才剛剛開始。大家來看筋粗,這是一個報價列表的頁面策橘,動起來了!沒有卡頓亏狰,沒有掉幀役纹,有木有,這手感暇唾,大家有沒有想上手摸一把 :) 在對話列表內(nèi)部促脉,還可以通過上滑直接將列表中的一項放大成全屏,繼續(xù)上滑策州,TabBar還可以置頂瘸味,并且可以進行滑動切換操作,下滑又可以退出全屏够挂。我剛拿到這個交互需求之后旁仿,我是一臉懵逼的。那我們就一起來看一下通過RN的動畫和手勢能不能實現(xiàn)這些交互。

在WEB頁面中枯冈,我們通過CSS3動畫毅贮,像transition、animation等可以方便的實現(xiàn)很多過渡和動畫效果尘奏。JS層面滩褥,我們也可以使用requestAnimationFrame來進行動畫操作,實際上很多動畫庫就是基于它來進行封裝的炫加。在RN沒辦法通過過渡瑰煎,動畫幀來實現(xiàn)動畫,但是RN框架給我們提供更為精細的動畫支持俗孝。我們來一張圖:

Animated組件能夠用于實現(xiàn)精細體驗酒甸,友好的交互動畫。我們可以通過定義特定的Value作為動畫變化的參數(shù)赋铝,而這些動畫可以是隨時間漸變的插勤,彈跳的,或者有加速度的柬甥。動畫的可以是單個的饮六,也可以是多個動畫進行組合,比如說并行苛蒲、順序卤橄、交錯的方式進行組合。這些動畫都必須應(yīng)用在特定的動畫組件之上臂外,除了內(nèi)置一些動畫組件窟扑,我們還可以根據(jù)需要自定義動畫組件。動畫的過程中漏健,我們還可以進行跟蹤嚎货,根據(jù)Animated.event對象獲得動畫過程中的相關(guān)變量。實際上蔫浆,通過剛才說的這些殖属,實現(xiàn)一些常規(guī)的動畫效果已經(jīng)游刃有余了。下面我們通過幾個代碼片段瓦盛,直觀的感受一下洗显。

首先我們定義一個動畫的值opacityValue用于記錄透明度的變化。然后將這個值應(yīng)用于Animated.Image組件的style屬性之上原环,這跟我們書寫內(nèi)聯(lián)樣式?jīng)]有什么卻別挠唆,只不過opacity的值是我們定義的特定類型的動畫值。那我們?nèi)绾斡|發(fā)這個圖片的透明度動畫呢嘱吗?我們使用Animated.timing對透明度進行一個線性的操作玄组,第一個參數(shù)是我們定義的值,第二個是指定動畫完結(jié)時的值,持續(xù)時間俄讹,變化虛線哆致。綜合起來就是說,在4秒鐘之內(nèi)患膛,圖片的透明度將會由0線性的變化成1沽瞭。在動畫完成之后,我們還可以在回調(diào)中做一些事情剩瓶。這是一個很有用的操作,我們可以把動畫和業(yè)務(wù)操作錯開來城丧,避免動畫和數(shù)據(jù)操作同時占用資源延曙,造成卡頓。

除了剛才介紹的精細控制亡哄,RN也提供了粗粒度的動畫控制 LayoutAnimation枝缔,我們可以把多個動畫值,一次變化到另一個狀態(tài)蚊惯,具體的動畫效果交由框架去完成愿卸。簡單的動畫,我們可以這么做截型,但是一旦復(fù)雜起來趴荸,我們還是會更加傾向于使用Animated去做控制。

RN的組件還給我們提供了一個很有意思的接口叫做 setNativeProps宦焦,顧名思義就是設(shè)置原生組件的屬性发钝,這就類似于我們在WEB中直接操作DOM,結(jié)合起requestAnimationFrame有可能讓你爽到波闹。一般情況下酝豪,我們都不建議你這么去用,因為脫離了框架的操作會讓程序變得失控精堕,除非你自己知道自己在干什么孵淘,還有就是別忘了寫上顯著的注釋!

一般情況下歹篓,動畫都是伴隨著手勢產(chǎn)生的瘫证。RN中很很多組件都對手勢操作進行了封裝,比如Touch打頭的組件滋捶,對觸摸操作進行了處理痛悯,ScrollView中的onScroll是對滑動操作進行了封裝。RN中的事件也是分為捕獲重窟、目標(biāo)和冒泡三個階段载萌,在各個階段,我們都可以進行一些操作,比如判斷是否需要響應(yīng)事件扭仁,我們可以在子組件之前響應(yīng)事件垮衷,也可以在子組件之后響應(yīng)事件;我們可以處理簡單的觸摸事件乖坠,也可以處理滑動操作搀突。

有的情況下,我們需要把多個手指的操作熊泵,協(xié)調(diào)成一個單點操作仰迁,這是我們需要使用PanResponser。這與我們剛剛提到的事件處理非常類似顽分,因此不再贅述徐许。

我們通過一個例子來直觀的感受一下手勢操作的處理。我們不區(qū)分單個手指或者多個手指卒蘸,因此我們使用PanRespnsor來處理雌隅,在onMoveShouldSetPanResponser中,我們判斷手指(可能是一個缸沃,也可能是多個) 滑動時恰起,組件是否需要響應(yīng)該手勢。接下來基本就是一些業(yè)務(wù)判斷趾牧,比如正在加載數(shù)據(jù)检盼、水平方向上有滾動、正處于加載完畢提示頁武氓、水平位移大于豎直位移時梯皿,則不需要處理;如果是全屏县恕,向下滑動時东羹,需要響應(yīng);如果是列表狀態(tài)忠烛,向上滑動需要響應(yīng)属提。當(dāng)然,這里僅僅是手勢響應(yīng)的一部分美尸,還需要其他很多配合才能將手勢和動畫組合起來冤议。

之前我們提到過AsyncStore可以和Redux起來配合起來使用,實際上师坎,所有需要進行持久化緩存的數(shù)據(jù)都可以使用AsyncStorage來進行操作恕酸。為什么是AsyncStorage鞭光?我們知道芽丹,localStorage也能進行持久化緩存,但是它的接口是同步的庆揪。在JS單線程模型中,耗時的阻塞IO操作是很蛋疼的 :) 所以AsyncStorage正是為了取代localStorage而出現(xiàn)的义矛,使用異步在JS中是最佳實踐发笔。

不過,我們一般不建議直接使用AsyncStorage凉翻,因為它存儲的內(nèi)容都是字符串了讨,我們不想每次操作的時候都進行序列化,反序列化制轰,同時還要捕捉異常前计。所以我們通常把存取操作封裝起來,如果有必要垃杖,也可以加上命名空間來區(qū)分不同的數(shù)據(jù)資源残炮。

除了數(shù)據(jù)緩存,在APP上缩滨,圖片等資源的還原顯得格外重要,用戶不希望一個10M的APP在多次使用后莫名其妙的變成了1個G泉瞻,占用了用戶的內(nèi)存脉漏,也浪費了”不菲”的流量。對于圖中這樣地址不會變更的圖片袖牙,我們只要使用一個圖片組件就可以將圖片的資源的緩存起來侧巨,避免重復(fù)下載。

而對于七牛資源這樣動態(tài)變化的地址鞭达,剛才的方案就不可行了司忱。為了保證設(shè)計師資源的安全性,我們每次給到客戶的資源都是一個帶有token標(biāo)識的鏈接畴蹭,而這個鏈接很快就會過期坦仍,這就意味著同樣一張圖片,也會重復(fù)進行下載叨襟,這是很恐怖的一件事情繁扎。不過我們看到每個七牛資源的key是不變的,比如途中的“5483389ab...”部分糊闽,那我們就可以利用這個key去判斷梳玫,是否需要下載,還是從文件系統(tǒng)中直接讀取該圖片右犹。

具體的實現(xiàn)中提澎,我們用到了react-native-fetch-blob組件,他可以配置資源下載后的存儲路徑念链,然后根據(jù)這個路徑盼忌,就可以從本地文件系統(tǒng)中直接讀取到該圖片积糯,從而實現(xiàn)了對非固定路徑資源的緩存。

為了實現(xiàn)資金的閉環(huán)碴犬,支付是必不可少的一個功能絮宁。在Web端,我們使用的Ping++的支付服務(wù)服协,當(dāng)我們知道Ping++沒有RN的SDK時绍昂,差點嚇尿了 :) 萬幸的他們內(nèi)部正在研發(fā)的RN的SDK,而且最終經(jīng)歷各種坎坷偿荷,把我們的第一筆錢付出去了窘游。所以,做前端同學(xué)跳纳,如果發(fā)現(xiàn)你身邊有搞Native的忍饰,趕緊和他成為好基友,關(guān)鍵的時候寺庄,他會拔刀相助艾蓝,救你于水深火熱之中的。

有了開發(fā)前的準(zhǔn)備工作斗塘,也攻克了開發(fā)過程中的種種問題赢织,一個APP就基本開發(fā)出來 了,它應(yīng)該包含了你需要的主要業(yè)務(wù)流程馍盟,這是我們終于可以細細把玩于置,愛不釋手了。然而好景不長贞岭,你會發(fā)它他竟然會崩潰八毯,卡頓,而且也不容易定位到原因瞄桨;消息推送也是必備功能话速。

消息推送的流程比較簡單,如果是iOS應(yīng)用芯侥,首先我們需要使用蘋果開發(fā)者賬號申請一張證書尿孔,iOS APP可以獲得設(shè)備token, 后臺結(jié)合token和證書可以申請消息推送的請求,獲得授權(quán)之后筹麸,就可以調(diào)用推送接口活合,直接推送必要的消息既可。

在開始討論異常監(jiān)控之前物赶,我們最好了解異常發(fā)生的原因白指。這是RN在Android和iOS兩個平臺上的架構(gòu),最上層是打出的安裝包酵紫,可以運行在對應(yīng)的操作系統(tǒng)上告嘲。中間部分是我們書寫的JS代碼错维,在往下是原生組件和核心類庫部分。以上橄唬,我們可以大致看出可能的異常來源:用戶業(yè)務(wù)代碼產(chǎn)生的異常赋焕,這部分屬于JS異常;JS模塊和Native相互調(diào)用可能產(chǎn)生的異常仰楚,我們稱之為Native異常隆判;還有組件渲染過程中產(chǎn)生的異常,這部分叫做UI異常僧界。我們分別看一下各自異常的處理方式侨嘀。

全局的JS異常,可以通過react-native模塊中的ErrorUtils工具類來捕獲捂襟。也可以通過模塊react-native-exception-handler來統(tǒng)一處理JS異常咬腕,比如記錄的日志系統(tǒng)。

通過RN Android框架的源代碼葬荷,我們可以找到對應(yīng)Native異常和UI異常的錯誤處理涨共,這就意味著我們可以通過修改源碼來自定義異常的處理方式。不過這就意味著宠漩,一旦升級RN版本煞赢,我們就需要做出相應(yīng)的修改,這會帶來維護成本哄孤。

也許這些對于你來說有些復(fù)雜,那也可以使用像bugly這樣的異常監(jiān)控平臺吹截,不僅可以隨時監(jiān)控APP的崩潰瘦陈、卡頓和錯誤等發(fā)生的情況,也可以清晰的知道用戶和手機的分布情況波俄。

我們知道JS可以通過應(yīng)用內(nèi)的JS引擎動態(tài)解釋執(zhí)行晨逝。所以無論我們的源代碼做了多大的修改,只要無需構(gòu)建懦铺,我們都可以通過熱更新動態(tài)的推送到用戶的手機上捉貌。這個過程大致如下:當(dāng)用戶的APP啟動或喚醒的時候,檢查APP內(nèi)的bundle和圖片資源是否是最新的冬念,如果不是趁窃,則從熱更新服務(wù)器加載最新的bundle和圖片。實際情況可能要稍微復(fù)雜一點急前。

在用戶的APP這邊醒陆,我們需要檢查bundle版本,進行下載裆针、解壓刨摩、reload操作寺晌。如果是增量更新,還要進行bundle合并澡刹。對于熱更新服務(wù)器呻征,我們要針對Android和iOS提供不同的bundle版本,每次發(fā)布或者更新時都需要打包發(fā)布對應(yīng)的bundle版本罢浇;如果是增量提供bundle patch版本陆赋,還要對bundle進行拆分。哈己莺,所以的這些都做出來奏甫,工作量可能甚至要超過APP開發(fā)本身的工作量了 :( 所以有沒有現(xiàn)成的方案呢?

顯然是有的凌受,我們目前使用的是微軟提供CodePush熱更新服務(wù)阵子,只要簡單注冊配置,然后在APP端引入CodePush的客戶端插件胜蛉,就可以完成剛剛提到的那么多工作挠进。他還提供了版本的出錯回退機制。不過訪問速度是它的缺點誊册,如果每次更新需要幾十M甚至上百M领突,那就要斟酌一下了,目前來看案怯,我們使用起來感覺還是很爽的君旦。

最后,也可能是最重要的一塊內(nèi)容是性能優(yōu)化嘲碱。所為天下武功金砍,唯快不破,如何讓我們的應(yīng)用快起來時優(yōu)化的關(guān)鍵麦锯。下面我們從加速速度恕稠、滾動速度和響應(yīng)速度三個方面來提供一些優(yōu)化建議。

加速速度帶來的是給用戶的既視體驗扶欣,如果避免白屏鹅巍,把數(shù)據(jù)和頁面第一時間呈現(xiàn)給用用戶是關(guān)鍵。首先我們考慮的是從緩存中加載往次訪問數(shù)據(jù)料祠,然后異步加載去加載最新的數(shù)據(jù)骆捧。如果是對實時性要求并不是很高的數(shù)據(jù),我們可以使用Redux中統(tǒng)一管理的數(shù)據(jù)髓绽,之前我們提到過凑懂,這一部分數(shù)據(jù)我們也做了持久化緩存。

大列表在應(yīng)用中必會出現(xiàn)的部分梧宫,而列表本身操作又特別復(fù)雜和頻繁接谨,這就導(dǎo)致列表內(nèi)的組件會重復(fù)渲染摆碉,這會帶來極大的性能消耗,通過使用shouldComponentUpdate我們可以判斷組件是否需要渲染脓豪,從而阻止不必要的渲染——這很簡單巷帝,也非常有效。除此之外扫夜,ListView列表組件本身也提供了一些配置來提高渲染效率楞泼,比如首屏加載的數(shù)量、可視部分的數(shù)量笤闯。如果大家剛剛開始使用RN堕阔,恭喜你,你可以使用FlatList組件颗味,列表的操作變得簡單超陆,性能也非常出色。

最后浦马,我們看如何提升響應(yīng)速度时呀。在Navigator頁面切換后,如果需要通過網(wǎng)絡(luò)加載數(shù)據(jù)晶默,很容易造成轉(zhuǎn)場動畫的卡頓谨娜,這是因為業(yè)務(wù)邏輯和UI渲染邏輯出現(xiàn)了交錯。RN提供了InteractionManager讓我們?nèi)ヌ幚磉@樣的情況磺陡,我們只要把業(yè)務(wù)邏輯放到runAfterInteractions方法的回調(diào)中去執(zhí)行就可以確保轉(zhuǎn)場動畫的完整展示趴梢。對于按鈕點擊或其他的一些位操作可能也會出現(xiàn)類似情況,處理的方式也是大同小異币他,requestAnimationFrame的回調(diào)使得交互和業(yè)務(wù)邏輯能夠錯開坞靶。實際上,上面提到的卡頓丟幀始作俑者都是JS單線程圆丹,如果我們使用setNativeProps就可以跳出這個模型,那是那句話躯喇,除非你知道自己在做什么辫封,否則不要這么做。

當(dāng)然還會有很多其他的優(yōu)化建議廉丽,我沒有辦法完整列舉下來倦微。實際上,如果大家按照上面給出的建議去做了優(yōu)化正压,APP的體驗應(yīng)該已經(jīng)很不錯了欣福。但凡事無絕對,實在快不起來的時候焦履,我們別忘了把Loading效果用起來 :) 這會讓用戶愿意多等一會拓劝。

至此雏逾,我的分享就差不多了。剛才我們看了開始開發(fā)APP之前我們的一些準(zhǔn)備郑临,開發(fā)過程中我們需要理解的一些重要概念栖博,也分享了一些異常監(jiān)控、熱更新厢洞、性能優(yōu)化的等方面的東西仇让。希望我剛才分享的內(nèi)容能夠給大家?guī)硪稽c幫助和啟發(fā)!謝謝大家躺翻!

啊丧叽, 忘了,還有廣告時間公你。先介紹一下我自己踊淳,我以前是Java工程師,最近今年一直在做前端相關(guān)工作省店,現(xiàn)在主要負責(zé)特贊服務(wù)網(wǎng)關(guān)的開發(fā)和維護工作嚣崭。我們公司還有前端名額,有意向的趕緊騷擾我 :) 如果大家對React和React Native有興趣懦傍,也可以來參加我的課程雹舀,機會難得,不要錯過粗俱,兩天只要 999 :)






最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末说榆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子寸认,更是在濱河造成了極大的恐慌签财,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偏塞,死亡現(xiàn)場離奇詭異唱蒸,居然都是意外死亡,警方通過查閱死者的電腦和手機灸叼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門神汹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人古今,你說我怎么就攤上這事屁魏。” “怎么了捉腥?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵氓拼,是天一觀的道長。 經(jīng)常有香客問我,道長桃漾,這世上最難降的妖魔是什么坏匪? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮呈队,結(jié)果婚禮上剥槐,老公的妹妹穿的比我還像新娘。我一直安慰自己宪摧,他們只是感情好粒竖,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著几于,像睡著了一般蕊苗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沿彭,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天朽砰,我揣著相機與錄音,去河邊找鬼喉刘。 笑死瞧柔,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的睦裳。 我是一名探鬼主播造锅,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼廉邑!你這毒婦竟也來了哥蔚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤蛛蒙,失蹤者是張志新(化名)和其女友劉穎糙箍,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牵祟,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡深夯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了诺苹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咕晋。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筝尾,靈堂內(nèi)的尸體忽然破棺而出捡需,到底是詐尸還是另有隱情办桨,我是刑警寧澤筹淫,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響损姜,放射性物質(zhì)發(fā)生泄漏饰剥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一摧阅、第九天 我趴在偏房一處隱蔽的房頂上張望汰蓉。 院中可真熱鬧,春花似錦棒卷、人聲如沸顾孽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽若厚。三九已至,卻和暖如春蜒什,著一層夾襖步出監(jiān)牢的瞬間测秸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工灾常, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留霎冯,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓钞瀑,卻偏偏與公主長得像沈撞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子仔戈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容