盒子端 Css 動畫性能提升研究

作者:chokcoco?

http://web.jobbole.com/93258/


不同于傳統(tǒng)的 PC Web 或者是移動 WEB,在騰訊視頻客廳盒子端非竿,接大屏顯示器(電視)下银觅,許多能流暢運(yùn)行于 PC 端渐北、移動端的 Web 動畫危虱,受限于硬件水平,在盒子端的表現(xiàn)的往往不盡如人意球匕。

基于此填渠,對于 Web 動畫的性能問題,僅僅停留在感覺已經(jīng)優(yōu)化的OK之上谎倔,是不夠的柳击,想要在盒子端跑出高性能接近 60 FPS 的流暢動畫,就必須要刨根問底片习,深挖每一處可以提升的方法捌肴。

流暢動畫的標(biāo)準(zhǔn)

理論上說,F(xiàn)PS 越高藕咏,動畫會越流暢状知,目前大多數(shù)設(shè)備的屏幕刷新率為 60 次/秒,所以通常來講 FPS 為 60frame/s 時動畫效果最好孽查,也就是每幀的消耗時間為 16.67ms试幽。

直觀感受,不同幀率的體驗(yàn)

1卦碾、幀率能夠達(dá)到 50 ~ 60 FPS 的動畫將會相當(dāng)流暢铺坞,讓人倍感舒適;

2洲胖、幀率在 30 ~ 50 FPS 之間的動畫济榨,因各人敏感程度不同,舒適度因人而異绿映;

3擒滑、幀率在 30 FPS 以下的動畫,讓人感覺到明顯的卡頓和不適感叉弦;

4丐一、幀率波動很大的動畫,亦會使人感覺到卡頓淹冰。


盒子端動畫優(yōu)化

在騰訊視頻客廳盒子端库车,Web 動畫未進(jìn)行優(yōu)化之前,一些復(fù)雜動畫的幀率僅有 10 ~ 30 FPS樱拴,卡頓感非常明顯柠衍,帶來很不好的用戶體驗(yàn)。

而進(jìn)行優(yōu)化之后晶乔,能將 10 ~ 30 FPS的動畫優(yōu)化至 30 ~ 60 FPS珍坊,雖然不算優(yōu)化到最完美,但是當(dāng)前盒子硬件的條件下正罢,已經(jīng)算是非常大的進(jìn)步阵漏。

盒子端 Web 動畫性能比較

首先先給出在盒子端不同類型的Web 動畫的性能比較。經(jīng)過對比,在盒子端 CSS 動畫的性能要優(yōu)于 Javascript 動畫履怯,而在 CSS 動畫里川无,使用 GPU 硬件加速的動畫性能要優(yōu)于不使用硬件加速的性能。

所以在盒子端虑乖,實(shí)現(xiàn)一個 Web 動畫懦趋,優(yōu)先級是:

GPU 硬件加速 CSS 動畫 > 非硬件加速 CSS 動畫 > Javascript 動畫

動畫性能上報分析

要有優(yōu)化,就必須得有數(shù)據(jù)做為支撐疹味。對比優(yōu)化前后是否有提升仅叫。而對于動畫而言,衡量一個動畫的標(biāo)準(zhǔn)也就是 FPS 值糙捺。

所以現(xiàn)在的關(guān)鍵是如何計(jì)算出每個動畫運(yùn)行時的幀率诫咱,這里我使用的是?requestAnimationFrame這個函數(shù)近似的得到動畫運(yùn)行時的幀率。

考慮到盒子都是安卓系統(tǒng)洪灯,且大多版本較低且硬件性能堪憂坎缭,導(dǎo)致一是許多高級 API 無法使用,二是這里只是近似得到動畫幀率

原理是签钩,正常而言?requestAnimationFrame?這個方法在一秒內(nèi)會執(zhí)行 60 次掏呼,也就是不掉幀的情況下。假設(shè)動畫在時間 A 開始執(zhí)行铅檩,在時間 B 結(jié)束憎夷,耗時 x ms。而中間?requestAnimationFrame?一共執(zhí)行了 n 次昧旨,則此段動畫的幀率大致為:n / (B – A)拾给。

