最新前端性能優(yōu)化方案(支持 Vite 和 Webpack)

前言

前端性能優(yōu)化可以大致可以從三個方面入手:打包構(gòu)建性能、網(wǎng)絡傳輸性能、運行性能。這三個方面涵蓋了我們從打包部署到用戶使用的全過程。本文將介紹一些具體的實施辦法。

打包構(gòu)建性能

壓縮代碼

代碼壓縮可以減少頁面的加載時間、減少對網(wǎng)絡帶寬的占用、增強代碼安全性。

Webpack 提供了許多壓縮代碼的插件,下面介紹其中兩個常用的插件:

  • UglifyJSPlugin

    UglifyJSPlugin 是一個可以將 JS 代碼壓縮至極致的插件。可以通過以下方式來安裝和配置:

    安裝:

    npm i uglifyjs-webpack-plugin -D
    

    引入:

    // webpack.config.js
    const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
    
    module.exports = {
      plugins: [new UglifyJsPlugin()],
    }
    
  • OptimizeCSSAssetsPlugin

    OptimizeCSSAssetsPlugin 是一個可以壓縮 CSS 代碼的插件。可以通過以下方式來安裝和配置:

    安裝:

    npm i optimize-css-assets-webpack-plugin -D
    

    引入:

    // webpack.config.js
    const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")
    
    module.exports = {
      optimization: {
        minimizer: [new OptimizeCSSAssetsPlugin({})],
      },
    }
    

通過使用 Webpack 提供的 UglifyJSPlugin 和 OptimizeCSSAssetsPlugin 插件,可以輕松地壓縮 JavaScript 和 CSS 代碼,從而提高頁面加載速度和性能。

Vite 壓縮代碼:

Vite 中默認開啟了代碼壓縮,下面是 Vite 的默認配置,一般情況下不需要修改。

// vite.config.js
import { defineConfig } from "vite"
export default defineConfig({
  build: {
    minify: "esbuild", // boolean | 'terser' | 'esbuild'
  },
})

如果需要,可以通過修改 minify 選項更改壓縮方式。默認為 Esbuild,它比 terser 快 20-40 倍,壓縮率只差 1%-2%。

壓縮打包體積

壓縮打包體積可以使用 GZIP,能大幅度減小打包后的文件大小。

WebPack 開啟 GZIP

使用 compression-webpack-plugin 插件可以在構(gòu)建過程中對文件進行 gzip 壓縮,并生成對應的 .gz 文件。

安裝:

npm i compression-webpack-plugin -D

引入:

// webpack.config.js
const CompressionPlugin = require("compression-webpack-plugin")

module.exports = {
  plugins: [
    new CompressionPlugin({
      algorithm: "gzip",
      test: /\.(js|css|html|svg)$/,
      threshold: 10240,
      minRatio: 0.8,
    }),
  ],
}

在上面的配置中使用了 compression-webpack-plugin 插件對所有的 .js、.css、.html 和 .svg 文件進行 gzip 壓縮,并設置了壓縮的閾值和比率。

Vite 開啟 GZIP

在 Vite 中開啟 gzip,可以使用 vite-plugin-compression 插件來實現(xiàn)。這個插件可以在構(gòu)建過程中對文件進行 gzip 壓縮,并生成對應的 .gz 文件。

安裝:

npm i vite-plugin-compression -D

引入:

// vite.config.js
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import viteCompression from "vite-plugin-compression"

export default defineConfig({
  plugins: [
    vue(),
    viteCompression({
      threshold: 10240, // the unit is Bytes
    }),
  ],
})

在這個配置中,我們使用 vite-plugin-compression 插件對所有大于 10KB 的文件進行 gzip 壓縮,并設置了壓縮的閾值。在構(gòu)建過程中,插件會自動在輸出目錄下生成對應的 .gz 文件。然后在 Web 服務器的配置文件中開啟 gzip,當瀏覽器請求文件時,服務器會將對應的 gzip 文件返回給瀏覽器。

更多配置,請參考 ?? vbenjs/vite-plugin-compression: Use gzip or brotli to compress resources

在服務器中開啟 GZIP

