JS引擎運(yùn)行機(jī)制

JS引擎運(yùn)行機(jī)制

-- 原地址(自己學(xué)習(xí)記錄): https://juejin.im/post/5a6547d0f265da3e283a1df7#heading-6

解決的面試問(wèn)題

  1. 瀏覽器包含的進(jìn)程

  2. 瀏覽器內(nèi)核: 渲染引擎 + JS引擎(V8引擎)

  3. render進(jìn)程(瀏覽器內(nèi)核)包含的進(jìn)程

  4. 為何JS阻塞線程會(huì)導(dǎo)致頁(yè)面渲染阻塞

  5. 從輸入url開(kāi)始到渲染, 瀏覽器做了什么

  6. CSS阻塞DOM樹(shù)的渲染

  7. 任務(wù)隊(duì)列, 宏任務(wù), 微任務(wù)的執(zhí)行順序等等

大綱

  • 區(qū)分進(jìn)程和線程

    • 瀏覽器是多進(jìn)程的

    • 瀏覽器都包含哪些進(jìn)程拯欧?

    • 瀏覽器多進(jìn)程的優(yōu)勢(shì)

    • 重點(diǎn)是瀏覽器內(nèi)核(渲染進(jìn)程)

    • Browser進(jìn)程和瀏覽器內(nèi)核(Renderer進(jìn)程)的通信過(guò)程

  • 梳理瀏覽器內(nèi)核中線程之間的關(guān)系

    • GUI渲染線程與JS引擎線程互斥

    • JS阻塞頁(yè)面加載

    • WebWorker栅螟,JS的多線程?

    • WebWorker與SharedWorker

  • 簡(jiǎn)單梳理下瀏覽器渲染流程

    • load事件與DOMContentLoaded事件的先后

    • css加載是否會(huì)阻塞dom樹(shù)渲染态罪?

    • 普通圖層和復(fù)合圖層

  • 從Event Loop談JS的運(yùn)行機(jī)制

    • 事件循環(huán)機(jī)制進(jìn)一步補(bǔ)充

    • 單獨(dú)說(shuō)說(shuō)定時(shí)器

    • setTimeout而不是setInterval

  • 事件循環(huán)進(jìn)階:macrotask與microtask

區(qū)分進(jìn)程和線程


  - 進(jìn)程是一個(gè)工廠,工廠有它的獨(dú)立資源 -> 系統(tǒng)分配的內(nèi)存(獨(dú)立的一塊內(nèi)存)

  - 工廠之間相互獨(dú)立 -> 進(jìn)程之間相互獨(dú)立

  - 線程是工廠中的工人察藐,多個(gè)工人協(xié)作完成任務(wù) -> 多個(gè)線程在進(jìn)程中協(xié)作完成任務(wù)

  - 工廠內(nèi)有一個(gè)或多個(gè)工人 -> 一個(gè)進(jìn)程由一個(gè)或多個(gè)線程組成

  - 工人之間共享空間 - -> 同一進(jìn)程下的各個(gè)線程之間共享程序的內(nèi)存空間(包括代碼段歪脏、數(shù)據(jù)集、堆等)

windows系統(tǒng)

-- 打開(kāi)任務(wù)管理器技扼,可以看到有一個(gè)后臺(tái)進(jìn)程列表, 瀏覽器打開(kāi)多個(gè)進(jìn)程, 以及每個(gè)進(jìn)程內(nèi)存資源信息以及cpu占有率伍玖。

  • 進(jìn)程是cpu資源分配的最小單位(是能擁有資源和獨(dú)立運(yùn)行的最小單位)

  • 線程是cpu調(diào)度的最小單位(線程是建立在進(jìn)程的基礎(chǔ)上的一次程序運(yùn)行單位,一個(gè)進(jìn)程中可以有多個(gè)線程)

tips

  • 不同進(jìn)程之間也可以通信剿吻,不過(guò)代價(jià)較大

  • 現(xiàn)在窍箍,一般通用的叫法:?jiǎn)尉€程與多線程,都是指在一個(gè)進(jìn)程內(nèi)的單和多丽旅。(所以核心還是得屬于一個(gè)進(jìn)程才行)

