在以前的開發中,常常會接觸到前端性能優化的問題,這段時間看了一系列大佬的課程與博客,下面主要對前端性能優化進行一個總結。javascript
問題一:一個請求從發出到返回結果經歷了什麼? css
用戶首先在瀏覽器中輸入一個url,瀏覽器中的核心代碼會將url進行拆分解析。瀏覽器會將domain發送到dns服務器,dns服務器會根據domain查詢對應的ip地址,同時將ip地址返回給瀏覽器,瀏覽器在持有ip地址以後,就會知道這個請求要發送的地址,就跟隨協議,將ip地址打在協議中,而且請求相關的參數都攜帶,發送到咱們的網絡中,通過局域網、交換機、路由器、主幹網絡,以後請求會到達咱們的服務端,服務端是MVC架構,請求會首先進入到controller中,在controller中進行相關邏輯的分發,調用model層,model是與數據進行交互的,在數據進行交互中,去拿數據庫的數據,最後將咱們渲染好的數據經過view層分發到網絡中,http請求的response就從服務端又回到了瀏覽器,瀏覽器就開始render。html
潛在的性能優化點:前端
問題二:一個網站在瀏覽器端是如何進行渲染的? 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註釋也能夠被壓縮。瀏覽器
實現方式 一、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,會直接替換
});
複製代碼
原理 無效代碼刪除、空格刪除、製表符刪除
實現方式 一、gulp中使用gulp-minify-css插件進行壓縮 二、在線的壓縮軟件進行壓縮(不適用與大的項目)
原理 無效字符的刪除、剔除註釋、代碼語義的縮減和優化、代碼保護(將一些具備語義化的名稱修改成a/b/c之類的)
實現方式 一、gulp中使用gulp-uglify插件進行壓縮 二、在線的壓縮軟件進行壓縮(不適用與大的項目)
圖片類型
解決方法
實現方法
存在的問題
解決方法
實現方法
使用gulp的gulp-concat插件進行文件合併。
懶加載
預加載
懶加載實現方法 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變慢,會致使頁面性能變差。
迴流 尺寸、佈局、隱藏等改變須要從新構建,就稱爲迴流。
觸發迴流的因素:
重繪 外觀、風格改變而不影響佈局須要重繪