核心代碼如下,能近似計(jì)算每秒頁面幀率兔沃,以及我們額外記錄一個?allFrameCount蒋得,用于記錄 rAF 的執(zhí)行次數(shù),用于計(jì)算每次動畫的幀率 :

var?rAF?=?function?()?{

????return?(

????????window.requestAnimationFrame?||

????????window.webkitRequestAnimationFrame?||

????????function?(callback)?{

????????????window.setTimeout(callback,?1000?/?60);

????????}

????);

}();


var?frame?=?0;

var?allFrameCount?=?0;

var?lastTime?=?Date.now();

var?lastFameTime?=?Date.now();


var?loop?=?function?()?{

????var?now?=?Date.now();

????var?fs?=?(now?-?lastFameTime);

????var?fps?=?Math.round(1000?/?fs);


????lastFameTime?=?now;

????// 不置 0乒疏,在動畫的開頭及結(jié)尾記錄此值的差值算出 FPS

????allFrameCount++;

????frame++;


????if?(now?>?1000?+?lastTime)?{

????????var?fps?=?Math.round((frame *?1000)?/?(now?-?lastTime));

????????// console.log('fps', fps); 每秒 FPS

????????frame?=?0;

????????lastTime?=?now;

????};


????rAF(loop);

}


研究結(jié)論

所以额衙,我們的目標(biāo)就是在使用 GPU 硬件加速的基礎(chǔ)之上,更深入的去優(yōu)化 CSS 動畫缰雇,先給出最后的一個優(yōu)化步驟方案:

1入偷、精簡 DOM ,合理布局

2械哟、使用 transform 代替 left、top殿雪,減少使用耗性能樣式

3暇咆、控制頻繁動畫的層級關(guān)系

4、考慮使用 will-change

5、使用 dev-tool 時間線 timeline 觀察爸业,找出導(dǎo)致高耗時其骄、掉幀的關(guān)鍵操作


下文會有每一步驟的具體分析解釋。

Web 每一幀的渲染

要想達(dá)到 60 FPS扯旷,每幀的預(yù)算時間僅比 16 毫秒多一點(diǎn) (1 秒/ 60 = 16.67 毫秒)拯爽。但實(shí)際上,瀏覽器有整理工作要做钧忽,因此您的所有工作需要盡量在 10 毫秒內(nèi)完成毯炮。

完整的像素管道 JS / CSS > 樣式 > 布局 > 繪制 > 合成:

1、JavaScript耸黑。一般來說桃煎,我們會使用 JavaScript 來實(shí)現(xiàn)一些視覺變化的效果。比如用 jQuery 的 animate 函數(shù)做一個動畫大刊、對一個數(shù)據(jù)集進(jìn)行排序或者往頁面里添加一些 DOM 元素等为迈。當(dāng)然,除了 JavaScript缺菌,還有其他一些常用方法也可以實(shí)現(xiàn)視覺變化效果葫辐,比如:CSS Animations、Transitions 和 Web Animation API伴郁。

2另患、樣式計(jì)算。此過程是根據(jù)匹配選擇器(例如 .headline 或 .nav > .nav__item)計(jì)算出哪些元素應(yīng)用哪些 CSS 3. 規(guī)則的過程蛾绎。從中知道規(guī)則之后昆箕,將應(yīng)用規(guī)則并計(jì)算每個元素的最終樣式。

3租冠、布局鹏倘。在知道對一個元素應(yīng)用哪些規(guī)則之后,瀏覽器即可開始計(jì)算它要占據(jù)的空間大小及其在屏幕的位置顽爹。網(wǎng)頁的布局模式意味著一個元素可能影響其他元素纤泵,例如 元素的寬度一般會影響其子元素的寬度以及樹中各處的節(jié)點(diǎn),因此對于瀏覽器來說镜粤,布局過程是經(jīng)常發(fā)生的捏题。

4、繪制肉渴。繪制是填充像素的過程公荧。它涉及繪出文本、顏色同规、圖像循狰、邊框和陰影窟社,基本上包括元素的每個可視部分。繪制一般是在多個表面(通常稱為層)上完成的绪钥。