瀏覽器是多進(jìn)程的

  1. 瀏覽器的簡(jiǎn)化理解

    • 瀏覽器是多進(jìn)程的
    • 瀏覽器之所以能夠運(yùn)行椰棘,是因?yàn)橄到y(tǒng)給它的進(jìn)程分配了資源(cpu、內(nèi)存)
    • 簡(jiǎn)單點(diǎn)理解榄笙,每打開(kāi)一個(gè)Tab頁(yè)邪狞,就相當(dāng)于創(chuàng)建了一個(gè)獨(dú)立的瀏覽器進(jìn)程。
  2. 任務(wù)管理器

    Chrome瀏覽器打開(kāi)多個(gè)標(biāo)簽頁(yè), 在***任務(wù)管理器***中看到有多個(gè)進(jìn)程(一個(gè)Tab頁(yè)面一個(gè)獨(dú)立進(jìn)程外加一個(gè)主程)

    瀏覽器有自己的優(yōu)化機(jī)制, 打開(kāi)多個(gè)空白頁(yè)面時(shí)候, 其實(shí)共用一個(gè)進(jìn)程

7.png

瀏覽器包含的進(jìn)程

  1. Browser進(jìn)程:瀏覽器的主進(jìn)程(負(fù)責(zé)協(xié)調(diào)茅撞、主控)帆卓,只有一個(gè), 作用有

    • 負(fù)責(zé)瀏覽器界面顯示,與用戶(hù)交互米丘。如前進(jìn)剑令,后退等

    • 負(fù)責(zé)各個(gè)頁(yè)面的管理,創(chuàng)建和銷(xiāo)毀其他進(jìn)程

    • 將Renderer進(jìn)程得到的內(nèi)存中的Bitmap蠕蚜,繪制到用戶(hù)界面上

    • 網(wǎng)絡(luò)資源的管理尚洽,下載等

  2. 第三方插件進(jìn)程:每種類(lèi)型的插件對(duì)應(yīng)一個(gè)進(jìn)程,僅當(dāng)使用該插件時(shí)才創(chuàng)建

  3. GPU進(jìn)程:最多一個(gè)靶累,用于3D繪制等

  4. 瀏覽器渲染進(jìn)程(瀏覽器內(nèi)核)(Renderer進(jìn)程腺毫,內(nèi)部是多線程的):默認(rèn)每個(gè)Tab頁(yè)面一個(gè)進(jìn)程,互不影響挣柬。主要作用為

    • 頁(yè)面渲染潮酒,腳本執(zhí)行,事件處理等

瀏覽器多進(jìn)程的優(yōu)勢(shì)

-- 相對(duì)于單進(jìn)程, 多進(jìn)程的優(yōu)點(diǎn)

  • 避免單個(gè)頁(yè)面崩潰影響整個(gè)瀏覽器

  • 避免第三方插件崩潰影響整個(gè)瀏覽器

  • 多進(jìn)程充分利用多核優(yōu)勢(shì)

  • 方便使用沙盒模型隔離插件等進(jìn)程邪蛔,提高瀏覽器穩(wěn)定性

重點(diǎn)是瀏覽器內(nèi)核(渲染進(jìn)程)

