前端性能優化

一、PC端優化策略?

? 主要包括網絡加載類、頁面渲染類、CSS優化類、JavaScript執行類、緩存類、圖片類、架構協議類等幾類;
1、網絡加載類
(1)減少HTTP資源請求次數:
? 在前端頁面中,通常建議盡可能合并靜態資源圖片、JavaScript或CSS代碼,減少頁面請求數和資源請求消耗,這樣可以縮短首屏加載時間,通過構建工具合并雪碧圖、CSS、JavaScript文件等都是為了減少HTTP資源請求次數,另外也要盡量避免重復的資源,防止增加多余請求;
(2)減少HTTP請求大小:
? 除了減少HTTP資源請求次數,也要盡量減少每個HTTP請求的大小,如減少沒必要的圖片、JavaScript、CSS 及 HTML 代碼,對文件進行壓縮優化,或者使用gzip壓縮傳輸內容等都可以用來減少文件大小,縮短網絡傳輸等待時延,使用構建工具來壓縮靜態圖片資源以及移除代碼中的注釋并壓縮,目的都是為了減少HTTP請求的大小;
(3)將CSS或JavaScript放到外部文件中,避免使用style或script標簽直接引入:
? 在HTML文件上引用外部資源可以有效利用瀏覽器的靜態資源緩存,但有時候在移動端頁面CSS或JavaScript比較簡單的情況下為了減少請求,也會將CSS或JavaScript直接寫到HTML里面,具體要根據CSS或JavaScript文件的大小和業務的場景來分析,如果CSS或JavaScript文件內容較多,業務邏輯較復雜,建議放到外部文件引入;
? <link rel="stylesheet" href="/css/master.css">
? <script type="text/javascript" src="http://cdn.domain.com/path/main.js"></script>
(4)避免頁面中空的href和src:
? 當<link>標簽的href屬性為空,或<script>、<img>、<iframe>標簽的src屬性為空時,瀏覽器在渲染過程中仍會將href屬性或者src屬性中的空內容進行加載,直至加載失敗,這樣就阻塞了頁面中其他資源的下載進程,而且最終加載到的內容是無效的,因此要盡量避免;
? <!--不推薦-->
? <img src="" alt="photo" >
? <a href="">點擊鏈接</a>
(5)為HTML指定Cache-Control或Expires:
? 為HTML內容設置Cache-Control 或 Expires可以將HTML內容緩存起來,避免頻繁向服務器端發送請求,在頁面中的Cache-Control 或 Expires頭部有效時,瀏覽器將直接從緩存中讀取內容,不再向服務器端發送請求;
? <meta http-equiv="Cache-Control" content="max-age=7200">
? <meta http-equiv="Expires" content="Mon,20Jul201623:00:00GMT">
(6)合理設置Etag和Last-Modified:
? 合理設置Etag 和 Last-Modified使用瀏覽器緩存,對于未修改的文件,靜態資源服務器會向瀏覽器端返回304,讓瀏覽器從緩存中讀取文件,減少Web資源下載的帶寬消耗并降低服務器負載;
? <meta http-equiv="last-modified" content="Sun,05 Nov 2017 13:45:57 GMT">
(7)減少頁面重定向:
? 頁面每次重定向都會延長頁面內容返回的等待延時,一次重定向大約需要200毫秒不等的時間開銷(無緩存),為了保證用戶盡快看到頁面內容,要盡量避免頁面重定向;
(8)使用靜態資源分域存放來增加下載并行數:
? 瀏覽器在同一時刻向同一域名請求文件的并行下載數是有限的,因此可以利用多個域名的主機來存放不同的靜態資源,增大頁面加載時資源的并行下載數,縮短頁面資源加載的時間,通常根據多個域名來分別存儲JavaScript、CSS和圖片文件;
? <link rel="stylesheet" >
? <script src="http://cdn2.domain.com/path/main.js"></script>
(9)使用靜態資源CDN來存儲文件:
? 如果條件允許,可以利用CDN網絡加快同一個地理區域內重復靜態資源文件的響應下載速度,縮短資源請求時間;
(10)使用CDN Combo下載傳輸內容:
? CDN Combo是在CDN服務器端將多個文件請求打包成一個文件的形式來返回的技術,這樣可以實現HTTP連接傳輸的一次性復用,減少瀏覽器的HTTP請求數,加快資源下載速度,例如同一個域名CDN服務器上的a.js,b.js,c.js就可以按如下方式在一個請求中下載:
? <script src="http://cdn.domain.com/path/a.js,b.js,c.js"></script>
(11)使用可緩存的AJAX:
? 對于返回內容相同的請求,沒必要每次都直接從服務端拉取,合理使用AJAX緩存能加快AJAX響應速度并減輕服務器壓力;
? $.ajax({
??? url: url,
??? type: 'get',
??? cache: true, //推薦使用緩存
??? data: {},
??? success() {},
??? error() {}
? });
(12)使用GET來完成AJAX請求:
? 使用XMLHttpRequest時,瀏覽器中的POST方法會發起兩次TCP數據包傳輸,首先會發送文件頭,然后發送HTTP正文數據,而使用GET時只發送頭部,所以在拉取服務端數據時使用GET請求效率更高;
? $.ajax({
??? url: url,
??? type: 'get', //推薦使用get完成請求
??? data: {},
??? success() {},
??? error() {}
? });
(13)減少Cookie的大小并進行Cookie隔離:
? HTTP請求通常默認帶上瀏覽器端的Cookie一起發送給服務器,所以在非必要的情況下,要盡量減少Cookie來減少HTTP請求的大小,對于靜態資源,盡量使用不同的域名來存放,因為Cookie默認是不能跨域的,這樣就做到了不同域名下靜態資源請求的Cookie隔離;
(14)縮小favicon.ico并緩存:
? 有利favicon.ico的重復加載,因為一般一個Web應用的favicon.ico是很少改變的;
(15)推薦使用異步JavaScript資源:
? 異步的JavaScript資源不會阻塞文檔解析,所以允許在瀏覽器中優先渲染頁面,延后加載腳本執行,例如JavaScript的引用可以如下設置,也可以使用模塊化加載機制來實現;其中使用async時,加載和渲染后續文檔元素的過程和main.js的加載與執行是并行的;使用defer時,加載后續文檔元素的過程和main.js的加載是并行的,但是main.js的執行要在頁面所有元素解析完成之后才開始執行;
? <script src="main.js" defer></script>
? <script src="main.js" async></script>
(16)消除阻塞渲染的CSS及JavaScript:
? 對于頁面中加載時間過長的CSS或JavaScript文件,需要進行合理拆分或延后加載,保證關鍵路徑的資源能快速加載完成;
(17)避免使用CSS import引用加載CSS:
? CSS中的@import可以從另一個樣式文件中引入樣式,但應該避免這種用法,因為這樣會增加CSS資源加載的關鍵路徑長度,帶有@import的CSS樣式需要在CSS文件串行解析到@import時才會加載另外的CSS文件,大大延后CSS渲染完成的時間;
? <!--不推薦-->
? <style>
? @import "path/main.css";
? </style>
? <!--推薦-->
? <link rel="stylesheet" >