開啟 gzip 需要同時確保 Web 服務器已經(jīng)開啟了對應的 gzip 支持。

  • 以 nginx 為例:

    server {
      gzip on;
      gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
      gzip_min_length 10240;
      gzip_comp_level 6;
    }
    
  • 以 nodejs 為例:

    npm i compression
    
    // app.js
    const compression = require("compression")
    
    app.use(compression())
    

壓縮圖片

WebPack 壓縮圖片

在 Webpack 中,可以通過 image-webpack-loader 對圖片進行壓縮和優(yōu)化處理。

安裝:

npm i image-webpack-loader -D

引入:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: "file-loader",
            options: {
              name: "[name].[ext]",
              outputPath: "images/",
              publicPath: "images/",
            },
          },
          {
            loader: "image-webpack-loader",
            options: {
              mozjpeg: {
                quality: 80,
              },
              pngquant: {
                quality: [0.65, 0.9],
                speed: 4,
              },
              gifsicle: {
                interlaced: false,
              },
              webp: {
                quality: 75,
              },
            },
          },
        ],
      },
    ],
  },
}

在這個配置中,我們使用 file-loader 處理圖片文件,然后使用 image-webpack-loader 插件對圖片進行壓縮和優(yōu)化處理,其中 options 可以設置不同的壓縮算法和參數(shù)。

Vite 壓縮圖片

在 Vite 中常用的圖片壓縮插件有 imageminsquoosh,下面以 squoosh 為例:

  1. 安裝 vite-plugin-squoosh

    npm install vite-plugin-squoosh -D
    
  2. 配置 vite-plugin-squoosh

    // vite.config.js
    const { defineConfig } = require("vite")
    const vue = require("@vitejs/plugin-vue")
    const squooshPlugin = require("vite-plugin-squoosh")
    
    module.exports = defineConfig({
      plugins: [
        vue(),
        squooshPlugin({
          // Specify codec options.
          codecs: {
            mozjpeg: { quality: 30, smoothing: 1 },
            webp: { quality: 25 },
            avif: { cqLevel: 20, sharpness: 1 },
            jxl: { quality: 30 },
            wp2: { quality: 40 },
            oxipng: { level: 3 },
          },
          // Do not encode .wp2 and .webp files.
          exclude: /.(wp2|webp)$/,
          // Encode png to webp.
          encodeTo: [{ from: /.png$/, to: "webp" }],
        }),
      ],
    })
    

更多配置請參考 ?? vite-plugin-squoosh

網(wǎng)絡傳輸性能

大量的 HTTP 請求會給服務器和瀏覽器造成一定的壓力,導致前端獲取響應的時間增加,從而造成頁面加載時間過長。優(yōu)化網(wǎng)絡傳輸性能可以從以下幾個方面入手:

圖片使用 LazyLoad 懶加載

懶加載也稱為延遲加載。基本思想是,在頁面加載時只加載當前頁面可視區(qū)域的圖片,而其它圖片等用戶滾動到可視區(qū)域頁面時再進行加載。

Vue 中實現(xiàn)圖片懶加載

在 Vue 中實現(xiàn)圖片懶加載,可以使用 vue-lazyload 插件

  1. 安裝 vue-lazyload

    npm i vue-lazyload
    
  2. 引入 vue-lazyload

    // main.js
    import Vue from "vue"
    import VueLazyload from "vue-lazyload"
    
    Vue.use(VueLazyload)
    
  3. 在需要懶加載的圖片上使用 v-lazy 指令

    <template>
      <img v-lazy="imgUrl" alt="圖片" />
    </template>
    

更多配置點擊這里 ?? vue-lazyload

React 中實現(xiàn)圖片懶加載

在 React 中實現(xiàn)圖片懶加載,可以借助 react-lazyload

  1. 安裝 react-lazyload

    npm i react-lazyload
    
  2. 在組件中引入 react-lazyload

    import React from "react"
    import LazyLoad from "react-lazyload"
    
    function MyComponent() {
      return (
        <div>
          <LazyLoad>
            <img src='path/to/image' alt='image' />
          </LazyLoad>
        </div>
      )
    }
    

更多配置點擊這里 ?? react-lazyload

原生 JS 實現(xiàn)圖片懶加載

原生 JS 實現(xiàn)圖片懶加載可以使用 Element.getBoundingClientRect() 方法,該方法會返回元素的大小及其相對于視口的位置。然后判斷圖片是否出現(xiàn)在頁面上。

