為什么我們正在放棄 CSS-in-JS

hello 大家好,我是 superZidan,這篇文章想跟大家聊聊 為什么我們正在放棄 CSS-in-JS

這篇文章將深入的挖掘我當(dāng)時(shí)為什么會(huì)在項(xiàng)目中使用 CSS-in-JS (本文使用 Emotion 方案 ),而現(xiàn)在為什么正在放棄這樣的方案。

什么是 CSS-in-JS

CSS-in-JS 允許你直接使用 JavaScript 或者 TypeScript 修改你的 React 組件的樣式

import styled from '@emotion/styled'

const ErrorMessageRed = styled.div`
  color: red;
  font-weight: bold;
`;

function App() {
  return (
   <div>
    <ErrorMessageRed>
      hello ErrorMessageRed !!
    </ErrorMessageRed>
   </div>
  );
}

export default App;

styled-componentsEmotion 是 React 社區(qū)最流行的 CSS-in-JS 方案。本文中我只是提及到 Emotion ,但是我相信大部分的使用場(chǎng)景也同樣適用于 styled-components。

本文專(zhuān)注于 運(yùn)行時(shí)類(lèi)型的 CSS-in-JS ,styled-components 和 Emotion 都屬于這個(gè)類(lèi)型。因?yàn)?CSS-in-JS 還有另一種類(lèi)型,編譯時(shí)類(lèi)型 CSS-in-JS 這塊會(huì)在文章末段稍微提及到。

CSS-in-JS 的優(yōu)缺點(diǎn)

在我們深入了解 CSS-in-JS 的模式和它對(duì)性能的影響之前,我們先從總體的了解一下為什么我們會(huì)使用這項(xiàng)技術(shù)以及為什么要逐步放棄

優(yōu)點(diǎn)

1.Locally-scoped styles: 當(dāng)我們?cè)诼銓?xiě) CSS 的時(shí)候,很容易就污染到其他我們意想不到的組件。比如我們寫(xiě)了一個(gè)列表,每一行的需要加一個(gè)內(nèi)邊距和邊框的樣式。我們可能會(huì)寫(xiě)這樣的 CSS 代碼

.row {
  padding: 0.5rem;
  border: 1px solid #ddd;
}

幾個(gè)月之后可能你已經(jīng)忘記了這個(gè)列表的代碼了,然后你寫(xiě)了 className="row" 在另外的組件上,那么這個(gè)新的組件有了內(nèi)邊距合邊框樣式,你甚至都不知道為什么會(huì)這樣。你可以使用更長(zhǎng)的類(lèi)名或者更加明確的選擇器來(lái)避免這樣的情況發(fā)生,但是你還是無(wú)法完全保證不會(huì)再出現(xiàn)這樣的樣式?jīng)_突。

CSS-in-JS 就可以通過(guò) Locally-scoped styles 來(lái)完全解決這個(gè)問(wèn)題。如果你的列表代碼這么寫(xiě)的話(huà):

<div className={css`
        padding: 0.5rem;
        border: 1px solid #ddd;
    `}>
    ...row item...
 </div>

這樣的話(huà),內(nèi)邊距和邊框的樣式永遠(yuǎn)不會(huì)影響到其他組件。

提示:CSS Modules 也提供了 Locally-scoped styles

2. Colocation: 你的 React 組件是寫(xiě)在 src/components 目錄中的,當(dāng)你裸寫(xiě) CSS 的時(shí)候,你的 .css 文件可能是放置在 src/styles 目錄中。隨著項(xiàng)目越來(lái)越大,你很難明確哪些 CSS 樣式是用在哪些組件上,這樣最后你會(huì)冗余很多樣式代碼。

一個(gè)更好的組織代碼的方式可能是將相關(guān)的代碼文件放在同個(gè)地方。這種做法成為「共置」,可以通過(guò)這篇文章了解一下。

問(wèn)題在于其實(shí)很難實(shí)現(xiàn)所謂的「共置」。如果在項(xiàng)目中裸寫(xiě) CSS 的話(huà),你的樣式和可能會(huì)作用于全局不管你的 .css 文件被放置在哪里。另一方面,如果你使用 CSS-in-JS,你可以直接在 React 組件內(nèi)部書(shū)寫(xiě)樣式,如果組織得好,那么你的項(xiàng)目的可維護(hù)性將大大提升。