2、頁面渲染類
(1)把CSS資源引用放到HTML文件頂部:
? 一般推薦將所有CSS資源指定在HTML文檔<head>中,這樣瀏覽器可以優先下載CSS并盡早完成頁面渲染;
(2)JavaScript資源引用放到HTML文件底部:
? JavaScript資源放到HTML文檔底部可以防止JavaScript的加載和解析執行對頁面渲染造成阻塞,由于JavaScript資源默認是解析阻塞的,除非被標記為異步或者通過其他的異步方式加載,否則會阻塞HTML DOM解析和CSS渲染過程;
(3)盡量預先設定圖片等大小:
? 在加載大量的圖片元素時,盡量預先限定圖片的尺寸大小,否則在圖片加載過程中會更新圖片的排版信息,產生大量的重排;
(4)不要在HTML中直接縮放圖片:
? 在HTML中直接縮放圖片會導致頁面內容的重排重繪,此時可能會使頁面中的其他操作產生卡頓,因此要盡量減少在頁面中直接進行圖片縮放;
(5)減少DOM元素數量和深度:
? HTML中標簽元素越多,標簽的層級越深,瀏覽器解析DOM并繪制到瀏覽器中所花的時間就越長,所以應盡可能保持DOM元素簡潔和層級較少;
? <!--不推薦-->
? <div>
??? <span>
??????? <a href="javascript:void(0);">
??????????? <img src="./path/photo.jpg" alt="圖片">
??????? </a>
??? </span>
? </div>
? <!--推薦-->
? <img src="./path/photo.jpg" alt="圖片" >
(6)盡量避免在選擇器末尾添加通配符:
? CSS解析匹配到渲染樹的過程是從右到左的逆向匹配,在選擇器末尾添加通配符至少會增加一倍多計算量;
(7)減少使用關系型樣式表的寫法:
? 直接使用唯一的類名即可最大限度的提升渲染引擎繪制渲染樹的效率;
(8)盡量減少使用JS動畫:
? JS直接操作DOM極容易引起頁面的重排;
(9)CSS動畫使用translate、scale代替top、height:
? 盡量使用CSS3的translate、scale屬性代替top、left和height、width,避免大量的重排計算;
(10)盡量避免使用<table>、<iframe>:
? <table>內容的渲染是將table的DOM渲染樹全部生成完并一次性繪制到頁面上的,所以在長表格渲染時很耗性能,應該盡量避免使用它,可以考慮使用列表元素<ul>代替;盡量使用異步的方式動態添加iframe,因為iframe內資源的下載進程會阻塞父頁面靜態資源的下載與CSS及HTML DOM的解析;
(11)避免運行耗時的JavaScript:
? 長時間運行的JavaScript會阻塞瀏覽器構建DOM樹、DOM渲染樹、渲染頁面,所以任何與頁面初次渲染無關的邏輯功能都應該延遲加載執行,這和JavaScript資源的異步加載思路是一致的;
(12)避免使用CSS表達式或CSS濾鏡:
? CSS表達式或CSS濾鏡的解析渲染速度是比較慢的,在有其他解決方案的情況下應該盡量避免使用;
? //不推薦
? .opacity{
??? filter : progid : DXImageTransform.Microsoft.Alpha( opacity = 50 );
? }


二、移動端優化策略