5灿里、合成。由于頁面的各部分可能被繪制到多層程腹,由此它們需要按正確順序繪制到屏幕上匣吊,以便正確渲染頁面。對于與另一元素重疊的元素來說寸潦,這點(diǎn)特別重要色鸳,因?yàn)橐粋€錯誤可能使一個元素錯誤地出現(xiàn)在另一個元素的上層。


當(dāng)然甸祭,不一定每幀都總是會經(jīng)過管道每個部分的處理缕碎。我們的目標(biāo)就是,每一幀的動畫池户,對于上述的管道流程咏雌,能避免則避免,不能避免則最大限度優(yōu)化校焦。

優(yōu)化動畫步驟

先給出一個步驟赊抖,調(diào)優(yōu)一個動畫,有一定的指導(dǎo)原則可以遵循寨典,一步一步深入動畫:

1.精簡 DOM 氛雪,合理布局

這個沒什么好說的,如果可以耸成,精簡 DOM 結(jié)構(gòu)在任何時候都是對頁面有幫助的报亩。

2.使用 transform 代替 left、top井氢,減少使用耗性能樣式

現(xiàn)代瀏覽器在完成以下四種屬性的動畫時弦追,消耗成本較低:

1、position(位置):?transform: translate(npx, npx)

2花竞、scale(比例縮放):transform: scale(n)

3劲件、rotation(旋轉(zhuǎn)) :transform: rotate(ndeg)

4、opacity(透明度):opacity: 0...1


如果可以约急,盡量只使用上述四種屬性去控制動畫零远。

不同樣式在消耗性能方面是不同的,改變一些屬性的開銷比改變其他屬性要多厌蔽,因此更可能使動畫卡頓牵辣。

例如,與改變元素的文本顏色相比躺枕,改變元素的?box-shadow?將需要開銷大很多的繪圖操作服猪。 改變元素的?width?可能比改變其?transform?要多一些開銷供填。如?box-shadow?屬性拐云,從渲染角度來講十分耗性能罢猪,原因就是與其他樣式相比,它們的繪制代碼執(zhí)行時間過長叉瘩。

這就是說膳帕,如果一個耗性能嚴(yán)重的樣式經(jīng)常需要重繪,那么你就會遇到性能問題薇缅。其次你要知道危彩,沒有不變的事情,在今天性能很差的樣式泳桦,可能明天就被優(yōu)化汤徽,并且瀏覽器之間也存在差異。

開啟 GPU 硬件加速

歸根結(jié)底灸撰,上述四種屬性的動畫消耗較低的原因是會開啟了 GPU 硬件加速谒府。動畫元素生成了自己的圖形層(GraphicsLayer)。

通常而言浮毯,開啟 GPU 加速的方法我們可以使用

1完疫、will-change: transform


這會使聲明了該樣式屬性的元素生成一個圖形層,告訴瀏覽器接下來該元素將會進(jìn)行 transform 變換债蓝,讓瀏覽器提前做好準(zhǔn)備壳鹤。

使用?will-change?并不一定會有性能的提升,因?yàn)榧词篂g覽器預(yù)料到會有這些更改饰迹,依然會為這些屬性運(yùn)行布局和繪制流程芳誓,所以提前告訴瀏覽器,也并不會有太多性能上的提升啊鸭。這樣做的好處是锹淌,創(chuàng)建新的圖層代價很高,而等到需要時匆忙地創(chuàng)建莉掂,不如一開始直接創(chuàng)建好葛圃。

對于 Safari 及一些舊版本瀏覽器,它們不能識別?will-change憎妙,則需要使用某種 translate 3D 進(jìn)行 hack库正,通常會使用

2、transform: translateZ(0)


所以厘唾,正常而言褥符,在生產(chǎn)環(huán)境下,我們可能需要使用如下代碼抚垃,開啟硬件加速:

{

????will-change:?transform;

????transform:?translateZ(0);

}


3.控制頻繁動畫的層級關(guān)系

動畫層級的控制的意思是盡量讓需要進(jìn)行 CSS 動畫的元素的?z-index?保持在頁面最上方喷楣,避免瀏覽器創(chuàng)建不必要的圖形層(GraphicsLayer),能夠很好的提升渲染性能铣焊。

OK逊朽,這里又提到了圖形層(GraphicsLayer)曲伊,這是一個瀏覽器渲染原理相關(guān)的知識(WebKit/blink內(nèi)核下)。它能對動畫進(jìn)行加速岛蚤,但同時也存在相應(yīng)的加速坑!