渲染進(jìn)程(多線程)包含的線程(也叫瀏覽器內(nèi)核: 渲染內(nèi)核 + JS內(nèi)核 + 等等)

  1. GUI渲染線程(渲染內(nèi)核)

    • 負(fù)責(zé)渲染瀏覽器界面急黎,解析HTML,CSS,構(gòu)建DOM樹(shù)和RenderObject樹(shù)勃教,布局和繪制等淤击。

    • 當(dāng)界面需要重繪(Repaint)或由于某種操作引發(fā)回流(reflow)時(shí),該線程就會(huì)執(zhí)行

    • 注意故源,GUI渲染線程與JS引擎線程是互斥的污抬,當(dāng)JS引擎執(zhí)行時(shí)GUI線程會(huì)被掛起(相當(dāng)于被凍結(jié)了),GUI更新會(huì)被保存在一個(gè)隊(duì)列中等到JS引擎空閑時(shí)立即被執(zhí)行绳军。

  2. JS引擎線程(JS內(nèi)核)

    • 負(fù)責(zé)處理Javascript腳本程序印机。(例如V8引擎)

    • JS引擎線程負(fù)責(zé)解析Javascript腳本,運(yùn)行代碼门驾。

    • JS引擎一直等待著任務(wù)隊(duì)列(事件隊(duì)列)中任務(wù)的到來(lái)射赛,然后加以處理,一個(gè)Tab頁(yè)(renderer進(jìn)程)中無(wú)論什么時(shí)候都只有一個(gè)JS線程在運(yùn)行JS程序

    • 同樣注意奶是,GUI渲染線程與JS引擎線程是互斥的楣责,所以如果JS執(zhí)行的時(shí)間過(guò)長(zhǎng),這樣就會(huì)造成頁(yè)面的渲染不連貫诫隅,導(dǎo)致頁(yè)面渲染加載阻塞腐魂。

  3. 事件觸發(fā)線程(web api)

    • 用來(lái)控制事件循環(huán)(可以理解,JS引擎自己都忙不過(guò)來(lái)逐纬,需要瀏覽器另開(kāi)線程協(xié)助)

    • 當(dāng)JS引擎執(zhí)行代碼塊如setTimeOut時(shí)(也可來(lái)自瀏覽器內(nèi)核的其他線程,如鼠標(biāo)點(diǎn)擊蛔屹、AJAX異步請(qǐng)求等),會(huì)將對(duì)應(yīng)任務(wù)添加到事件線程中

    • 當(dāng)對(duì)應(yīng)的事件符合觸發(fā)條件被觸發(fā)時(shí)豁生,該線程會(huì)把事件添加到待處理隊(duì)列的隊(duì)尾兔毒,等待JS引擎的處理

    • 注意,由于JS的單線程關(guān)系甸箱,所以這些待處理隊(duì)列中的事件都得排隊(duì)等待JS引擎處理(當(dāng)JS引擎空閑時(shí)才會(huì)去執(zhí)行)

  4. 定時(shí)觸發(fā)器線程

    • 傳說(shuō)中的setInterval與setTimeout所在線程

    • 瀏覽器定時(shí)計(jì)數(shù)器并不是由JavaScript引擎計(jì)數(shù)的,(因?yàn)镴avaScript引擎是單線程的, 如果處于阻塞線程狀態(tài)就會(huì)影響記計(jì)時(shí)的準(zhǔn)確)

    • 因此通過(guò)單獨(dú)線程來(lái)計(jì)時(shí)并觸發(fā)定時(shí)(計(jì)時(shí)完畢后育叁,添加到事件隊(duì)列中,等待JS引擎空閑后執(zhí)行)

    • 注意芍殖,W3C在HTML標(biāo)準(zhǔn)中規(guī)定豪嗽,規(guī)定要求setTimeout中低于4ms的時(shí)間間隔算為4ms。所以, 即便setTimeout設(shè)置為0, 事實(shí)上也是4ms

  5. 異步http請(qǐng)求線程

    • 在XMLHttpRequest在連接后是通過(guò)瀏覽器新開(kāi)一個(gè)線程請(qǐng)求

    • 將檢測(cè)到狀態(tài)變更時(shí)豌骏,如果設(shè)置有回調(diào)函數(shù)龟梦,異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件隊(duì)列中窃躲。再由JavaScript引擎執(zhí)行

8.png

Browser進(jìn)程和瀏覽器內(nèi)核(Render進(jìn)程)的通信過(guò)程

-- 首先, 打開(kāi)瀏覽器, 打開(kāi)任務(wù)管理器, 任務(wù)管理器上有兩個(gè)進(jìn)程(主控進(jìn)程, 一個(gè)是Tab的渲染進(jìn)程)

  • Browser進(jìn)程收到用戶(hù)請(qǐng)求计贰,首先需要獲取頁(yè)面內(nèi)容(譬如通過(guò)網(wǎng)絡(luò)下載資源),隨后將該任務(wù)通過(guò)RendererHost接口傳遞給Render進(jìn)程

  • Render進(jìn)程的RenderHost接口收到消息蒂窒,簡(jiǎn)單解釋后躁倒,交給渲染線程荞怒,然后開(kāi)始渲染

  • 渲染線程接收請(qǐng)求,加載網(wǎng)頁(yè)并渲染網(wǎng)頁(yè)秧秉,這其中可能需要Browser進(jìn)程獲取資源和需要GPU進(jìn)程來(lái)幫助渲染

  • 當(dāng)然可能會(huì)有JS線程操作DOM(這樣可能會(huì)造成回流并重繪)

  • 最后Render進(jìn)程將結(jié)果傳遞給Browser進(jìn)程

  • Browser進(jìn)程接收到結(jié)果并將結(jié)果繪制出來(lái)

9.png