1、網絡加載類
(1)首屏數據請求提前,避免JavaScript文件加載后才請求數據:
? 為了進一步提升頁面加載速度,可以考慮將頁面的數據請求盡可能提前,避免在JavaScript加載完成后才去請求數據,通常數據請求是頁面內容渲染中關鍵路徑最長的部分,而且不能并行,所以如果能將數據請求提前,可以極大程度縮短頁面內容的渲染完成時間;
(2)首屏加載和按需加載,非首屏內容滾屏加載,保證首屏內容最小化:
? 由于移動端網絡速度相對較慢,網絡資源有限,因此為了盡快完成頁面內容的加載,需要保證首屏加載資源最小化,非首屏內容使用滾動的方式異步加載,一般推薦移動端頁面首屏數據展示延時最長不超過3秒,目前中國聯通3G的網絡速度為338KB/s (2.71Mb/s),所以推薦首屏所有資源大小不超過1014KB,即大約不超過1MB;
(3)模塊化資源并行下載:
? 在移動端資源加載中,盡量保證JavaScript資源并行加載,主要指的是模塊化JavaScript資源的異步加載,例如AMD的異步模塊,使用并行的加載方式能夠縮短多個文件資源的加載時間;
(4)inline首屏必備的CSS和JavaScript:
? 通常為了在HTML加載完成時能使瀏覽器中有基本的樣式,需要將頁面渲染時必備的CSS和JavaScript通過<script>或<style>內聯到頁面中,避免頁面HTML載入完成到頁面內容展示這段過程中頁面出現空白;
? <!DOCTYPE html>
? <head>
??? <meta charset="UTF-8">
??? <title>樣例</title>
??? <meta>
??? <style>
????? /*必備的首屏CSS*/
????? html,
????? body {
??????? margin: 0;
??????? padding: 0;
??????? background-color: #ccc;
????? }
??? </style>
? </head>
? <body>
? </body>
? </html>
(5)meta dns prefetch設置DNS預解析:
? 設置文件資源的DNS預解析,讓瀏覽器提前解析獲取靜態資源的主機IP,避免等到請求時才發起DNS解析請求,通常在移動端HTML中可以采用如下方式完成:
? <!--cdn域名預解析-->
? <meta http-equiv="x-dns-prefetch-control" content="on" >
? <link rel="dns-prefetch" >
(6)資源預加載:
? 對于移動端首屏加載后可能會被使用的資源,需要在首屏完成加載后盡快進行加載,保證在用戶需要瀏覽時已經加載完成,這時候如果再去異步請求就顯得很慢;
(7)合理利用MTU策略:
? 通常情況下,我們認為TCP網絡傳輸的最大傳輸單元(Maximum Transmission Unit,MTU)為 1500B,即一個 RTT(Round-Trip Time,網絡請求往返時間)內可以傳輸的數據量最大為1500字節,因此在前后端分離的開發模式中,盡量保證頁面的HTML內容在1KB以內,這樣整個HTML的內容請求就可以在一個RTT內請求完成,最大限度地提高HTML載入速度;

2、緩存類
(1)合理利用瀏覽器緩存:
? 除了上面所說的Cache-Control、Expires、Etag 和 Last-Modified來設置HTTP緩存外,在移動端還可以使用localStorage等來保存AJAX返回的數據,或者使用localStorage保存CSS或JavaScript靜態資源內容,實現移動端的離線應用,盡可能減少網絡請求,保證靜態資源內容的快速加載;
(2)靜態資源離線方案:
? 對于移動端或Hybrid應用,可以設置離線文件或離線包機制讓靜態資源請求從本地讀取,加快資源載入速度,并實現離線更新;
(3)嘗試使用AMP HTML
? AMP HTML可以作為優化前端頁面性能的一個解決方案,使用AMP Component中的元素來代替原始的頁面元素進行直接渲染;
? <!--不推薦-->
? <video width="400" height="300" src="http://www.domain.com/videos/myvideo.mp4"
? poster="path/poster.jpg">
? <div fallback>
??? <p>Your browser doesn’t support HTML5 video</p>
? </div>
? <source type="video/mp4" src="foo.mp4">
? <source type="video/webm" src="foo.webm">
? </video>
? <!--推薦-->
? <amp-video width="400" height="300" src="http://www.domain.com/videos/myvideo.mp4" poster="path/poster.jpg">
? <div fallback>
??? <p>Your browser doesn’t support HTML5 video</p>
? </div>
? <source type="video/mp4" src="foo.mp4">
? <source type="video/webm" src="foo.webm">
? </amp-video>
(4)嘗試使用PWA模式:
? PWA(Progressive Web Apps)是 Google 提出的用前沿的 Web 技術為網頁提供 App 般使用體驗的一系列方案;

3、圖片類
(1)圖片壓縮處理:
? 在移動端,通常要保證頁面中一切用到的圖片都是經過壓縮優化處理的,而不是以原圖的形式直接使用的,因為那樣很消耗流量,而且加載時間更長;
(2)使用較小的圖片,合理使用base64內嵌圖片:
? 在頁面使用的背景圖片不多且較小的情況下,可以將圖片轉化成base64編碼嵌入到HTML頁面或CSS文件中,這樣可以減少頁面的HTTP請求數,需要注意的是,要保證圖片較小,一般圖片大小超過2KB就不推薦使用base64嵌入顯示了;
? .class-name{
??? background-image : url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAALCAMAAABxsOwqAAAAYFBMVEWnxwusyQukxQudwQyZvgyhxAyfwgyxzAsUHQGOuA0aJAERGAFIXwSTugyEqgtqhghQZgUwQQIpOQKbuguVtQuKrAuCowp2kQlheghTbQZHWQU7SwVAVgQ6TgQlLwMeKwFOemyQAAAAVElEQVQI1y3JVRaAIAAF0UconXbvf5ei8HfPDIQQhBAAFE10iKig3SLRNN4SP/p+N08VC0YnfIlNWtqIkhg/TPYbCvhqdHAWRXPZSp3g3CWZvVLXC6OJA3ukv0AaAAAAAElFTkSuQmCC');
? }
(3)使用更高壓縮比格式的圖片:
? 使用具有較高壓縮比格式的圖片,如webp(需要設計降級兼容方案)等,在同等圖片畫質的情況下,高壓縮比格式的圖片體積更小,能夠更快完成文件傳輸,節省網絡流量;
? <img src="http://cdn.domain.com/path/photo.webp" alt="webp格式圖片" >
(4)圖片懶加載:
? 為了保證頁面內容的最小化,加速頁面的渲染,盡可能節省移動端網絡流量,頁面中的圖片資源推薦使用懶加載實現,在頁面滾動時動態載入圖片;
? <img data-src="http://cdn.domain.com/path/photo.jpg" alt="懶加載圖片" >
(5)使用MediaQuery 或 srcset根據不同屏幕加載不同大小圖片:
? 針對不同的移動端屏幕尺寸和分辨率,輸出不同大小的圖片或背景圖能保證在用戶體驗不降低的前提下節省網絡流量,加快部分機型的圖片加載速度,這在移動端非常值得推薦;
(6)使用iconfont代替圖片圖標:
? 在頁面中盡可能使用iconfont來代替圖片圖標,這樣做的好處有:使用iconfont體積較小,而且是矢量圖,因此縮放時不會失真;可以方便地修改圖片大小尺寸和呈現顏色;但是需要注意的是,iconfont引用不同webfont格式時的兼容性寫法,根據經驗推薦盡量按照以下順序書寫,否則不容易兼容到所有的瀏覽器上;
? @font-face{
??? font-family:iconfont;
??? src:url("./iconfont.eot");
??? src:url("./iconfont.eot?#iefix") format("eot"),
??? url("./iconfont.woff") format("woff"),
??? url("./iconfont.ttf") format("truetype");
? }
(7)定義圖片大小限制:
? 加載的單張圖片一般建議不超過30KB,避免大圖片加載時間長而阻塞頁面其他資源的下載,因此推薦10KB以內,如果用戶上傳的圖片過大,建議設置告警系統,幫助我們觀察了解整個網站的圖片流量情況,做出進一步的改善;
(8)強緩存策略:
? 對于一些永遠不會變的圖片可以使用強緩存的方式緩存在用戶的瀏覽器上;