提示:CSS Modules 也提供了「共置」的能力

3. 在樣式中使用 JavaScript 變量: CSS-in-JS 提供了讓你在樣式中訪(fǎng)問(wèn) JavaScript 變量的能力


function App(props) {
    const color = "red";
    const ErrorMessageRed = styled.div`
      color: ${props.color || color};
      font-weight: bold;
    `;
    
    return (
        <div>
            <ErrorMessageRed>
              hello ErrorMessageRed !!
            </ErrorMessageRed>
        </div>
    );
}

上面的例子展示了,我們可以在 CSS-in-JS 方案中使用 JavaScript 的 const 變量 或者是 React 組件的 props。這樣可以減少很多重復(fù)代碼,當(dāng)我們需要同時(shí)在 JavaScript 和 CSS 兩側(cè)定義相同的變量的時(shí)候。我們通過(guò)這樣的能力可以不需要使用 inline styles 這樣的方式來(lái)完成高度自定義的樣式。( inline styles 對(duì)性能不是特別友好,當(dāng)我們有很多相同的樣式寫(xiě)在不同的組件的時(shí)候)

中立點(diǎn)

1. 這是熱門(mén)的新技術(shù): 許多的開(kāi)發(fā)者包括我自己,會(huì)更熱衷于使用 JavaScript 社區(qū)中熱門(mén)的新技術(shù)。一個(gè)重要的原因是,很多新的框架或者庫(kù),能夠提升帶來(lái)巨大的性能或者體驗(yàn)上的提升(想象一下,React 對(duì)比 jQuery 帶來(lái)的開(kāi)發(fā)效率提升)。另一個(gè)原因就是,我們對(duì)新技術(shù)抱有比較開(kāi)放的態(tài)度,我們不愿意錯(cuò)過(guò)每個(gè)大事件。當(dāng)然了,我們?cè)谶x擇新的技術(shù)的時(shí)候也會(huì)考慮到它帶來(lái)的負(fù)面影響。這大概就是我之前選擇 CSS-in-JS 的原因。

缺點(diǎn)

  1. CSS-in-JS 的運(yùn)行時(shí)問(wèn)題。當(dāng)你的組件進(jìn)行渲染的時(shí)候,CSS-in-JS 庫(kù)會(huì)在運(yùn)行時(shí)將你的樣式代碼 ”序列化” 為可以插入文檔的 CSS 。這無(wú)疑會(huì)消耗瀏覽器更多的 CPU 性能
  2. CSS-in-JS 讓你的包體積更大了。 這是一個(gè)明顯的問(wèn)題。每個(gè)訪(fǎng)問(wèn)你的站點(diǎn)的用戶(hù)都不得不加載關(guān)于 CSS-in-JS 的 JavaScript。Emotion 的包體積壓縮之后是 7.9k ,而 styled-components 則是 12.7 kB 。雖然這些包都不算是特別[圖片上傳中...(image-607491-1689056587535)]
    大,但是如果再加上 react & react-dom 的話(huà),那也是不小的開(kāi)銷(xiāo)。
  3. CSS-in-JS 讓 React DevTools 變得難看。 每一個(gè)使用 css prop 的 react 元素, Emotion 都會(huì)渲染成 <EmotionCssPropInternal><Insertion> 組件。如果你使用很多的 css prop,那么你會(huì)在 React DevTools 看到下面這樣的場(chǎng)景
image.png
  1. 頻繁的插入 CSS 樣式規(guī)則會(huì)迫使瀏覽器做更多的工作。 React 團(tuán)隊(duì)核心成員&React Hooks 設(shè)計(jì)者 Sebasian 寫(xiě)了一篇關(guān)于 CSS-in-JS 庫(kù)如何與 React 18 一起工作的文章。他特別說(shuō)到

在 concurrent 渲染模式下,React 可以在渲染之間讓出瀏覽器的控制權(quán)。如果你為一個(gè)組件插入一個(gè)新的 CSS 規(guī)則,然后 React 讓出控制權(quán),瀏覽器會(huì)檢查這個(gè)新的規(guī)則是否作用到了已有的樹(shù)上。所以瀏覽器重新計(jì)算了樣式規(guī)則。然后 React 渲染下一個(gè)組件,該組件發(fā)現(xiàn)一個(gè)新的規(guī)則,那么又會(huì)重新觸發(fā)樣式規(guī)則的計(jì)算。