梳理瀏覽器內(nèi)核中線程之間的關(guān)系

GUI渲染線程(渲染內(nèi)核)與JS引擎線程(JS內(nèi)核)互斥

由于JavaScript是可操縱DOM的褐桌,如果在修改這些元素屬性同時(shí)渲染界面(即JS線程和UI線程同時(shí)運(yùn)行),那么渲染線程前后獲得的元素?cái)?shù)據(jù)就可能不一致了

因此為了防止渲染出現(xiàn)不可預(yù)期的結(jié)果福贞,瀏覽器設(shè)置GUI渲染線程與JS引擎為互斥的關(guān)系撩嚼,當(dāng)JS引擎執(zhí)行時(shí)GUI線程會(huì)被掛起, GUI更新則會(huì)被保存在一個(gè)隊(duì)列中等到JS引擎線程空閑時(shí)立即被執(zhí)行挖帘。

JS阻塞頁(yè)面加載

從上述的互斥關(guān)系,可以推導(dǎo)出恋技,JS如果執(zhí)行時(shí)間過(guò)長(zhǎng)就會(huì)阻塞頁(yè)面拇舀。

譬如,假設(shè)JS引擎正在進(jìn)行巨量的計(jì)算蜻底,此時(shí)就算GUI有更新骄崩,也會(huì)被保存到隊(duì)列中,等待JS引擎空閑后執(zhí)行薄辅。 然后要拂,由于巨量計(jì)算,所以JS引擎很可能很久很久后才能空閑站楚,自然頁(yè)面渲染加載阻塞

WebWorker

前文中有提到JS引擎是單線程的脱惰,而且JS執(zhí)行時(shí)間過(guò)長(zhǎng)會(huì)阻塞頁(yè)面,那么JS就真的對(duì)cpu密集型計(jì)算無(wú)能為力么窿春?

所以拉一,后來(lái)HTML5中支持了Web Worker。

MDN的官方解釋是:


  Web Worker為Web內(nèi)容在后臺(tái)線程中運(yùn)行腳本提供了一種簡(jiǎn)單的方法旧乞。線程可以執(zhí)行任務(wù)而不干擾用戶(hù)界面

  一個(gè)worker是使用一個(gè)構(gòu)造函數(shù)創(chuàng)建的一個(gè)對(duì)象(e.g. Worker()) 運(yùn)行一個(gè)命名的JavaScript文件

  這個(gè)文件包含將在工作線程中運(yùn)行的代碼; workers 運(yùn)行在另一個(gè)全局上下文中,不同于當(dāng)前的window

  因此蔚润,使用 window快捷方式獲取當(dāng)前全局的范圍 (而不是self) 在一個(gè) Worker 內(nèi)將返回錯(cuò)誤

這樣理解下:

  • 創(chuàng)建webWorker時(shí),JS引擎向?yàn)g覽器申請(qǐng)開(kāi)一個(gè)子線程(子線程是瀏覽器開(kāi)的尺栖,完全受主線程控制嫡纠,而且不能操作DOM)

  • JS引擎線程與webworker線程間通過(guò)特定的方式通信(postMessage API,需要通過(guò)序列化對(duì)象來(lái)與線程交互特定的數(shù)據(jù)), webWorker可以理解是瀏覽器給JS引擎開(kāi)的外掛, 專(zhuān)門(mén)用來(lái)解決大量計(jì)算問(wèn)題

WebWorker與SharedWorker

  1. WebWorker: 只屬于某個(gè)頁(yè)面, 跟其他Render進(jìn)程不共享, 是瀏覽器內(nèi)核(Render進(jìn)程)創(chuàng)建新的線程來(lái)處理JavaScript程序

  2. SharedWorker: 瀏覽器開(kāi)啟新的進(jìn)程, 所有頁(yè)面共享

  3. SharedWorker由獨(dú)立的進(jìn)程管理延赌,WebWorker只是屬于render進(jìn)

瀏覽器渲染流程

  - 瀏覽器輸入url除盏,瀏覽器主進(jìn)程接管,開(kāi)一個(gè)下載線程皮胡,
  然后進(jìn)行 http請(qǐng)求(略去DNS查詢(xún)痴颊,IP尋址等等操作),然后等待響應(yīng)屡贺,獲取內(nèi)容蠢棱,
  隨后將內(nèi)容通過(guò)RendererHost接口轉(zhuǎn)交給Renderer進(jìn)程

  - 瀏覽器渲染流程開(kāi)始