<img class="lazyload" data-src="https://picsum.photos/200/300" />
<img class="lazyload" data-src="https://picsum.photos/200/300" />
<img class="lazyload" data-src="https://picsum.photos/200/300" />
// 獲取需要懶加載的圖片元素
const lazyloadImages = document.querySelectorAll(".lazyload")
// 獲取視口高度和寬度
const windowHeight = window.innerHeight
const windowWidth = window.innerWidth

// 判斷一個元素是否在視口內(nèi)
function isInViewport(element) {
  const rect = element.getBoundingClientRect()
  return rect.top >= 0 && rect.left >= 0 && rect.bottom <= windowHeight && rect.right <= windowWidth
}

// 監(jiān)聽窗口的滾動事件
window.addEventListener("scroll", function () {
  lazyloadImages.forEach(img => {
    if (isInViewport(img)) {
      img.src = img.dataset.src
      img.classList.remove("lazyload")
    }
  })
})

使用 CSS3 代替簡單圖片

可以利用 CSS3 代替一些簡單的圖片,這樣就可以減少一些圖片請求,提高頁面加載速度。

使用 Data URI

將小圖片轉(zhuǎn)為 Data URI 格式,直接嵌入 CSS 或 HTML 中,可以避免請求。但是需要注意,Data URI 格式的圖片會增加頁面大小,需要根據(jù)實際情況進行權衡和選擇。下面介紹在 Webpack 和 Vite 中將小圖片轉(zhuǎn)換為 base64 編碼的 Data URI 格式的方法。

  • Webpack 中將小圖片轉(zhuǎn)換為 base64

    在 Webpack 中,可以使用 url-loader 或者 file-loader 將小圖片轉(zhuǎn)換成 base64 編碼的 Data URI 格式。這兩個 loader 都是用于處理文件的,可以將文件轉(zhuǎn)換成模塊,以便在代碼中引用。

    其中,url-loader 和 file-loader 的主要區(qū)別在于處理方式不同。url-loader 在處理圖片時,會先判斷圖片大小是否超過指定的限制,如果超過了限制,則使用 file-loader 進行處理;如果沒有超過限制,則將圖片轉(zhuǎn)換成 base64 編碼的 Data URI 格式,并嵌入到代碼中,以減少 HTTP 請求次數(shù)。

    // webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif)$/,
            use: [
              {
                loader: "url-loader",
                options: {
                  limit: 8192, // 小于 8KB 的圖片會被轉(zhuǎn)換成 base64 編碼的 Data URI 格式
                  fallback: "file-loader", // 超過 8KB 的圖片使用 file-loader 進行處理
                },
              },
            ],
          },
        ],
      },
    }
    
  • Vite 中將小圖片轉(zhuǎn)換為 base64

    在 Vite 中,可以通過配置 assetsInlineLimit 選項來指定大小限制,小于指定大小的圖片將被轉(zhuǎn)換成 base64 編碼的 Data URI 格式。

    下面是在 Vite 中配置 assetsInlineLimit 的示例:

    // vite.config.js
    module.exports = {
      build: {
        assetsInlineLimit: 8192, // 小于 8KB 的圖片會被轉(zhuǎn)換成 base64 編碼的 Data URI 格式
      },
    }
    

使用雪碧圖或字體圖標代替圖標圖片

  • 將多個小圖標合并成一張圖片,通過 CSS 背景定位來顯示不同的圖片,減少請求次數(shù)。

  • 或者使用字體圖標來代替圖標圖片,減少請求次數(shù)。

合并文件

將多個 CSS 文件或 JavaScript 文件合并成一個文件,減少請求次數(shù)。

使用 HTTP/2

HTTP/2 是一種新的協(xié)議,相比 HTTP/1.1,可以更快地傳輸數(shù)據(jù)。 HTTP/1.1 的 Headers 采用的是文本格式,并且每一次請求都會帶上一些完全相同的數(shù)據(jù),而 HTTP/2 采用的是二進制編碼,并且對 Headers 進行了 HPack 壓縮,進而提升了傳輸效率。不僅如此,HTTP/2 還可以同時發(fā)送多個請求和響應,因此可以通過合并和壓縮資源,減少請求的數(shù)量,提高頁面加載速度。