實(shí)際上 React 進(jìn)行渲染的每一幀,所有 DOM 元素上的 CSS 規(guī)則都會(huì)重新計(jì)算。這會(huì)非常非常的慢

更壞的是,這個(gè)問(wèn)題好像是無(wú)解的(針對(duì)運(yùn)行時(shí) CSS-in-JS)。運(yùn)行時(shí) CSS-in-JS 庫(kù)會(huì)在組件渲染的時(shí)候插入新的樣式規(guī)則,這對(duì)性能來(lái)說(shuō)是一個(gè)很大的損耗。

  1. 使用 CSS-in-JS ,會(huì)有更大的概率導(dǎo)致項(xiàng)目報(bào)錯(cuò),特別是在 SSR 或者組件庫(kù)這樣的項(xiàng)目中。在 Emotion 的 GitHub 倉(cāng)庫(kù),我們可以看到很多向如下的 issue

我在我的 SSR 項(xiàng)目中使用了 Emotion,但是它報(bào)錯(cuò)了,因?yàn)椤?

在這些海量的 issue 中,我們可以找到一些共同特征:

  • 多個(gè) Emotion 實(shí)例被同時(shí)加載。如果多個(gè)被同時(shí)加載的實(shí)例是相同的Emotion 版本,這將會(huì)引起很多問(wèn)題(比如說(shuō)
  • 組件庫(kù)通常無(wú)法讓您完全控制插入樣式的順序(比如說(shuō)
  • Emotion 的 SSR 能力支持對(duì)于 React 17 和 18 兩個(gè)版本是不相同的。我們需要做一些兼容性的工作來(lái)兼容 React 18 的 stream SSR(比如說(shuō)

相信我,上述的這些問(wèn)題僅僅是冰山一角。

性能檢測(cè)

在這一點(diǎn)上,很明顯,CSS-in-JS 有著顯著的優(yōu)點(diǎn)和缺點(diǎn)。為了明白我們?yōu)槭裁凑谝瞥@項(xiàng)技術(shù),我們需要更加真實(shí)的 CSS-in-JS 性能場(chǎng)景。這里我們會(huì)著重關(guān)注 Emotion 對(duì)于性能的影響。Emotion 有很多種使用方式,每種方式都有其各自的性能表現(xiàn)特點(diǎn)。

內(nèi)部序列化渲染 vs. 外部序列化渲染

樣式序列化指的是 Emotion 將你的 CSS 字符串或者樣式對(duì)象轉(zhuǎn)化成可以插入文檔的純 CSS 字符串。Emotion 同時(shí)也會(huì)在序列化的過(guò)程中根據(jù)生成的存 CSS 字符串計(jì)算出相應(yīng)的哈希值——這個(gè)哈希值就是你可以看到的動(dòng)態(tài)生成的類(lèi)名,比如 css-an61r6

在測(cè)試前,我預(yù)感到這個(gè)樣式序列化是在 React 組件渲染周期里面完成還是外面完成,將對(duì) Emotion 的性能表現(xiàn)起到比較大的影響。

在渲染周期內(nèi)完成的代碼如下

function MyComponent() {
  return (
    <div
      css={{
        backgroundColor: 'blue',
        width: 100,
        height: 100,
      }}
    />
  );
}

每次 MyComponent 渲染,樣式對(duì)象都會(huì)被序列化一次。如果 MyComponent 渲染的比較頻繁,重復(fù)的序列化將有很大的性能開(kāi)銷(xiāo)

一個(gè)性能更好的方案是把樣式移到組件的外面,所以序列化過(guò)程只會(huì)在組件模塊被載入的時(shí)候發(fā)生,而不是每次都要執(zhí)行一遍。你可以使用 @emotion/reactcss 方法

const myCss = css({
  backgroundColor: 'blue',
  width: 100,
  height: 100,
});

function MyComponent() {
  return <div css={myCss} />;
}

當(dāng)然,這樣使得你無(wú)法在樣式種獲得組件的 props,所以你會(huì)錯(cuò)失 CSS-in-JS 的一個(gè)主要的賣(mài)點(diǎn)。

測(cè)試「成員檢索」功能

我們接下來(lái)將使用在一個(gè)頁(yè)面上實(shí)現(xiàn)「成員檢索」的能力,就是使用一個(gè)列表展示團(tuán)隊(duì)成員的一個(gè)簡(jiǎn)單的功能。列表上幾乎所有的樣式都是通過(guò) Emotion 來(lái)實(shí)現(xiàn),特別是使用 css prop

image.png

測(cè)試如下:

  • 「成員檢索」會(huì)在頁(yè)面上顯示 20 個(gè)用戶(hù)
  • 去除 react.memo 對(duì)列表的包裹
  • 每秒都強(qiáng)制渲染 <BrowseMembers> 組件,記錄前 10 次渲染的時(shí)間
  • 關(guān)閉 React Strict 模式 (不然會(huì)觸發(fā)重復(fù)渲染,時(shí)間可能是現(xiàn)在的 2 倍)

我使用 React DevTools 進(jìn)行記錄,得到前 10 次的平均渲染時(shí)間為 54.3 毫秒。

以往的經(jīng)驗(yàn)告訴我,一個(gè) React 組件最好的渲染時(shí)間大概是 16 毫秒(每秒 60 幀計(jì)算)。 < BrowseMembers > 組件的渲染時(shí)間是經(jīng)驗(yàn)值的 3 倍左右,所以它是一個(gè)比較「重」的組件。

如果我去除 Emotion,而使用 Sass Modules 來(lái)實(shí)現(xiàn)頁(yè)面的樣式,平均的渲染時(shí)間大概是在 27.7 毫秒。這比原來(lái)使用 Emotion 少了將近 48% !!!

這就是為什么我們開(kāi)始放棄使用 CSS-in-JS 的原因:運(yùn)行時(shí)的性能消耗實(shí)在太嚴(yán)重了!!!

我們的新樣式方案

在我們下定決心要移除 CSS-in-JS 之后,剩下的問(wèn)題就是:我們應(yīng)該什么方案來(lái)代替。我們既想要有裸寫(xiě) CSS 這樣的性能,又想要盡可能保留 CSS-in-JS 的優(yōu)點(diǎn)。這里再次簡(jiǎn)單梳理一下 CSS-in-JS 的優(yōu)點(diǎn)(忘記的同學(xué)可以翻回上面再看看):

  1. locally-scoped styles
  2. colocated
  3. 在 CSS 中使用 JS 變量

如果你有認(rèn)真看這篇文章,那你應(yīng)該還記得我在上文中提到,CSS Modules 其實(shí)也是可以提供 locally-scoped styles 和 colocated 這樣類(lèi)似的能力的。并且 CSS Modules 編譯成原生 CSS 文件之后,沒(méi)有運(yùn)行時(shí)的性能開(kāi)銷(xiāo)。

在我看來(lái),CSS Modules 的缺點(diǎn)在于,他們依然是原生的 CSS —— 原生 CSS 缺少提升開(kāi)發(fā)體驗(yàn)以及減少冗余代碼的能力。但是,如果當(dāng)原生CSS 具備 nested selectors 的能力之后,情況將會(huì)改善很多。

幸好,市面上已經(jīng)有了一個(gè)很簡(jiǎn)單的方案來(lái)解決這個(gè)問(wèn)題—— Sass Modules ( 使用 Sass 來(lái)寫(xiě) CSS Modules ) 。你既可以享受 CSS Modules 的 locally-scoped styles 能力,又可以享受 Sass 強(qiáng)大的編譯時(shí)功能(去除運(yùn)行時(shí)性能開(kāi)銷(xiāo))。這就是我們會(huì)使用 Sass Modules 的一個(gè)重要原因。

注意:使用 Sass Modules ,你將無(wú)法享受到 CSS-in-JS 的第 3 個(gè)優(yōu)點(diǎn)(在 CSS 中使用 JS 變量)。但是你可以使用 :export 塊將 Sass 代碼的常量導(dǎo)出到 JS 代碼中。這個(gè)用起來(lái)不是特別方便,但是會(huì)使你的代碼更加清晰。

Utility Classes

比較擔(dān)心我們團(tuán)隊(duì)從 Emotion 切換到 Sass Modules 之后,會(huì)在寫(xiě)一些極度常用的樣式的時(shí)候不是很方便,比如 display: flex 。之前我們是這樣寫(xiě)的

<FlexH alignItems="center">...</FlexH>

如果改用 Sass Modules 之后,我們需要?jiǎng)?chuàng)建一個(gè) .module.scss 文件,然后寫(xiě)一個(gè) display: flexalign-item: center 。這不是世界末日,但肯定是不夠方便的。