瀏覽器內(nèi)核拿到內(nèi)容后, 渲染分為幾個(gè)步驟:

  1. 解析html建立dom樹(shù)

  2. 解析css構(gòu)建render樹(shù)(將CSS代碼解析成樹(shù)形的數(shù)據(jù)結(jié)構(gòu)锌杀,然后結(jié)合DOM合并成render樹(shù))

  3. 布局render樹(shù)(Layout/reflow),負(fù)責(zé)各元素尺寸泻仙、位置的計(jì)算

  4. 繪制render樹(shù)(paint)糕再,繪制頁(yè)面像素信息

  5. 瀏覽器會(huì)將各層的信息發(fā)送給GPU,GPU會(huì)將各層合成(composite)玉转,顯示在屏幕上突想。

渲染完成之后就是load事件(windows.onload)

load事件與DOMContentLoaded事件

  1. DOMContentLoaded事件: 僅當(dāng)DOM加載完成,不包括樣式表

  2. load事件: 頁(yè)面上所有的DOM究抓,樣式表猾担,腳本,圖片都已經(jīng)加載完成了刺下。 (渲染完畢了)

css加載是否會(huì)阻塞dom樹(shù)渲染

這里說(shuō)的是頭部引入css的情況

由于css是由單獨(dú)的下載線程異步下載的绑嘹。 然后

  • css加載不會(huì)阻塞DOM樹(shù)解析(異步加載時(shí)DOM照常構(gòu)建)

  • 但會(huì)阻塞render樹(shù)渲染(渲染時(shí)需等css加載完畢,因?yàn)閞ender樹(shù)需要css信息)
    這可能也是瀏覽器的一種優(yōu)化機(jī)制橘茉。

因?yàn)槟慵虞dcss的時(shí)候工腋,可能會(huì)修改下面DOM節(jié)點(diǎn)的樣式,
如果css加載不阻塞render樹(shù)渲染的話畅卓,那么當(dāng)css加載完之后擅腰,
render樹(shù)可能又得重新重繪或者回流了,這就造成了一些沒(méi)有必要的損耗翁潘。
所以干脆就先把DOM樹(shù)的結(jié)構(gòu)先解析完趁冈,把可以做的工作做完,然后等你css加載完之后唐础,
在根據(jù)最終的樣式來(lái)渲染render樹(shù)箱歧,這種做法性能方面確實(shí)會(huì)比較好一點(diǎn)。

普通圖層和復(fù)合圖層

  1. 普通文檔流內(nèi)可以理解為一個(gè)復(fù)合圖層, absolute(fixed)也都默認(rèn)是跟普通文檔流在同一復(fù)合圖層中

  2. 如果a是一個(gè)復(fù)合圖層一膨,而且b在a上面呀邢,那么b也會(huì)被隱式轉(zhuǎn)為一個(gè)復(fù)合圖層,這點(diǎn)需要特別注意

  3. GPU中豹绪,各個(gè)復(fù)合圖層是單獨(dú)繪制的价淌,所以互不影響

  4. 某些動(dòng)畫(huà), 為了防止DOM更新然后全部頁(yè)面回流重繪, 所以會(huì)通過(guò)translate3d等方式, 另起一個(gè)復(fù)合圖層, 節(jié)省性能(硬件加速)

從Event Loop談JS的運(yùn)行機(jī)制

讀這部分的前提是已經(jīng)知道了JS引擎是單線程,而且這里會(huì)用到上文中的幾個(gè)概念:(如果不是很理解瞒津,可以回頭溫習(xí))

  • JS引擎線程

  • 事件觸發(fā)線程

  • 定時(shí)觸發(fā)器線程

然后再理解一個(gè)概念

  • JS分為同步任務(wù)和異步任務(wù)

  • 同步任務(wù)都在主線程上執(zhí)行蝉衣,形成一個(gè)執(zhí)行棧

  • 主線程之外,事件觸發(fā)線程管理著一個(gè)任務(wù)隊(duì)列巷蚪,只要異步任務(wù)有了運(yùn)行結(jié)果病毡,就在任務(wù)隊(duì)列之中放置一個(gè)事件。

  • 一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢(此時(shí)JS引擎空閑)屁柏,系統(tǒng)就會(huì)讀取任務(wù)隊(duì)列啦膜,將可運(yùn)行的異步任務(wù)添加到可執(zhí)行棧中有送,開(kāi)始執(zhí)行。