HTTP/2 是向下兼容的,當瀏覽器不支持的時候會自動切換到 HTTP/1.1。但需要在服務器端和客戶端同時配置才能生效。

可以通過以下步驟來升級到 HTTP/2:

  1. 使用 HTTPS:HTTP/2 只支持加密連接,因此需要使用 HTTPS 來使用 HTTP/2。

  2. 在服務器端啟用 HTTP/2:需要在服務器端啟用 HTTP/2,以便前端可以使用該協(xié)議。常見的 Web 服務器,如 Nginx 和 Apache,都支持 HTTP/2。

Nginx 啟用 HTTP/2 請參考這里 ?? Supporting HTTP/2 for Google Chrome Users | NGINX

另外,關于 HTTP 版本之間的區(qū)別,可以參考 ?? 了解 HTTP 的前世今生

異步加載 JS 和 CSS

使用異步加載可以提高頁面響應速度,具體來說,可以采取以下措施:

  • 將 JavaScript 腳本放在頁面底部,或者使用 defer 或 async 屬性延遲 JavaScript 加載和執(zhí)行。

  • 將 CSS 樣式通過 link 標簽異步加載,也可以使用 JavaScript 動態(tài)加載樣式表。

使用 CDN

服務器的位置是固定的,負載也是有限的。通常訪客區(qū)域距離服務器越遠,打開網(wǎng)站速度越慢。如果在高峰時間段,網(wǎng)站訪問量很大,服務器無法負載,也會導致訪問速度下降。

因此,我們可以將某些資源放到 CDN 上,這樣就可以減少對服務器的 HTTP 請求。從而提高頁面加載速度。


運行性能

避免重繪(Repaint)和重排(Reflow)

重繪和重排都會導致頁面或部分頁面重新渲染,所以我們應當盡量避免觸發(fā)這兩個瀏覽器事件。

重繪(Repaint) 就是瀏覽器使用新的樣式重新渲染一個元素。改變元素的以下樣式通常會觸發(fā)重繪,應當盡量避免:

  • background

  • border

  • border-radius

  • box-shadow

  • color

  • visibility

  • outline

如果需要改變元素的某些 CSS 屬性,盡量一次性改變,減少觸發(fā)重繪的次數(shù)。

重排(Reflow) 就是瀏覽器重新渲染部分或全部頁面,通常是當元素的尺寸發(fā)生改變或者瀏覽器的一些行為影響到頁面布局而觸發(fā)的,比如

  • clientWidthclientHeight 等窗口屬性改變

  • box-sizingwidthheightborderpadding 等元素尺寸改變

  • font-sizeline-height 等元素字體大小改變

  • marginfloatflex-direction 等元素位置改變

如果需要改變元素位置或尺寸,可以使用以下屬性避免重排:

  • position: fixed | absolute 使元素脫離文檔流。

  • transform 屬性不會觸發(fā)避免重排。

使用節(jié)流防抖

在用戶瀏覽網(wǎng)頁或者在網(wǎng)頁上進行一些操作時,我們常常需要監(jiān)聽一些事件去完成相應的功能。比如鼠標點擊、鍵盤輸入、滾輪滾動等一些其它事件。

在處理這些事件時,我們常常會發(fā)現(xiàn),如果一個事件發(fā)生的頻率過高,相應的代碼執(zhí)行的頻率也會越高。

所以,我們并不需要代碼如此高頻率的執(zhí)行,這在一定程度上對系統(tǒng)資源造成了浪費,程序的性能也會因此變得很差。因此,我們需要使用節(jié)流防抖,對代碼的執(zhí)行頻率進行一些限制。

基本的節(jié)流函數(shù)

/**
 * @description 節(jié)流函數(shù)
 * @param {Function} func 需要節(jié)流的函數(shù)
 * @param {Number} wait 節(jié)流的時間
 * @returns {Function} 返回節(jié)流后的函數(shù)
 */
function throttle(func, wait) {
  let timer = null
  return function () {
    if (timer) return
    timer = setTimeout(() => {
      func.apply(this, arguments)
      timer = null
    }, wait)
  }
}

基本的防抖函數(shù)

/**
 * @description 防抖函數(shù)
 * @param {Function} func 需要防抖的函數(shù)
 * @param {Number} wait 防抖的時間
 * @returns {Function} 返回防抖后的函數(shù)
 */