為了提升開(kāi)發(fā)體驗(yàn),我們決定引入一個(gè) Utility Classes。如果你對(duì) Utility Classes 還不是很熟悉,用一句話(huà)概括就是,“他們是一些只包含一個(gè) CSS 屬性的 CSS 類(lèi)”。通常情況下,你會(huì)在你的元素上使用多個(gè)這樣的類(lèi),通過(guò)組合的方式來(lái)修改元素的樣式。對(duì)于上面的這個(gè)例子,你可能需要這樣寫(xiě):

<div className="d-flex align-items-center">...</div>

BootstrapTailwind 是目前最流行的提供 Utility Classes 的解決方案。這些庫(kù)在設(shè)計(jì)方案上做了非常多的努力,這使得我們可以放心的使用他們,而不是自己重新搭建一個(gè)。因?yàn)槲沂褂?Bootstrap 已經(jīng)很多年了,所以我們選擇了 Bootstrap。我們使用 Bootstrap 作為我們項(xiàng)目的預(yù)設(shè)樣式方案。

我們已經(jīng)在新組件上使用 Sass Modules 和 Utility Classes 好幾個(gè)星期了。我們覺(jué)得都不錯(cuò)。它的開(kāi)發(fā)體驗(yàn)跟 Emotion 差不多,但是運(yùn)行時(shí)的性能更加的好。