此時(shí)為什么有時(shí)候setTimeout推入的事件不能準(zhǔn)時(shí)執(zhí)行僧家?因?yàn)榭赡茉谒迫氲绞录斜頃r(shí)雀摘,主線程還不空閑,正在執(zhí)行其它代碼八拱, 所以自然有誤差阵赠。

00.png

事件循環(huán)機(jī)制進(jìn)一步補(bǔ)充

  • 主線程運(yùn)行時(shí)會(huì)產(chǎn)生執(zhí)行棧, 棧中的代碼調(diào)用某些api時(shí)肌稻,它們會(huì)在事件隊(duì)列中添加各種事件(當(dāng)滿(mǎn)足觸發(fā)條件后清蚀,如ajax請(qǐng)求完畢)

  • 而棧中的代碼執(zhí)行完畢档址,就會(huì)讀取事件隊(duì)列中的事件,去執(zhí)行那些回調(diào)

好好.png

單獨(dú)說(shuō)說(shuō)定時(shí)器

  1. 計(jì)時(shí)是由定時(shí)器線程控制, 因?yàn)閖s是單線程, 如果阻塞會(huì)造成計(jì)時(shí)不準(zhǔn)確
  // 1s后(定時(shí)器線程計(jì)時(shí)), 將回調(diào)函數(shù)推入事件隊(duì)列中, 等待主線程執(zhí)行
  setTimeout(function(){
    console.log('hello!');
  }, 1000);

事件循環(huán)進(jìn)階:JS兩種任務(wù)類(lèi)型 macrotask(宏任務(wù))與microtask(微任務(wù))

Promise里面的新概念: microtask

  1. 宏任務(wù)(macrotask): 每次執(zhí)行棧執(zhí)行的代碼就是一個(gè)宏任務(wù)(從頭到尾執(zhí)行完為止)

    • 瀏覽器為了能夠使得JS內(nèi)部task與DOM任務(wù)能夠有序的執(zhí)行士鸥,會(huì)在一個(gè)task執(zhí)行結(jié)束后莹规,在下一個(gè) task 執(zhí)行開(kāi)始前,對(duì)頁(yè)面進(jìn)行重新渲染 (task->渲染->task->...)
  2. 微任務(wù)(microtask):在當(dāng)前 task 執(zhí)行結(jié)束后立即執(zhí)行的任務(wù)(兩個(gè)宏任務(wù)之間)

  3. 例子

    1. macrotask:主代碼塊潮尝,setTimeout,setInterval等(可以看到,事件隊(duì)列中的每一個(gè)事件都是一個(gè)macrotask)

    2. microtask:Promise绑洛,process.nextTick等

    3. Promise響應(yīng)速度相比setTimeout快

i.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市童本,隨后出現(xiàn)的幾起案子真屯,更是在濱河造成了極大的恐慌,老刑警劉巖穷娱,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绑蔫,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡泵额,警方通過(guò)查閱死者的電腦和手機(jī)配深,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)嫁盲,“玉大人篓叶,你說(shuō)我怎么就攤上這事⌒叱樱” “怎么了缸托?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瘾蛋。 經(jīng)常有香客問(wèn)我俐镐,道長(zhǎng),這世上最難降的妖魔是什么哺哼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任佩抹,我火速辦了婚禮叼风,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匹摇。我一直安慰自己咬扇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布廊勃。 她就那樣靜靜地躺著懈贺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪坡垫。 梳的紋絲不亂的頭發(fā)上梭灿,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音冰悠,去河邊找鬼堡妒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛溉卓,可吹牛的內(nèi)容都是我干的皮迟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼桑寨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伏尼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起尉尾,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤爆阶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后沙咏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體辨图,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年肢藐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了故河。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窖壕,死狀恐怖忧勿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瞻讽,我是刑警寧澤鸳吸,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站速勇,受9級(jí)特大地震影響晌砾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烦磁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一养匈、第九天 我趴在偏房一處隱蔽的房頂上張望哼勇。 院中可真熱鬧,春花似錦呕乎、人聲如沸积担。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)帝璧。三九已至,卻和暖如春湿刽,著一層夾襖步出監(jiān)牢的瞬間的烁,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工诈闺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渴庆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓雅镊,卻偏偏與公主長(zhǎng)得像襟雷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仁烹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

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