4、腳本類
(1)盡量使用id:
? 選擇器選擇頁面DOM元素時盡量使用id選擇器,因為id選擇器速度最快;
(2)合理緩存DOM對象:
? 對于需要重復使用的DOM對象,要優先設置緩存變量,避免每次使用時都要從整個DOM樹中重新查找;
? //不推薦
? $('#mod.active').remove('active');
? $('#mod.not-active').addClass('active');
? //推薦
? let $mod=$('#mod');
? $mod.find('.active').remove('active');
? $mod.find('.not-active').addClass('active');
(3)頁面元素盡量使用事件代理,避免直接事件綁定:
? 使用事件代理可以避免對每個元素都進行綁定,并且可以避免出現內存泄露及需要動態添加元素的事件綁定問題,所以盡量不要直接使用事件綁定;
? //不推薦
? $('.btn').on('click',function(e){
??? console.log(this);
? });
? //推薦
? $('body').on('click','.btn',function(e){
??? console.log(this);
? });
(4)使用touchstart代替click:
? 由于移動端屏幕的設計,touchstart事件和click事件觸發時間之間存在300毫秒的延時,所以在頁面中沒有實現touchmove滾動處理的情況下,可以使用touchstart事件來代替元素的click事件,加快頁面點擊的響應速度,提高用戶體驗,但同時我們也要注意頁面重疊元素touch動作的點擊穿透問題;
? //不推薦
? $('body').on('click','.btn',function(e){
??? console.log(this);
? });
? //推薦
? $('body').on('touchstart','.btn',function(e){
??? console.log(this);
? });
(5)避免touchmove、scroll連續事件處理:
? 需要對touchmove、scroll這類可能連續觸發回調的事件設置事件節流,例如設置每隔16ms(60幀的幀間隔為16.7ms,因此可以合理地設置為16ms)才進行一次事件處理,避免頻繁的事件調用導致移動端頁面卡頓;
? //不推薦
? $('.scroller').on('touchmove','.btn',function(e){
??? console.log(this);
? });
? //推薦
? $('.scroller').on('touchmove','.btn',function(e){
??? let self=this;
??? setTimeout(function(){
????? console.log(self);
??? },16);
? });
(6)避免使用eval、with,使用join代替連接符+,推薦使用ECMAScript6的字符串模板,這些都是一些基礎的安全腳本編寫問題,盡可能使用較高效率的特性來完成這些操作,避免不規范或不安全的寫法;
(7)盡量使用ECMAScript6+的特性來編程:
? ECMAScript6+一定程序上更加安全高效,而且部分特性執行速度更快,也是未來規范的需要,所以推薦使用ECMAScript6+的新特性來完成后面的開發;

5、渲染類
(1)使用Viewport固定屏幕渲染,可以加速頁面渲染內容:
?? 一般認為,在移動端設置Viewport可以加速頁面的渲染,同時可以避免縮放導致頁面重排重繪;
(2)避免各種形式重排重繪:
? 頁面的重排重繪很耗性能,所以一定要盡可能減少頁面的重排重繪,例如頁面圖片大小變化,元素位置變化等這些情況都會導致重排重繪;
(3)使用CSS3動畫,開啟GPU加速:
? 使用CSS3動畫時可以設置transform:translateZ(0) 來開啟移動設備瀏覽器的GPU圖形處理加速,讓動畫過程更加流暢,但需要注意的是,在Native WebView 下 GPU 加速有幾率產生 App Crash;
? -webkit-transform:translateZ(0);
? -ms-transform:translateZ(0);
? -o-transform:translateZ(0);
? transform:translateZ(0);
(4)合理使用Canvas 和 requestAnimationFrame:
? 選擇Canvas 或requestAnimationFrame等更高效的動畫實現方式,盡量避免使用setTimeout、setInterval等方式來直接處理連續動畫;
(5)SVG 代替圖片:
? 部分情況下可以考慮使用SVG 代替圖片實現動畫,因為使用SVG格式內容更小,而且SVG DOM結構方便調整;
(6)不濫用float:
? 在DOM渲染樹生成后的布局渲染階段,使用float的元素布局計算比較耗性能,所以盡量減少float的使用,推薦使用固定布局或flex-box彈性布局的方式來實現頁面元素布局;
(7)不濫用web字體或過多font-size聲明:
? 過多的font-size聲明會增加字體的大小計算,而且也沒有必要;
(8)做好腳本容錯:
? 腳本容錯可以避免非正常環境的執行錯誤影響頁面的加載和不相關功能的使用;

6、架構協議類
(1)嘗試使用 SPDY 和 HTTP2:
? 在條件允許的情況下可以考慮使用 SPDY 協議來進行文件資源傳輸,利用連接復用加快傳輸過程,縮短資源加載時間,HTTP2 在未來也是可以考慮嘗試的;
(2)使用后端數據渲染:
? 使用后端數據渲染的方式可以加快頁面內容的渲染展示,避免空白頁面的出現,同時可以解決移動端頁面 SEO 的問題,如果條件允許,后端數據渲染是一個很不錯的實踐思路;
(3)使用 NativeView 代替 DOM 的性能劣勢:
? 可以嘗試使用 NativeView 的 MNV* 開發模式來避免 HTML DOM 性能慢的問題,目前使用 MNV* 的開發模式已經可以將頁面內容渲染體驗做到接近客戶端 Native 應用的體驗了,但需要避免 js Framework 和 native Framework 的頻繁交互;