我們也使用 typed-scss-modules 來(lái)為 Sass Modules 生成 TypeScript 的類(lèi)型文件。也許這樣做最大的好處就是允許我們定一個(gè)幫助函數(shù) utils() ,這樣我們可以像使用 classnames 去操作樣式。

一些關(guān)于 構(gòu)建時(shí) CSS-in-JS 方案

本文主要關(guān)注的是 運(yùn)行時(shí) CSS-in- JS 方案,比如 Emotion 和 styled-components 。最近,我們也關(guān)注到了一些將樣式轉(zhuǎn)換是純 CSS 的構(gòu)建時(shí)CSS-in-JS 方案。包括

這些庫(kù)的目標(biāo)是為了提供類(lèi)似于運(yùn)行時(shí) CSS-in-JS 的能力,但是沒(méi)有性能損耗。

目前我還沒(méi)有在真實(shí)項(xiàng)目中使用構(gòu)建時(shí) CSS-in-JS 方案。但我想這些方案對(duì)比 Sass Modules 大概會(huì)有以下的缺點(diǎn):

  • 依然會(huì)在組件 mount 的時(shí)候完成樣式的第一次插入,這還是會(huì)使得瀏覽器重新計(jì)算每個(gè) DOM 節(jié)點(diǎn)的樣式
  • 動(dòng)態(tài)樣式無(wú)法被抽取出來(lái),所以會(huì)使用 CSS 變量加上行內(nèi)樣式的方法來(lái)替代。過(guò)多的行內(nèi)樣式依然會(huì)影響性能
  • 這些庫(kù)依然會(huì)插入一些特定的組件到項(xiàng)目的 React 樹(shù)中,依然會(huì)導(dǎo)致 React DevTools 的可讀性變得比較差

結(jié)論

感謝你閱讀到這里~任何事情都是,有它好的一面也有它不好的一面。最終,作為開(kāi)發(fā)人員,你必須評(píng)估這些優(yōu)缺點(diǎn),然后就該技術(shù)是否適合你的項(xiàng)目,然后做出決定。而對(duì)于目前我所在的團(tuán)隊(duì)來(lái)說(shuō),Emotion 帶來(lái)的運(yùn)行時(shí)性能消耗的影響已經(jīng)大于它帶來(lái)的開(kāi)發(fā)體驗(yàn)的好處。而我們目前所使用的 Sass Modules 加上 Utility Classes 方案,在一定程度上也彌補(bǔ)了開(kāi)發(fā)體驗(yàn)的問(wèn)題。以上~

本文為翻譯文:

原文地址:https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,143評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,553評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,620評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,416評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,940評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,170評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,709評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,597評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,784評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評(píng)論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,029評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,407評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,663評(píng)論 1 280
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,403評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,746評(píng)論 2 370

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