您好,登錄后才能下訂單哦!
小編給大家分享一下網頁基本性能優化規則有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
針對瀏覽器網頁的一些優化規則
頁面優化
靜態資源壓縮
借助構建工具(webpack、gulp)適當壓縮圖片、腳本及樣式等網頁靜態資源。
CSS雪碧圖、base64內聯圖片
將站內小圖標合并成一張圖,使用css定位截取對應圖標;適當使用內聯圖片。
樣式置頂、腳本置底
頁面是一個逐步呈現的過程,樣式置頂能更快呈現頁面給用戶;<script> 標簽置頂會阻塞頁面后面資源的下載。
使用外鏈的css和js
多個頁面引用公共靜態資源,資源復用減少額外的http請求。
避免空src的圖片
避免不必要的http請求。
<!-- 空src的圖片依然會發起http請求 --> <img src="" alt="image" />
避免在html中縮放圖片
圖片盡量按需求使用指定規格的尺寸,而不是加載一張大圖片再將它縮小。
<!-- 實際圖片尺寸為600x300,在html中縮放為了200x100 --> <img src="/static/images/a.png" width="200" height="100" alt="image" />
Preload預加載
給link標簽的rel設置preload屬性,可以讓瀏覽器在主渲染機制介入前就預加載資源。這種機制可以更早的獲取資源且不阻塞頁面的初始化。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link ref="preload" href="style.css" as="style"> <link ref="preload" href="main.js" as="script"> <link ref="stylesheet" href="style.css"> </head> <body> <script src="main.js"></script> </body> </html>
例子中預加載了css和js文件,在之后的頁面渲染中,一旦使用它們就會立即調用。
可指定as的類型加載不同類型的資源。
style
script
video
audio
image
font
document
...
該方式也可跨域預加載資源,設置crossorigin屬性即可。
<link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">
CSS
選擇器
選擇器的優先級從高到低排列為:
ID選擇器
類選擇器
標簽選擇器
相鄰選擇器
h2 + p{ margin-top: 15px; }
選擇緊接在h2元素后出現的段落,h2和p元素擁有共同的父元素。
子選擇器
h2 > strong {color:red;}
后代選擇器
h2 em {color:red;}
通配符選擇器
屬性選擇器
*[title] {color:red;} img[alt] {border: 5px solid red;}
偽類選擇器
選擇器使用經驗:
優先選擇類選擇器,可替代多層標簽選擇器;
慎用ID選擇器,雖然它效率高,但是在頁面中是唯一的,不利于團隊協作和維護;
合理利用選擇器的繼承性;
避免css表達式。
減少選擇器的層級
建立在上一條選擇器的優先級之上,應盡量避免多層次的選擇器嵌套,最好不要超過3層。
.container .text .logo{ color: red; } /*改成*/ .container .text-logo{ color: red; }
精簡頁面樣式文件,去掉不用的樣式
瀏覽器會進行多余的樣式匹配,影響渲染時間,另外樣式文件過大也會影響加載速度。
利用css繼承減少代碼量
利用css的可繼承屬性,父元素設置了樣式,子元素就不用再設置。
常見的可以繼承的屬性比如:color,font-size,font-family等;不可繼承的比如:position,display,float等。
屬性值為0時,不加單位
css屬性值為0時,可不加單位,減少代碼量。
.text{ width: 0px; height: 0px; } /*改成*/ .text{ width: 0; height: 0; }
JavaScript
使用事件委托
給多個同類DOM元素綁定事件使用事件委托。
<ul id="container"> <li class="list">1</li> <li class="list">2</li> <li class="list">3</li> </ul>
// 不合理的方式:給每個元素都綁定click事件 $('#container .list').on('click', function() { var text = $(this).text(); console.log(text); }); // 事件委托方式:利用事件冒泡機制將事件統一委托給父元素 $('#container').on('click', '.list', function() { var text = $(this).text(); console.log(text); });
需要注意的是,雖然使用事件委托時都可以將事件委托給document來做,但這是不合理的,一個是容易造成事件誤判,另一個是作用域鏈查找效率低。應該選擇最近的父元素作為委托對象。
使用事件委托除了性能上更優,動態創建的DOM元素也不需要再綁定事件。
DOMContentLoaded
可在DOM元素加載完畢(DOMContentLoaded)后開始處理DOM樹,不必等到所有圖片資源下載完后再處理。
// 原生javascript document.addEventListener("DOMContentLoaded", function(event) { console.log("DOM fully loaded and parsed"); }, false); // jquery $(document).ready(function() { console.log("ready!"); }); // $(document).ready()的簡化版 $(function() { console.log("ready!"); });
預加載和懶加載
預加載
利用瀏覽器空閑時間預先加載將來可能會用到的資源,如圖片、樣式、腳本。
無條件預加載
一旦onload觸發,立即獲取將來需要用到的資源。
圖片資源預加載。(3種實現圖片預加載的方式)。
基于用戶行為的預加載
對于用戶行為可能進行的操作進行判斷,預先加載將來可能需要用到的資源。
當用戶在搜索輸入框輸入時,預先加載搜索結果頁可能用到的資源;
當用戶去操作一個Tab選項卡時,默認顯示其中一個,當要去點擊(click)其他選項時,在鼠標hover時,就可先加載將來會用到的資源;
懶加載
除頁面初始化需要的內容或組件之外,其他都可以延遲加載,如剪切圖片的js庫、不在可視范圍的圖片等等。
圖片懶加載。(判斷圖片是否在可視區域范圍內,若在,則將真實路徑賦給圖片)
避免全局查找
任何一個非局部變量在函數中被使用超過一次時,都應該將其存儲為局部變量。
function updateUI(){ var imgs = document.getElementsByTagName("img"); for (var i=0, len=imgs.length; i < len; i++){ imgs[i].title = document.title + " image " + i; } var msg = document.getElementById("msg"); msg.innerHTML = "Update complete."; }
在上面函數中多次使用到document全局變量,尤其在for循環中。因此將document全局變量存儲為局部變量再使用是更優的方案。
function updateUI(){ var doc = document; var imgs = doc.getElementsByTagName("img"); for (var i=0, len=imgs.length; i < len; i++){ imgs[i].title = doc.title + " image " + i; } var msg = doc.getElementById("msg"); msg.innerHTML = "Update complete."; }
值得注意的一點是,在javascript代碼中,任何沒有使用var聲明的變量都會變為全局變量,不正當的使用會帶來性能問題。
避免不必要的屬性查詢
使用變量和數組要比訪問對象上的屬性更有效率,因為對象必須在原型鏈中對擁有該名稱的屬性進行搜索。
// 使用數組 var values = [5, 10]; var sum = values[0] + values[1]; alert(sum); // 使用對象 var values = { first: 5, second: 10}; var sum = values.first + values.second; alert(sum);
上面代碼中,使用對象屬性來計算。一次兩次的屬性查找不會造成性能問題,但若需要多次查找,如在循環中,就會影響性能。
在獲取單個值的多重屬性查找時,如:
var query = window.location.href.substring(window.location.href.indexOf("?"));
應該減少不必要的屬性查找,將window.location.href緩存為變量。
var url = window.location.href; var query = url.substring(url.indexOf("?"));
函數節流
假設有一個搜索框,給搜索框綁定onkeyup事件,這樣每次鼠標抬起都會發送請求。而使用節流函數,能保證用戶在輸入時的指定時間內的連續多次操作只觸發一次請求。
<input type="text" id="input" value="" />
// 綁定事件 document.getElementById('input').addEventListener('keyup', function() { throttle(search); }, false); // 邏輯函數 function search() { console.log('search...'); } // 節流函數 function throttle(method, context) { clearTimeout(method.tId); method.tId = setTimeout(function() { method.call(context); }, 300); }
節流函數的應用場景不局限搜索框,比如頁面的滾動onscroll,拉伸窗口onresize等都應該使用節流函數提升性能。
最小化語句數
語句數量的多少也是影響操作執行速度的因素。
將多個變量聲明合并為一個變量聲明
// 使用多個var聲明 var count = 5; var color = "blue"; var values = [1,2,3]; var now = new Date(); // 改進后 var count = 5, color = "blue", values = [1,2,3], now = new Date();
改進的版本是只使用一個var聲明,由逗號隔開。當變量很多時,只使用一個var聲明要比單個var分別聲明快很多。
使用數組和對象字面量
使用數組和對象字面量的方式代替逐條語句賦值的方式。
var values = new Array(); values[0] = 123; values[1] = 456; values[2] = 789; // 改進后 var values = [123, 456, 789];
var person = new Object(); person.name = "Jack"; person.age = 28; person.sayName = function(){ alert(this.name); }; // 改進后 var person = { name : "Jack", age : 28, sayName : function(){ alert(this.name); } };
字符串優化
字符串拼接
早期瀏覽器未對加號拼接字符串方式優化。由于字符串是不可變的,就意味著要使用中間字符串來存儲結果,因此頻繁的創建和銷毀字符串是導致它效率低下的原因。
var text = "Hello"; text+= " "; text+= "World!";
把字符串添加到數組中,再調用數組的join方法轉成字符串,就避免了使用加法運算符。
var arr = [], i = 0; arr[i++] = "Hello"; arr[i++] = " "; arr[i++] = "World!"; var text = arr.join('');
現在的瀏覽器都對字符串加號拼接做了優化,所以在大多數情況下,加法運算符還是首選。
減少回流和重繪
在瀏覽器渲染過程中,涉及到回流和重繪,這是一個損耗性能的過程,應注意在腳本操作時減少會觸發回流和重繪的動作。
回流:元素的幾何屬性發生了變化,需要重新構建渲染樹。渲染樹發生變化的過程,就叫回流;
重繪:元素的幾何尺寸沒有變化,某個元素的CSS樣式(背景色或顏色)發生了變化。
觸發重排或重繪的操作有哪些?
調整窗口大小
修改字體
增加或者移除樣式表
內容變化,比如用戶在<input/>框中輸入文字
操作class屬性
腳本操作DOM(增加、刪除或修改DOM元素)
計算offsetWidth和offsetHeight屬性
設置style屬性的值
如何減少重排和重繪,提升網頁性能?
1、腳本操作DOM元素
將DOM元素設置為display:none,設置過程中會觸發一次回流,但之后可以隨意改動,修改完后再顯示;
將元素clone到內存中再進行操作,修改完后重新替換元素。
2、修改元素的樣式
盡量批量修改,而不是逐條修改;
預先設定好id、class,再設置元素的className。
3、為元素添加動畫時將元素CSS樣式設為position:fixed或position:absolute,元素脫離文檔流后不會引起回流。
4、在調整窗口大小、輸入框輸入、頁面滾動等場景時使用節流函數(上面已提到過)。
HTTP
瀏覽器緩存
合理設置瀏覽器緩存是網頁優化的重要手段之一。
Expires 和 Cache-Control
Expires出自HTTP1.0,Cache-Control出自HTTP1.1,同時設置兩者時,Cache-Control 會覆蓋 Expires。
Expires指定的是實際過期日期而不是秒數。但Expires存在一些問題,如服務器時間不同步或不準確。所以最好使用剩余秒數而不是絕對時間來表達過期時間。
Cache-Control可設置max-age值,單位秒,指定緩存過期時間。如:Cache-Control: max-age=3600。
ETag 和 Last-Modified
ETag 和 Last-Modified都由服務器返回在response headers中,其中ETag的優先級比Last-Modified高,也就是說服務器會優先判斷ETag的值。
ETag是附加到文檔上的任意標簽,可能是文檔的序列號或版本號,或者是文檔內容的校驗等。當文檔改變時ETag值也會隨之改變。與ETag相關的是 If-None-Match,當瀏覽器發起請求時,會在If-None-Match字段攜帶ETag的值發給服務器;
Last-Modified是文檔在服務器端最后被修改的時間。與Last-Modified相關的是If-Modified-Since,當瀏覽器發起請求時,會在If-Modified-Since字段攜帶Last-Modified的值發送給服務器。
強緩存和協商緩存
緩存的類型強緩存和協商緩存。兩者區別是,強緩存不會向服務器發請求,而協商緩存會發請求,匹配成功返回304 Not Modified,匹配不成功返回200;瀏覽器會先校驗強緩存,若強緩存未命中,再進行協商緩存校驗。
如何配置瀏覽器緩存
在web服務器的返回響應中添加Expires和Cache-Control;
在nginx或apache的配置文件中配置Expires和Cache-Control。
為什么要減少HTTP請求
在性能優化中減少http請求的措施占了很大部分,比如:使用css雪碧圖代替多張圖片的請求、避免空src的圖片、使用內聯圖片、使用外鏈的css和js、緩存等。
從輸入URL到頁面加載完成的過程包括:
DNS解析
TCP連接
HTTP請求與響應
瀏覽器渲染頁面
關閉連接
一個完整的http請求要經歷這些過程,它是耗時耗資源的,因此減少請求數就變得很有必要。
以上是“網頁基本性能優化規則有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。