雅虎網站性能優化的 14 條規則:

盡可能減少 HTTP 請求數

使用 CDN(內容分發網絡)

為文件頭指定 Expires 或 Cache-Control,使內容具有緩存性

使用 Gzip 壓縮內容

把 CSS 放到頂部

把 JavaScript 放在底部

避免在 CSS 中使用 Expressions

把 JavaScript 和 CSS 都放到外部文件中

減少 DNS 查找次數

壓縮 JavaScript 和 CSS

避免重定向

剔除重復的 JavaScript 和 CSS

配置 Etags

使 AJAX 緩存

對規則的分析:

代碼編寫方面的規則:

把 CSS 放到頂部

把 JavaScript 放在底部

把 JavaScript 和 CSS 都放到外部文件中

避免在 CSS 中使用 Expressions

使 AJAX 緩存

打包方面的規則:

盡可能減少 HTTP 請求數

壓縮 JavaScript 和 CSS

剔除重復的 JavaScript 和 CSS

部署方面的規則:

使用 CDN(內容分發網絡)

為文件頭指定 Expires 或 Cache-Control,使內容具有緩存性

使用 Gzip 壓縮內容

減少 DNS 查找次數

避免重定向

配置 Etags

對規則的實踐

部署方面的規則,應用 Nginx 為靜態文件添加 Expires 跟 Cache-Control 頭,

配置 Etags,并啟用 Gzip 壓縮。并且避免在 Nginx 中做重定向,有條件的話可以

啟用 CDN,并優化網絡配置以減少 DNS 查找次數。

代碼編寫方面的規則,需要在編寫代碼種形成規范。默認使用類似 jQuery 這樣的庫

便可以對 AJAX 進行緩存。

打包方面 Linner 可以合并 JavaScript 與 CSS 文件, 并且支持小圖片的合并,用以減少 HTTP 請求數。同時 Linner 的倉庫管理可以避免重復的 JavaScript 與 CSS文件的出現。在build過后所有的文件將會被壓縮。


三、前端SEO優化

一、搜索引擎工作原理

  當我們在輸入框中輸入關鍵詞,點擊搜索或查詢時,然后得到結果。深究其背后的故事,搜索引擎做了很多事情。

  在搜索引擎網站,比如百度,在其后臺有一個非常龐大的數據庫,里面存儲了海量的關鍵詞,而每個關鍵詞又對應著很多網址,這些網址是百度程序從茫茫的互聯網上一點一點下載收集而來的,這些程序稱之為“搜索引擎蜘蛛”或“網絡爬蟲”。這些勤勞的“蜘蛛”每天在互聯網上爬行,從一個鏈接到另一個鏈接,下載其中的內容,進行分析提煉,找到其中的關鍵詞,如果“蜘蛛”認為關鍵詞在數據庫中沒有而對用戶是有用的便存入數據庫。反之,如果“蜘蛛”認為是垃圾信息或重復信息,就舍棄不要,繼續爬行,尋找最新的、有用的信息保存起來提供用戶搜索。當用戶搜索時,就能檢索出與關鍵字相關的網址顯示給訪客。

  一個關鍵詞對用多個網址,因此就出現了排序的問題,相應的當與關鍵詞最吻合的網址就會排在前面了。在“蜘蛛”抓取網頁內容,提煉關鍵詞的這個過程中,就存在一個問題:“蜘蛛”能否看懂。如果網站內容是flash和js,那么它是看不懂的,會犯迷糊,即使關鍵字再貼切也沒用。相應的,如果網站內容是它的語言,那么它便能看懂,它的語言即SEO。

二、SEO簡介

  全稱:Search English Optimization,搜索引擎優化。自從有了搜索引擎,SEO便誕生了。

  存在的意義:為了提升網頁在搜索引擎自然搜索結果中的收錄數量以及排序位置而做的優化行為。簡言之,就是希望百度等搜索引擎能多多我們收錄精心制作后的網站,并且在別人訪問時網站能排在前面。

  分類:白帽SEO和黑帽SEO。白帽SEO,起到了改良和規范網站設計的作用,使網站對搜索引擎和用戶更加友好,并且網站也能從搜索引擎中獲取合理的流量,這是搜索引擎鼓勵和支持的。黑帽SEO,利用和放大搜索引擎政策缺陷來獲取更多用戶的訪問量,這類行為大多是欺騙搜索引擎,一般搜索引擎公司是不支持與鼓勵的。本文針對白帽SEO,那么白帽SEO能做什么呢?

  1. 對網站的標題、關鍵字、描述精心設置,反映網站的定位,讓搜索引擎明白網站是做什么的;

  2. 網站內容優化:內容與關鍵字的對應,增加關鍵字的密度;

  3. 在網站上合理設置Robot.txt文件;

  4. 生成針對搜索引擎友好的網站地圖;

  5. 增加外部鏈接,到各個網站上宣傳;

三、前端SEO

  通過網站的結構布局設計和網頁代碼優化,使前端頁面既能讓瀏覽器用戶能夠看懂,也能讓“蜘蛛”看懂。

搜索對著三項的權重逐個減小,title值強調重點即可;description把頁面內容高度概括,不可過分堆砌關鍵詞;keywords列舉出重要關鍵詞。

(一)合理的title、description、keywords

1、title

title,就是瀏覽器上顯示的那些內容,不僅用戶能看到,也能被搜索引擎檢索到(搜索引擎在抓取網頁時,最先讀取的就是網頁標題,所以title是否正確設置極其重要。)title一般不超過80個字符,而且詞語間要用英文“-”隔開,因為計算機只對英語的敏感性較高,對漢語的敏感性不高。

用法:<title>網站標題</title>

