前端性能優化

在以前的開發中,常常會接觸到前端性能優化的問題,這段時間看了一系列大佬的課程與博客,下面主要對前端性能優化進行一個總結。javascript

1、目錄

  • 基礎優化
    • 前端優化原理解析
    • HTML優化
    • css優化
    • js優化
    • 圖片優化
    • 文件合併優化
  • 進階優化
    • 文件懶加載與預加載
    • 重繪與迴流
    • 瀏覽器緩存
    • 瀏覽器緩存策略

2、基礎優化

一、前端優化原理解析

問題一:一個請求從發出到返回結果經歷了什麼? css

下面是對上圖的一個具體的描述:

用戶首先在瀏覽器中輸入一個url,瀏覽器中的核心代碼會將url進行拆分解析。瀏覽器會將domain發送到dns服務器,dns服務器會根據domain查詢對應的ip地址,同時將ip地址返回給瀏覽器,瀏覽器在持有ip地址以後,就會知道這個請求要發送的地址,就跟隨協議,將ip地址打在協議中,而且請求相關的參數都攜帶,發送到咱們的網絡中,通過局域網、交換機、路由器、主幹網絡,以後請求會到達咱們的服務端,服務端是MVC架構,請求會首先進入到controller中,在controller中進行相關邏輯的分發,調用model層,model是與數據進行交互的,在數據進行交互中,去拿數據庫的數據,最後將咱們渲染好的數據經過view層分發到網絡中,http請求的response就從服務端又回到了瀏覽器,瀏覽器就開始render。html

潛在的性能優化點:前端

  • 一、dns緩存
  • 二、減小http請求
  • 三、減少http請求的大小
  • 四、網絡請求的時候走最近的網絡請求
  • 五、瀏覽器端緩存

問題二:一個網站在瀏覽器端是如何進行渲染的? java

下面是對上圖的一個具體的描述:web

請求返回一段HTML文檔,這一段HTML文檔會被瀏覽器中的HTML parse 這一個解析器進行解析,經過詞法分析的過程將tag分析爲token,依次從html文檔中從上到下去解析token,由於他是用next token的方式不斷的從上到下進行解析的,在詞法分析的過程當中是能夠相應的解析出link script這樣的標籤,這樣的標籤裏面所對應的web資源會進一步的由瀏覽器向網絡發起請求。請求回來的JavaScript web資源會交給瀏覽器中的v8 JavaScript執行引擎去執行。css相關的資源請求回來以後會由瀏覽器生成相應的CSSOM樹。頁面渲染的前提是DOM樹和CSSOM樹都有了以後,去生成Render tree,進一步進行一個佈局,從而進行繪製。數據庫

總結 從上面的兩個問題咱們能夠看出前端性能優化的基礎優化的核心就是減小http請求和減少http請求的大小。gulp

二、HTML優化

  • 原理
  • 實現方式

原理 壓縮包括空格,製表符,換行符等,還有一些其餘意義的字符,如HTML註釋也能夠被壓縮。瀏覽器

實現方式 一、gulp中使用gulp-htmlmin插件進行壓縮 二、在線的壓縮軟件進行壓縮(不適用與大的項目)緩存

gulp.task('htmlmin', function() {
   	var options = {
   		removeComments: true, //清除HTML註釋
   		collapseWhitespace: true, //壓縮HTML
   		collapseBooleanAttributes: true, //省略布爾屬性的值 <input checked="true"/> ==> <input />
   		removeEmptyAttributes: true, //刪除全部空格做屬性值 <input id="" /> ==> <input />
   		removeScriptTypeAttributes: true, //刪除<script>的type="text/javascript"
   		removeStyleLinkTypeAttributes: true, //刪除<style>和<link>的type="text/css"
   		minifyJS: true, //壓縮頁面JS
   		minifyCSS: true //壓縮頁面CSS
   	};
   	var htmlSrc = './src/*.html',
   		htmlDst = './dist';
   	gulp.src(htmlSrc)
   		.pipe(htmlmin(options))
   		.pipe(gulp.dest(htmlDst)); //同名的html,會直接替換
   });
複製代碼

三、CSS優化

  • 原理
  • 實現方式

原理 無效代碼刪除、空格刪除、製表符刪除

實現方式 一、gulp中使用gulp-minify-css插件進行壓縮 二、在線的壓縮軟件進行壓縮(不適用與大的項目)

四、JS優化

  • 原理
  • 實現方式

原理 無效字符的刪除、剔除註釋、代碼語義的縮減和優化、代碼保護(將一些具備語義化的名稱修改成a/b/c之類的)

實現方式 一、gulp中使用gulp-uglify插件進行壓縮 二、在線的壓縮軟件進行壓縮(不適用與大的項目)

五、圖片優化

圖片類型

  • jpg 有損壓縮 壓縮率高 不支持透明
  • png 支持透明 瀏覽器兼容性好
  • webp 壓縮程度更好 在iOS webview有兼容性問題
  • SVG 矢量圖 圖片樣式相對簡單的場景

解決方法

  • Image Inline(減小http請求的數量)
  • 雪碧圖(減小http請求的數量)

實現方法

  • 在線的圖片壓縮軟件
  • gulp的gulp-imagemin圖片壓縮插件

六、文件合併與優化

存在的問題

  • 首屏渲染問題(多個文件合併致使一個http請求過大,請求時間過長)
  • 緩存失效問題(合併後任何一個文件的修改都會致使緩存失效)

解決方法

  • 公共庫合併
  • 不一樣頁面的合併

實現方法

使用gulp的gulp-concat插件進行文件合併。

3、進階優化