簡單來說懈糯,瀏覽器為了提升動畫的性能赚哗,為了在動畫的每一幀的過程中不必每次都重新繪制整個頁面她紫。在特定方式下可以觸發(fā)生成一個合成層,合成層擁有單獨(dú)的 GraphicsLayer蜂奸。

需要進(jìn)行動畫的元素包含在這個合成層之下犁苏,這樣動畫的每一幀只需要去重新繪制這個 Graphics Layer 即可,從而達(dá)到提升動畫性能的目的扩所。

那么一個元素什么時候會觸發(fā)創(chuàng)建一個 Graphics Layer 層围详?從目前來說,滿足以下任意情況便會創(chuàng)建層:

1祖屏、硬件加速的 iframe 元素(比如 iframe 嵌入的頁面中有合成層)

2助赞、硬件加速的插件,比如 flash 等等

3袁勺、使用加速視頻解碼的 <video>元素

4雹食、3D 或者 硬件加速的 2D Canvas 元素

5、3D 或透視變換 (perspective期丰、transform) 的 CSS 屬性

6群叶、對自己的 opacity 做 CSS 動畫或使用一個動畫變換的元素

7、擁有加速 CSS 過濾器的元素

8钝荡、元素有一個包含復(fù)合層的后代節(jié)點(diǎn)(換句話說街立,就是一個元素?fù)碛幸粋€子元素,該子元素在自己的層里)

9埠通、元素有一個 z-index 較低且包含一個復(fù)合層的兄弟元素


本小點(diǎn)中說到的動畫層級的控制赎离,原因就在于上面生成層的最后一條:

元素有一個 z-index 較低且包含一個復(fù)合層的兄弟元素。

這里是存在坑的地方端辱,首先我們要明確兩點(diǎn):

1梁剔、我們希望我們的動畫得到 GPU 硬件加速虽画,所以我們會利用類似?transform: translateZ()這樣的方式生成一個 Graphics Layer 層。

2荣病、Graphics Layer 雖好码撰,但不是越多越好,每一幀的渲染內(nèi)核都會去遍歷計(jì)算當(dāng)前所有的 Graphics Layer 众雷,并計(jì)算他們下一幀的重繪區(qū)域灸拍,所以過量的 Graphics Layer 計(jì)算也會給渲染造成性能影響做祝。


記住這兩點(diǎn)之后砾省,回到上面我們說的坑。

假設(shè)我們有一個輪播圖混槐,有一個 ul 列表编兄,結(jié)構(gòu)如下:

<div?class="container">

? ? <div?class="swiper">輪播圖</div>

? ??<ul?class="list">

? ??? ??<li>列表li</li>

? ??? ??<li>列表li</li>

? ??? ??<li>列表li</li>

? ??? ??<li>列表li</li>

? ??</ul>

</div>


假設(shè)給他們定義如下 CSS:

.swiper?{

????position:?static;

????animation:?10s?move?infinite;

}


.list?{

????position:?relative;

}


@keyframes?move?{

????100%?{

????????transform:?translate3d(10px,?0,?0);

????}

}


由于給?.swiper?添加了?translate3d(10px, 0, 0)?動畫,所以它會生成一個 Graphics Layer声登,如下圖所示狠鸳,用開發(fā)者工具可以打開層的展示,圖形外的黃色邊框即代表生成了一個獨(dú)立的復(fù)合層悯嗓,擁有獨(dú)立的 Graphics Layer 件舵。


但是!在上面的圖中脯厨,我們并沒有給下面的?list?也添加任何能觸發(fā)生成 Graphics Layer 的屬性铅祸,但是它也同樣也有黃色的邊框,生成了一個獨(dú)立的復(fù)合層合武。

原因在于上面那條元素有一個 z-index 較低且包含一個復(fù)合層的兄弟元素临梗。我們并不希望?list?元素也生成 Graphics Layer ,但是由于 CSS 層級定義原因稼跳,下面的 list 的層級高于上面的 swiper盟庞,所以它被動的也生成了一個 Graphics Layer 。

使用 Chrome汤善,我們也可以觀察到這種層級關(guān)系什猖,可以看到?.list?的層級高于?.swiper