(1)首頁title寫法,一般是“網站名稱-主關鍵詞或一句含有主關鍵詞的描述”。一般網站名稱放后面,因為搜索引擎給予標題最前面的詞比后面的高。比如,做“冰箱”這個詞,就這樣寫“冰箱_變頻冰箱-海爾官網”。

(2)欄目頁title寫法,一般有2種:“欄目名稱-網站名稱”、“欄目名稱欄目關鍵詞-網站名稱”。而且欄目名稱最好用關鍵詞來確定,比如企業招聘欄目最好就用企業招聘,而不要起個讓人無法識別的名字如企業來人,企業看看,或企業加上一些特殊符號,這種寫法雖然很有個性,但會讓你的網站在優化上占了下風。

(3)分類列表頁title寫法,一般是“分類列表頁名稱-欄目名稱-網站名稱”,這個和欄目頁差不多。

(4)文章頁title寫法,一般有3種:“文章標題-網站名稱”、“內容標題-欄目名稱”、“內容標題-欄目名稱-網站名稱”。其中,“內容標題-欄目名稱-網站名稱”的寫法最為規范,但也相對復雜,它能給用戶很好的提示,讓用戶知道他在訪問哪篇文章,并且是在哪個網站的哪個欄目下。

2、description(內容摘要)

description是對于一個網頁的簡要內容概況。description一般不超過150個字符,描述內容要和頁面內容相關。

用法:<meta name=”Description” Content=”你網頁的簡述”>

(1)首頁description寫法,一般是將首頁的標題、關鍵詞和一些特殊欄目的內容融合到里面,寫成簡單的介紹。

(2)欄目頁description寫法,一般是將欄目的標題、關鍵字、分類列表名稱融合到里面,寫成簡單的介紹。

(3)分類列表頁description,這個就比較簡單了,一般只需要把分類列表的標題、關鍵詞融合在一起,寫成簡單的介紹。

(4)文章頁description寫法,一般有2種寫法,標準寫法就和前面的一樣,將文章標題、文章中的重要內容和關鍵詞融合在一起,寫成簡單的介紹。這是最好最標準的寫法。但是這樣寫比較麻煩,還有一種種偷懶的方法,你可以在文章首段和標題中加入關鍵詞,比如我這篇文章是講title、keywords、description的,那么在文章首段和標題中就加入這些內容,然后直接將文章首段的內容復制到description中即可。

3、keywords(關鍵詞)

keywords,主要作用是告訴搜索引擎本頁內容是圍繞哪些詞展開的。因此keywords的每個詞都要能在內容中找到相應匹配,才有利于排名。keywords一般不超過3個,每個關鍵詞不宜過長,而且詞語間要用英文“,”隔開。為什么用英文上文已經說過。而且,盡量將重要的關鍵字靠前放,因為靠后的關鍵字排名較差,除非你站有很高的權重。

用法:<meta name=”Keywords” Content=”關鍵詞1,關鍵詞2,關鍵詞3,關鍵詞4″>

(1)首頁keywords寫法,一般是“網站名稱,主要欄目名,主要關鍵詞”。

(2)欄目頁keywords寫法,一般是“欄目名稱,欄目關鍵字,欄目分類列表名稱”。

(3)分類列表頁keywords寫法,這個就比較簡單了,只要將你這個欄目中的主要關鍵字寫入即可。

(4)文章頁keywords寫法,建議大家提取文章中的關鍵詞,比如我的文章主要是講SEO優化的,那么我關鍵詞肯定是SEO優化,如果你覺得你提取關鍵詞的能力較差,也可以選擇文章中出現比較多的詞來作為關鍵詞,比如我現在寫的內容是關于title、keywords、description的,那我的文章頁關鍵詞就是這3個。

(二)語義化的HTML代碼,符合W3C規范:語義化代碼讓搜索引擎容易理解網頁

1. 什么是HTML語義化

? ? 什么是HTML語義化,我的理解是: 用最恰當的標簽來標記內容。通俗的說,就是告訴你:“這是一個一級標題或二級標題”,“這是一個段落”,“這是頭部”,“這是一個導航欄”,并不會告訴你:“這是紅色的”,“這個有多么寬,多么高”。標題脫了CSS這層外衣,它還是一個標題。這就是簡單的HTML語義化:表現網頁的結構。語義化的HTML元素指的是那些使用最恰當的HTML進行標記的內容,在標記構成中并不關心內容顯示。語義化的HTML是構建有效網站的基石。

2、在寫HTML代碼時應該注意

? ? 盡可能少的使用無語義的標簽div和span;

? ? 在語義不明顯時,既可以使用div或者p時,盡量用p, 因為p在默認情況下有上下間距,對兼容特殊終端有利;

? ? 不要使用純樣式標簽,如:b、font、u等,改用css設置。

? ? 需要強調的文本,可以包含在strong或者em標簽中(瀏覽器預設樣式,能用CSS指定就不用他們),strong默認樣式是加粗(不要用b),em是斜體(不用i);

? ? 使用表格時,標題要用caption,表頭用thead,主體部分用tbody包圍,尾部用tfoot包圍。表頭和一般單元格要區分開,表頭用th,單元格用td;

? ? 表單域要用fieldset標簽包起來,并用legend標簽說明表單的用途;

? ? 每個input標簽對應的說明文本都需要使用label標簽,并且通過為input設置id屬性,在lable標簽中設置for=someld來讓說明文本和相對應的input關聯起來。

3、HTML5常用的語義元素

? ? HTML5提供了新的語義元素來定義網頁的不同部分,它們被稱為“切片元素”,如圖所示

常用的語義化元素:

(1)header元素

? ? header 元素代表“網頁”或“section”的頁眉。

? ? 通常包含h1-h6元素或hgroup,作為整個頁面或者一個內容塊的標題。也可以包裹一節的目錄部分,一個搜索框,一個nav,或者任何相關logo。

? ? 整個頁面沒有限制header元素的個數,可以擁有多個,可以為每個內容塊增加一個header元素