一、文件懶加載與預加載

懶加載

  • 圖片進入可視區域以後請求圖片資源
  • 對於電商等圖片不少,頁面很長的業務場景適用
  • 減小無效資源的加載
  • 併發加載的資源過多會阻塞js的加載,影響網站的正常使用

預加載

  • 圖片等靜態資源在使用以前的提早請求
  • 資源使用到時能從緩存中加載,提高用戶體驗
  • 頁面展現的依賴關係維護

懶加載實現方法 HTML代碼

<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8" />
	<title>lazyload</title>
	<link rel="stylesheet" href="main.css" />
</head>
<body>
	<div class="image-list">
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i3/3851834739/TB2KAmyBHGYBuNjy0FoXXciBFXa_!!3851834739.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i3/3851834739/TB2RYRxqeGSBuNjSspbXXciipXa_!!3851834739-0-item_pic.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i3/1210506068553231586/TB2ZL6qt3RkpuFjy1zeXXc.6FXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i2/511076404/TB2J7wUApmWBuNjSspdXXbugXXa_!!511076404.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i3/23745640/TB2zBv9D1uSBuNjy1XcXXcYjFXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i3/587488716/TB2OyN5wrSYBuNjSspiXXXNzpXa_!!587488716.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i1/114335006/TB2IewMr41YBuNjy1zcXXbNcXXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i4/2782657655/TB2VvzUfYorBKNjSZFjXXc_SpXa_!!2782657655.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i3/13016599/TB2TuxpuGSWBuNjSsrbXXa0mVXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i2/90919986/TB2KqfVxv9TBuNjy1zbXXXpepXa_!!90919986.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i4/52863407/TB2mKqZDkKWBuNjy1zjXXcOypXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i3/1969607927/TB25oQdaIuYBuNkSmRyXXcA3pXa_!!1969607927.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i2/31490775/TB26MyDb8smBKNjSZFsXXaXSVXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i1/886644258/TB29ufKvrxmpuFjSZJiXXXauVXa_!!886644258.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i2/886644258/TB2D9pNwSxjpuFjSszeXXaeMVXa_!!886644258.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i2/121453312/TB2iATKD29TBuNjy0FcXXbeiFXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i4/3083173120/TB2CCLWDr5YBuNjSspoXXbeNFXa_!!3083173120.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i4/15303864/TB2eVxzhYsrBKNjSZFpXXcXhFXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i2/694223667/TB2N4cXy1ySBuNjy1zdXXXPxFXa_!!694223667.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i4/73861778/TB2r8vgl4uTBuNkHFNRXXc9qpXa_!!73861778.jpg_100x100xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/bao/uploaded/i2/26868233/TB2j2jQAhSYBuNjSsphXXbGvVXa_!!0-saturn_solar.jpg_240x240xzq75.jpg" />
		<img src="" class="image-item" lazyload="true" data-original="https://gma.alicdn.com/i3/694223667/TB21ohCqOCYBuNkHFCcXXcHtVXa_!!694223667.jpg_100x100xzq75.jpg" />
	</div>
	
	<script type="text/javascript" src="lazyload.js"></script>
</body>
</html>
複製代碼

CSS

.image-item{
	width: 40%;
	margin-right: 5%;
	display: inline-block;
	height: 400px;
	background: gray;
}

.image-list{
	margin-left: 5%;
}
複製代碼

JS

/**
 * 原理 須要比較可視區域的高度和當前圖片在區域內的top值來決定是否加載圖片
 * Element.getBoundingClientRect()方法返回元素的大小及其相對於視口的位置。
 * 
 * dataset 用於獲取某個屬性的值
 * */

var viewHeight = document.documentElement.clientHeight;


function lazyload(){
	var eles = document.querySelectorAll('img[data-original][lazyload]');
	Array.prototype.forEach.call(eles,function(item,index){
		var rect;
		if(item.dataset.original === '')
			return;
		rect = item.getBoundingClientRect();
		if(rect.bottom >=0 && rect.top < viewHeight){
			!function(){
				var img = new Image();
				img.src = item.dataset.original;
				img.onload = function(){
					item.src= img.src;
				}
				item.removeAttribute('data-original');
				item.removeAttribute('lazyload');
			}()
		}
	})
}

lazyload();

document.addEventListener('scroll', lazyload);
複製代碼

預加載實現方法

img標籤 + display:none
<img src="../a.png" style="display:none;" />

new Image()
var img =new Image();
img.src="sdsds.png";
複製代碼

二、重繪與迴流

  • 問題
  • 瀏覽器重繪與迴流機制
  • 什麼是重繪
  • 什麼是迴流
  • 哪些操做可以出噶重繪和迴流?

問題一:CSS性能讓JavaScript變慢?(會)

CSS和JavaScript會相互阻塞(JavaScript可能在代碼中獲取相關的渲染結果) 一個線程 => JavaScript解析 一個線程 => UI渲染

====全部這兩個線程是互斥的====

總結 前端性能優化與重繪與迴流有關係的緣由是:頻繁的觸發重繪與迴流,會致使UI頻繁渲染,最終會致使js變慢,會致使頁面性能變差。

迴流 尺寸、佈局、隱藏等改變須要從新構建,就稱爲迴流。

觸發迴流的因素:

  • 盒子模型相關屬性
  • 定位及浮動相關屬性
  • 節點內部文字結構

重繪 外觀、風格改變而不影響佈局須要重繪

三、瀏覽器緩存

  • cookie
  • localstroage sessionstorage
  • Service Workers

四、緩存

  • cache-control
  • expires
  • last-modified
  • etag
相關文章
相關標籤/搜索