所以,下面我們修改一下 CSS 红淡,改成:

.swiper?{

????position:?relative;

????z-index:?100;

}


.list?{

????position:?relative;

}


這里不狮,我們明確使得?.swiper?的層級高于?.list?,再打開開發(fā)者工具觀察一下:

可以看到锉屈,這一次荤傲,.list?元素已經(jīng)沒有了黃色外邊框,說明此時沒有生成 Graphics Layer 颈渊。再看看層級圖:


此時遂黍,層級關(guān)系才是我們希望看到的终佛,.list?元素沒有觸發(fā)生成 Graphics Layer 。而我們希望需要硬件加速的?.swiper?保持在最上方雾家,每次動畫過程中只會獨(dú)立重繪這部分的區(qū)域铃彰。

總結(jié)

這個坑最早見于張?jiān)讫埌l(fā)布的這篇文章CSS3硬件加速也有坑,這里還要總結(jié)補(bǔ)充的是:

1芯咧、GPU 硬件加速也會有坑牙捉,當(dāng)我們希望使用利用類似?transform: translate3d()?這樣的方式開啟 GPU 硬件加速,一定要注意元素層級的關(guān)系敬飒,盡量保持讓需要進(jìn)行 CSS 動畫的元素的?z-index?保持在頁面最上方邪铲。

2、Graphics Layer 不是越多越好无拗,每一幀的渲染內(nèi)核都會去遍歷計(jì)算當(dāng)前所有的 Graphics Layer 带到,并計(jì)算他們下一幀的重繪區(qū)域,所以過量的 Graphics Layer 計(jì)算也會給渲染造成性能影響英染。

3揽惹、可以使用 Chrome ,用上面介紹的兩個工具對自己的頁面生成的 Graphics Layer 和元素層級進(jìn)行觀察然后進(jìn)行相應(yīng)修改四康。

4搪搏、上面觀察頁面層級的 chrome 工具非常吃內(nèi)存?好像還是一個處于實(shí)驗(yàn)室的功能闪金,分析稍微大一點(diǎn)的頁面容易直接卡死疯溺,所以要多學(xué)會使用第一種觀察黃色邊框的方式查看頁面生成的 Graphics Layer 這種方式。


4. 使用 will-change 可以在元素屬性真正發(fā)生變化之前提前做好對應(yīng)準(zhǔn)備

// 示例

.example?{

????will-change:?transform;

}


上面已經(jīng)提到過 will-change 了毕泌。

will-change 為 web 開發(fā)者提供了一種告知瀏覽器該元素會有哪些變化的方法喝检,這樣瀏覽器可以在元素屬性真正發(fā)生變化之前提前做好對應(yīng)的優(yōu)化準(zhǔn)備工作。 這種優(yōu)化可以將一部分復(fù)雜的計(jì)算工作提前準(zhǔn)備好撼泛,使頁面的反應(yīng)更為快速靈敏挠说。

值得注意的是,用好這個屬性并不是很容易:

1愿题、在一些低端盒子上损俭,will-change?會導(dǎo)致很多小問題,譬如會使圖片模糊潘酗,有的時候很容易適得其反杆兵,所以使用的時候還需要多加測試。

2仔夺、不要將 will-change 應(yīng)用到太多元素上:瀏覽器已經(jīng)盡力嘗試去優(yōu)化一切可以優(yōu)化的東西了琐脏。有一些更強(qiáng)力的優(yōu)化,如果與 will-change 結(jié)合在一起的話,有可能會消耗很多機(jī)器資源日裙,如果過度使用的話吹艇,可能導(dǎo)致頁面響應(yīng)緩慢或者消耗非常多的資源。

3昂拂、有節(jié)制地使用:通常受神,當(dāng)元素恢復(fù)到初始狀態(tài)時,瀏覽器會丟棄掉之前做的優(yōu)化工作格侯。但是如果直接在樣式表中顯式聲明了 will-change 屬性鼻听,則表示目標(biāo)元素可能會經(jīng)常變化,瀏覽器會將優(yōu)化工作保存得比之前更久联四。所以最佳實(shí)踐是當(dāng)元素變化之前和之后通過腳本來切換 will-change 的值撑碴。