? ? <header>

? ? ? <hgroup>

? ? <h1>網站標題</h1>

? ? <h1>網站副標題</h1>

? ? ? </hgroup>

? ? </header>

header使用注意:

? ? 可以是“網頁”或任意“section”的頭部部分;

? ? 沒有個數限制。

? ? 如果hgroup或h1-h6自己就能工作的很好,那就不要用header。

(2)footer元素

footer元素代表“網頁”或“section”的頁腳,通常含有該節的一些基本信息,譬如:作者,相關文檔鏈接,版權資料。如果footer元素包含了整個節,那么它們就代表附錄,索引,提拔,許可協議,標簽,類別等一些其他類似信息。

<footer> 我是頁腳 </footer>

footer使用注意:

? ? 可以是“網頁”或任意“section”的底部部分;

? ? 沒有個數限制,除了包裹的內容不一樣,其他跟header類似。

(3)hgroup元素

hgroup元素代表“網頁”或“section”的標題,當元素有多個層級時,該元素可以將h1到h6元素放在其內,譬如文章的主標題和副標題的組合

? ? <hgroup>

? ? ? <h1>這是一篇介紹HTML 5語義化標簽和更簡潔的結構</h1>

? ? ? <h2>HTML 5</h2>

? ? </hgroup>

hgroup使用注意:

? ? 如果只需要一個h1-h6標簽就不用hgroup

? ? 如果有連續多個h1-h6標簽就用hgroup

? ? 如果有連續多個標題和其他文章數據,h1-h6標簽就用hgroup包住,和其他文章元數據一起放入header標簽

(4)nav元素

nav元素代表頁面的導航鏈接區域。用于定義頁面的主要導航部分。

? ? <nav>

? ? <ul>

? ? <li>HTML 5</li>

? ? <li>CSS3</li>

? ? <li>JavaScript</li>

? ? </ul>

? ? </nav>

但是我在有些時候卻情不自禁的想用它,譬如:側邊欄上目錄,面包屑導航,搜索樣式,或者下一篇上一篇文章,但是事實上規范上說nav只能用在頁面主要導航部分上。頁腳區域中的鏈接列表,雖然指向不同網站的不同區域,譬如服務條款,版權頁等,這些footer元素就能夠用了。

nav使用注意:

? ? 用在整個頁面主要導航部分上,不合適就不要用nav元素;

(5)aside元素

aside元素被包含在article元素中作為主要內容的附屬信息部分,其中的內容可以是與當前文章有關的相關資料、標簽、名次解釋等。(特殊的section)

在article元素之外使用作為頁面或站點全局的附屬信息部分。最典型的是側邊欄,其中的內容可以是日志串連,其他組的導航,甚至廣告,這些內容相關的頁面。

? ? <article>

? ? <p>內容</p>

? ? <aside>

? ? <h1>標題呢</h1>

? ? <p>這里是內容呢</p>

? ? </aside>

? ? </article>

aside使用總結:

? ? aside在article內表示主要內容的附屬信息,

? ? 在article之外則可做側邊欄,沒有article與之對應,最好不用。

? ? 如果是廣告,其他日志鏈接或者其他分類導航也可以用

(6)section元素

section元素代表文檔中的“節”或“段”,“段”可以是指一篇文章里按照主題的分段;“節”可以是指一個頁面里的分組。

section通常還帶標題,雖然html5中section會自動給標題h1-h6降級,但是最好手動給他們降級。如下:

? ? <section>

? ? <h1>section是啥?</h1>

? ? <article>

? ? <h2>關于section</h1>

? ? <p>section的介紹</p>

? ? <section>

? ? <h3>關于其他</h3>

? ? <p>關于其他section的介紹</p>

? ? </section>

? ? </article>

? ? </section>

section使用注意:

一張頁面可以用section劃分為簡介、文章條目和聯系信息。不過在文章內頁,最好用article。section不是一般意義上的容器元素,如果想作為樣式展示和腳本的便利,可以用div。

? ? 表示文檔中的節或者段;

? ? article、nav、aside可以理解為特殊的section,所以如果可以用article、nav、aside就不要用section,沒實際意義的就用div

(7)article元素

article元素最容易跟section和div容易混淆,其實article代表一個在文檔,頁面或者網站中自成一體的內容,其目的是為了讓開發者獨立開發或重用。譬如論壇的帖子,博客上的文章,一篇用戶的評論,一個互動的widget小工具。(特殊的section)

除了它的內容,article會有一個標題(通常會在header里),會有一個footer頁腳。

? ? <article>

? ? <h1>一篇文章</h1>

? ? <p>文章內容..</p>

? ? <footer>

? ? <p><small>small內容</small></p>

? ? </footer>

? ? </article>

更多語義化元素:https://developer.mozilla.org/en-US/docs/Web/HTML/Element

4、一些簡單的語義化舉例

下面是一段html代碼,我們來進行優化

? ? <div class="main">

? ? <div class="h2">標簽的語義<a href="#">更多</a></div>

? ? <div class="p">段落1內容<span class="strong">強調內容</span></div>

? ? <div class="p">段落2內容</div>

? ? </div>

上述代碼添加CSS樣式可以達到效果,但用的只是向div,span這樣的無語義標簽,我們從標簽上看不出結構這樣顯然是不行的,我們需要用代碼清晰表現出:“哪是標題”,“哪是內容”。我們改進一下。

版本一

? ? <div class="main">

? ? <h2>標簽的語義 <a href="#">更多</a></h2>

? ? <p>段落一的各種內容.....<strong>強調的內容</strong></p>

? ? <p>段落二的內容。。。段落二的內容。。。</p>

? ? </div>

版本一比源代碼大有改進,從標簽可以分清哪是標題哪是內容,也能看到哪被強調,但仔細看有a鏈接在h2標簽中,雖然它們是在同一行,但a鏈接并不是屬于標題。我們也可以添加HTML5語音元素進行改進:

版本二

? ? <main>