function debounce(func, wait) {
  let timeout
  return function () {
    timeout && clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(this, arguments)
    }, wait)
  }
}

使用示例

// 節(jié)流
input.addEventListener("input", throttle(printInputText, 500))

// 防抖
input.addEventListener("input", debounce(printInputText, 500))

更多有關節(jié)流防抖的使用,可以參考 ?? 手寫實現(xiàn)節(jié)流防抖

使用服務端渲染(SSR)

SSR(Server-Side Rendering,服務端渲染)是指將 Web 頁面的生成過程從瀏覽器端轉(zhuǎn)移到服務器端完成的一種技術。

在傳統(tǒng)的 SPA(Single Page Application,單頁應用)中,瀏覽器需要先下載 HTML、CSS、JavaScript 文件,并在客戶端執(zhí)行 JavaScript 代碼,才能生成頁面內(nèi)容。這樣的過程需要加載大量的 JavaScript 代碼,會導致首屏渲染時間較長,影響用戶體驗。而通過 SSR 技術,服務器可以將頁面的 HTML、CSS 和 JavaScript 代碼預先生成好,并將渲染好的 HTML 代碼直接返回給瀏覽器,從而加快頁面加載速度,提高用戶體驗。

SSR 在性能提升方面有以下優(yōu)點:

  • 提高頁面加載速度:SSR 可以將渲染頁面的工作從瀏覽器端轉(zhuǎn)移到服務器端,減少瀏覽器的工作量,從而加快頁面加載速度。

  • 提高首屏渲染速度:SSR 可以將頁面的渲染過程提前到服務器端完成,使得頁面在瀏覽器端顯示的速度更快,從而提高用戶體驗。

  • 更好的可訪問性:通過 SSR 技術,我們可以生成更符合 Web 標準的 HTML 頁面,從而使得頁面具有更好的可訪問性。

有關 SSR 的更多介紹,可以參考 五分鐘了解 SPA 與 SSR

使用 Web Workers

使用 Web Workers 可以將一些任務放在后臺線程中執(zhí)行,以避免阻塞主線程。主線程通常用于處理用戶界面的更新和響應用戶的操作,如果在主線程中執(zhí)行耗時的任務,會導致用戶界面出現(xiàn)卡頓或失去響應。使用 Web Workers 可以將這些耗時的任務放在后臺線程中執(zhí)行,從而避免阻塞主線程。Web Workers 可以與主線程進行通信,使得后臺線程可以向主線程發(fā)送消息,而主線程也可以向后臺線程發(fā)送消息。這種通信可以通過 postMessage 方法實現(xiàn)。

Web Workers 的使用有一定的限制,例如它們不能訪問 DOM 和一些瀏覽器 API。但是,如果應用程序需要處理大量數(shù)據(jù)或進行復雜的計算,使用 Web Workers 可以提高應用程序的性能和響應速度。

以下是一個使用 Web Workers 的實際案例和代碼示例:

假設我們有一個應用程序需要處理大量的數(shù)據(jù),例如計算數(shù)組中所有元素的平均值。由于數(shù)據(jù)量很大,如果在主線程中執(zhí)行這個任務,會導致頁面出現(xiàn)卡頓或失去響應。因此,我們可以使用 Web Workers 將這個任務放在后臺線程中執(zhí)行,從而避免阻塞主線程。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Web Workers Example</title>
  </head>
  <body>
    <p>計算數(shù)組中所有元素的平均值:</p>
    <p id="result"></p>
    <script>
      // 創(chuàng)建 Web Worker
      const worker = new Worker("worker.js")
      // 發(fā)送消息給 Web Worker
      worker.postMessage([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
      // 監(jiān)聽 Web Worker 的消息
      worker.onmessage = function (event) {
        // 將計算結(jié)果顯示在頁面上
        document.getElementById("result").textContent = event.data
      }
    </script>
  </body>
</html>
// worker.js
// 監(jiān)聽主線程的消息
onmessage = function (event) {
  // 計算數(shù)組中所有元素的平均值
  const sum = event.data.reduce((a, b) => a + b, 0)
  const average = sum / event.data.length
  // 發(fā)送計算結(jié)果給主線程
  postMessage(average)
}

參考資料:

特別感謝:

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

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