4、不要過早應(yīng)用 will-change 優(yōu)化:如果你的頁面在性能方面沒什么問題碎连,則不要添加 will-change 屬性來榨取一丁點(diǎn)的速度灰羽。 will-change 的設(shè)計(jì)初衷是作為最后的優(yōu)化手段,用來嘗試解決現(xiàn)有的性能問題鱼辙。它不應(yīng)該被用來預(yù)防性能問題。過度使用 will-change 會導(dǎo)致生成大量圖層玫镐,進(jìn)而導(dǎo)致大量的內(nèi)存占用倒戏,并會導(dǎo)致更復(fù)雜的渲染過程,因?yàn)闉g覽器會試圖準(zhǔn)備可能存在的變化過程恐似,這會導(dǎo)致更嚴(yán)重的性能問題杜跷。

5、給它足夠的工作時間:這個屬性是用來讓頁面開發(fā)者告知瀏覽器哪些屬性可能會變化的矫夷。然后瀏覽器可以選擇在變化發(fā)生前提前去做一些優(yōu)化工作葛闷。所以給瀏覽器一點(diǎn)時間去真正做這些優(yōu)化工作是非常重要的。使用時需要嘗試去找到一些方法提前一定時間獲知元素可能發(fā)生的變化双藕,然后為它加上 will-change 屬性淑趾。


5. 使用 dev-tool 時間線 timeline 觀察,找出導(dǎo)致高耗時忧陪、掉幀的關(guān)鍵操作

1扣泊、對比屏幕快照,觀察每一幀包含的內(nèi)容及具體的操作

2嘶摊、找到掉幀的那一幀延蟹,分析該幀內(nèi)不同步驟的耗時占比,進(jìn)行有針對性的優(yōu)化

3叶堆、觀察是否存在內(nèi)存泄漏

總結(jié)一下

對于盒子端 CSS 動畫的性能阱飘,很多方面仍處于探索中,本文大量內(nèi)容在之前文章已經(jīng)出現(xiàn)過,這里更多的是歸納總結(jié)提煉成可參照執(zhí)行的流程沥匈。

本文的優(yōu)化方案研究同樣適用于 PC Web 及移動 Web果录,文章難免有錯誤及疏漏,歡迎不吝賜教咐熙。

感興趣的小伙伴弱恒,可以關(guān)注公眾號【grain先森】,回復(fù)關(guān)鍵詞 “小程序”棋恼,獲取更多資料返弹,更多關(guān)鍵詞玩法期待你的探索~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市爪飘,隨后出現(xiàn)的幾起案子义起,更是在濱河造成了極大的恐慌,老刑警劉巖师崎,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件默终,死亡現(xiàn)場離奇詭異,居然都是意外死亡犁罩,警方通過查閱死者的電腦和手機(jī)齐蔽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來床估,“玉大人含滴,你說我怎么就攤上這事∝の祝” “怎么了谈况?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長递胧。 經(jīng)常有香客問我碑韵,道長,這世上最難降的妖魔是什么缎脾? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任祝闻,我火速辦了婚禮,結(jié)果婚禮上赊锚,老公的妹妹穿的比我還像新娘治筒。我一直安慰自己,他們只是感情好舷蒲,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布耸袜。 她就那樣靜靜地躺著,像睡著了一般牲平。 火紅的嫁衣襯著肌膚如雪堤框。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音蜈抓,去河邊找鬼启绰。 笑死,一個胖子當(dāng)著我的面吹牛沟使,可吹牛的內(nèi)容都是我干的委可。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼腊嗡,長吁一口氣:“原來是場噩夢啊……” “哼着倾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起燕少,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤卡者,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后客们,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體崇决,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年底挫,在試婚紗的時候發(fā)現(xiàn)自己被綠了恒傻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡凄敢,死狀恐怖碌冶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涝缝,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布譬重,位于F島的核電站拒逮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏臀规。R本人自食惡果不足惜滩援,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望塔嬉。 院中可真熱鬧玩徊,春花似錦、人聲如沸谨究。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胶哲。三九已至畔塔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背澈吨。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工把敢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谅辣。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓修赞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親桑阶。 傳聞我的和親對象是個殘疾皇子柏副,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

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