? ? <header class="title">

? ? <h2>標簽的語義化</h2>

? ? <a href="#">更多</a>

? ? </header>

? ? <article class="content">

? ? <p>段落一的各種內容.....<strong>強調的內容</strong></p>

? ? <p>段落二的內容。。。</p>

? ? </article>

? ? </main>

版本二用HTML5定義的新標簽是語義化更加完美,寫到這里基本上也就可以了,但其實我們還可以利用ARIA(無障礙網頁倡議)更加使代碼完美。更加具有可讀性。

版本三

? ? <main role="main">

? ? <header class="title" role="heading">

? ? <h2>標簽的語義化</h2>

? ? <a href="#">更多</a>

? ? </header>

? ? <article class="content" role="contentinfo">

? ? <p>段落一的各種內容.....<strong>強調的內容</strong></p>

? ? <p>段落二的內容。。。</p>

? ? </article>

? ? </main>

?現在可以看到標簽中多了一些role屬性,那是ARIA中定義的地標角色定義它們可以使屏幕閱讀器更好的工作。當然并不是使用div這些標簽就是不重視語義化,有些時候因為樣式的需求必須使用這些無語義標簽,這時我們就應該大膽使用它們。但能少用盡量少用。

? ? 但是也不要因為html5新標簽的出現,而隨意用之,錯誤的使用肯定會事與愿違。所以有些地方還是要用div的,就是因為div沒有任何意義的元素,他只是一個標簽,僅僅是用來構建外觀和結構。因此是最適合做容器的標簽。

(三)非裝飾性圖片必須加alt

<img> 標簽的 alt 屬性指定了替代文本,用于在圖像無法顯示或者用戶禁用圖像顯示時,代替圖像顯示在瀏覽器中的內容。

示例:<img src="xxx.jpg" alt="海爾官網-雙門冰箱" />

1、alt標簽的作用:

? ? 增強內容相關性

它是可以利用漢字介紹文章內容的,對于一些特定的企業產品,由于視覺的體驗,它往往是少文字的。?

? ? 提高關鍵詞密度

在操作企業站的時候,我們經常遇到是站點首屏一個大的橫幅banner,幾乎占用了首頁的大部分頁面,為了有效的提高首頁核心關鍵詞密度,我們只能利用一切辦法增添關鍵詞,比如:在圖片的alt標簽中添加。?

(四)友情鏈接,好的友情鏈接可以快速的提高你的網站權重

? ? 友情鏈接,也稱為網站交換鏈接、互惠鏈接、互換鏈接、聯盟鏈接等,是具有一定資源互補優勢的網站之間的簡單合作形式,即分別在自己的網站上放置對方網站的LOGO圖片或文字的網站名稱,并設置對方網站的超鏈接(點擊后,切換或彈出另一個新的頁面),使得用戶可以從合作網站中發現自己的網站,達到互相推廣的目的,因此常作為一種網站推廣基本手段。

? ? 友情鏈接是指互相在自己的網站上放對方網站的鏈接。必須要能在網頁代碼中找到網址和網站名稱,而且瀏覽網頁的時候能顯示網站名稱,這樣才叫友情鏈接。

? ? 友情鏈接是網站流量來源的根本,比如一種可以自動交換鏈接的友情鏈接網站(每來訪一個IP,就會自動排到第一),這是一種創新的自助式友情鏈接互聯網模式。

(五)外鏈,高質量的外鏈,會給你的網站提高源源不斷的權重提升

? ? 外鏈就是指在別的網站導入自己網站的鏈接。導入鏈接對于網站優化來說是非常重要的一個過程。導入鏈接的質量(即導入鏈接所在頁面的權重)間接影響了我們的網站在搜索引擎中的權重。

? ? 外鏈是互聯網的血液,是鏈接的一種。沒有鏈接的話,信息就是孤立的,結果就是我們什么都看不到。一個網站是很難做到面面俱到的,因此需要鏈接到別的網站,將其他網站所能補充的信息吸收過來,連接外鏈不在于數量,而是在于鏈接外鏈的質量。

? ? 外鏈的效果不只是為了提高網站的權重,也不僅僅是為了提高某個關鍵詞的排名。一個高質量的外部鏈接是可以給網站帶來很好的流量。

(六)向各大搜索引擎登陸入口提交尚未收錄站點

百度提交入口:https://ziyuan.baidu.com/linksubmit/url

Google提交入口:http://www.google.com/addurl/?hl=zh-CN&continue=/addurl

360提交入口:http://info.so.360.cn/site_submit.html

搜狗提交入口:http://fankui.help.sogou.com/index.php/web/web/index?type=1

必應提交入口:https://www.bing.com/toolbox/webmaster/(必應的匿名提交url已經取消,需要去登陸Bing網站管理員到“配置我的網站”菜單選項中的“提交URL”工具)

其他的一些優化內容:

1.重要內容HTML代碼放在最前:搜索引擎抓取HTML順序是從上到下,保證重要內容一定會被抓取

2.少用iframe:搜索引擎不會抓取iframe中的內容

3.提高網站速度:網站速度是搜索引擎排序的一個重要指標

4.頁面內容盡量不要做成flash、圖片、視頻,這些東西蜘蛛是抓不到的,就算是必須的,也要生成相應的靜態頁面。有很多企業站看著很炫,全站flash,老板看著是爽了,做SEO優化的人員就要抓狂了,全站沒一個鏈接。

5.除首頁外別的頁面最好要加上面包屑型導航,導航結構一定要清晰。

6.做好404頁面,一般會加首頁鏈接及錯誤提示,并測試其返回狀態碼為404:1、用戶體驗友好,可以留住用戶,不至于直接關閉頁面;2、蜘蛛友好,可以返回抓取其他頁面。

7.網站結構呈扁平狀樹型,目錄結構不宜過深,每個頁面離首頁最多點擊不超過3次,過深不利于搜索引擎的抓取。

借鑒:https://blog.csdn.net/yuyuking/java/article/details/89374794

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