溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

網(wǎng)頁(yè)基本性能優(yōu)化規(guī)則有哪些

發(fā)布時(shí)間:2021-09-09 09:12:19 來(lái)源:億速云 閱讀:135 作者:小新 欄目:移動(dòng)開發(fā)

小編給大家分享一下網(wǎng)頁(yè)基本性能優(yōu)化規(guī)則有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

針對(duì)瀏覽器網(wǎng)頁(yè)的一些優(yōu)化規(guī)則

頁(yè)面優(yōu)化

靜態(tài)資源壓縮

借助構(gòu)建工具(webpack、gulp)適當(dāng)壓縮圖片、腳本及樣式等網(wǎng)頁(yè)靜態(tài)資源。

CSS雪碧圖、base64內(nèi)聯(lián)圖片

將站內(nèi)小圖標(biāo)合并成一張圖,使用css定位截取對(duì)應(yīng)圖標(biāo);適當(dāng)使用內(nèi)聯(lián)圖片。

樣式置頂、腳本置底

頁(yè)面是一個(gè)逐步呈現(xiàn)的過程,樣式置頂能更快呈現(xiàn)頁(yè)面給用戶;<script> 標(biāo)簽置頂會(huì)阻塞頁(yè)面后面資源的下載。

使用外鏈的css和js

多個(gè)頁(yè)面引用公共靜態(tài)資源,資源復(fù)用減少額外的http請(qǐng)求。

避免空src的圖片

避免不必要的http請(qǐng)求。

<!-- 空src的圖片依然會(huì)發(fā)起http請(qǐng)求 -->
<img src="" alt="image" />

避免在html中縮放圖片

圖片盡量按需求使用指定規(guī)格的尺寸,而不是加載一張大圖片再將它縮小。

<!-- 實(shí)際圖片尺寸為600x300,在html中縮放為了200x100 -->
<img src="/static/images/a.png" width="200" height="100" alt="image" />

Preload預(yù)加載

給link標(biāo)簽的rel設(shè)置preload屬性,可以讓瀏覽器在主渲染機(jī)制介入前就預(yù)加載資源。這種機(jī)制可以更早的獲取資源且不阻塞頁(yè)面的初始化。

<!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>

例子中預(yù)加載了css和js文件,在之后的頁(yè)面渲染中,一旦使用它們就會(huì)立即調(diào)用。

可指定as的類型加載不同類型的資源。

  1. style

  2. script

  3. video

  4. audio

  5. image

  6. font

  7. document

  8. ...

該方式也可跨域預(yù)加載資源,設(shè)置crossorigin屬性即可。

<link rel="preload" href="fonts/cicle_fina-webfont.woff2" as="font" type="font/woff2" crossorigin="anonymous">

CSS

選擇器

選擇器的優(yōu)先級(jí)從高到低排列為:

  1. ID選擇器

  2. 類選擇器

  3. 標(biāo)簽選擇器

  4. 相鄰選擇器

h2 + p{ margin-top: 15px; }

選擇緊接在h2元素后出現(xiàn)的段落,h2和p元素?fù)碛泄餐母冈亍?/p>

子選擇器

h2 > strong {color:red;}

后代選擇器

h2 em {color:red;}

通配符選擇器

屬性選擇器

*[title] {color:red;}
img[alt] {border: 5px solid red;}

偽類選擇器

選擇器使用經(jīng)驗(yàn):

  1. 優(yōu)先選擇類選擇器,可替代多層標(biāo)簽選擇器;

  2. 慎用ID選擇器,雖然它效率高,但是在頁(yè)面中是唯一的,不利于團(tuán)隊(duì)協(xié)作和維護(hù);

  3. 合理利用選擇器的繼承性;

  4. 避免css表達(dá)式。
     

減少選擇器的層級(jí)

建立在上一條選擇器的優(yōu)先級(jí)之上,應(yīng)盡量避免多層次的選擇器嵌套,最好不要超過3層。

.container .text .logo{ color: red; }

/*改成*/
.container .text-logo{ color: red; }

精簡(jiǎn)頁(yè)面樣式文件,去掉不用的樣式

瀏覽器會(huì)進(jìn)行多余的樣式匹配,影響渲染時(shí)間,另外樣式文件過大也會(huì)影響加載速度。

利用css繼承減少代碼量

利用css的可繼承屬性,父元素設(shè)置了樣式,子元素就不用再設(shè)置。

常見的可以繼承的屬性比如:color,font-size,font-family等;不可繼承的比如:position,display,float等。

屬性值為0時(shí),不加單位

css屬性值為0時(shí),可不加單位,減少代碼量。

.text{ width: 0px; height: 0px; }

/*改成*/
.text{ width: 0; height: 0; }

JavaScript

使用事件委托

給多個(gè)同類DOM元素綁定事件使用事件委托。

<ul id="container">
  <li class="list">1</li>
  <li class="list">2</li>
  <li class="list">3</li>
</ul>
// 不合理的方式:給每個(gè)元素都綁定click事件
$('#container .list').on('click', function() {
  var text = $(this).text();
  console.log(text);
});

// 事件委托方式:利用事件冒泡機(jī)制將事件統(tǒng)一委托給父元素
$('#container').on('click', '.list', function() {
  var text = $(this).text();
  console.log(text);    
});

需要注意的是,雖然使用事件委托時(shí)都可以將事件委托給document來(lái)做,但這是不合理的,一個(gè)是容易造成事件誤判,另一個(gè)是作用域鏈查找效率低。應(yīng)該選擇最近的父元素作為委托對(duì)象。

使用事件委托除了性能上更優(yōu),動(dòng)態(tài)創(chuàng)建的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()的簡(jiǎn)化版
$(function() {
  console.log("ready!");
});

預(yù)加載和懶加載

預(yù)加載

利用瀏覽器空閑時(shí)間預(yù)先加載將來(lái)可能會(huì)用到的資源,如圖片、樣式、腳本。

無(wú)條件預(yù)加載

一旦onload觸發(fā),立即獲取將來(lái)需要用到的資源。

圖片資源預(yù)加載。(3種實(shí)現(xiàn)圖片預(yù)加載的方式)。

基于用戶行為的預(yù)加載

對(duì)于用戶行為可能進(jìn)行的操作進(jìn)行判斷,預(yù)先加載將來(lái)可能需要用到的資源。

  1. 當(dāng)用戶在搜索輸入框輸入時(shí),預(yù)先加載搜索結(jié)果頁(yè)可能用到的資源;

  2. 當(dāng)用戶去操作一個(gè)Tab選項(xiàng)卡時(shí),默認(rèn)顯示其中一個(gè),當(dāng)要去點(diǎn)擊(click)其他選項(xiàng)時(shí),在鼠標(biāo)hover時(shí),就可先加載將來(lái)會(huì)用到的資源;

懶加載

除頁(yè)面初始化需要的內(nèi)容或組件之外,其他都可以延遲加載,如剪切圖片的js庫(kù)、不在可視范圍的圖片等等。

圖片懶加載。(判斷圖片是否在可視區(qū)域范圍內(nèi),若在,則將真實(shí)路徑賦給圖片)

避免全局查找

任何一個(gè)非局部變量在函數(shù)中被使用超過一次時(shí),都應(yīng)該將其存儲(chǔ)為局部變量。

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.";
}

在上面函數(shù)中多次使用到document全局變量,尤其在for循環(huán)中。因此將document全局變量存儲(chǔ)為局部變量再使用是更優(yōu)的方案。

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.";
}

值得注意的一點(diǎn)是,在javascript代碼中,任何沒有使用var聲明的變量都會(huì)變?yōu)槿肿兞?,不正?dāng)?shù)氖褂脮?huì)帶來(lái)性能問題。

避免不必要的屬性查詢

使用變量和數(shù)組要比訪問對(duì)象上的屬性更有效率,因?yàn)閷?duì)象必須在原型鏈中對(duì)擁有該名稱的屬性進(jìn)行搜索。

// 使用數(shù)組
var values = [5, 10];
var sum = values[0] + values[1];
alert(sum);

// 使用對(duì)象
var values = { first: 5, second: 10};
var sum = values.first + values.second;
alert(sum);

上面代碼中,使用對(duì)象屬性來(lái)計(jì)算。一次兩次的屬性查找不會(huì)造成性能問題,但若需要多次查找,如在循環(huán)中,就會(huì)影響性能。

在獲取單個(gè)值的多重屬性查找時(shí),如:

var query = window.location.href.substring(window.location.href.indexOf("?"));

應(yīng)該減少不必要的屬性查找,將window.location.href緩存為變量。

var url = window.location.href;
var query = url.substring(url.indexOf("?"));

函數(shù)節(jié)流

假設(shè)有一個(gè)搜索框,給搜索框綁定onkeyup事件,這樣每次鼠標(biāo)抬起都會(huì)發(fā)送請(qǐng)求。而使用節(jié)流函數(shù),能保證用戶在輸入時(shí)的指定時(shí)間內(nèi)的連續(xù)多次操作只觸發(fā)一次請(qǐng)求。

<input type="text" id="input" value="" />
// 綁定事件
document.getElementById('input').addEventListener('keyup', function() {
  throttle(search);
}, false);

// 邏輯函數(shù)
function search() {
  console.log('search...');
}

// 節(jié)流函數(shù)
function throttle(method, context) {
  clearTimeout(method.tId);
  method.tId = setTimeout(function() {
    method.call(context);
  }, 300);
}

節(jié)流函數(shù)的應(yīng)用場(chǎng)景不局限搜索框,比如頁(yè)面的滾動(dòng)onscroll,拉伸窗口onresize等都應(yīng)該使用節(jié)流函數(shù)提升性能。

最小化語(yǔ)句數(shù)

語(yǔ)句數(shù)量的多少也是影響操作執(zhí)行速度的因素。

將多個(gè)變量聲明合并為一個(gè)變量聲明

// 使用多個(gè)var聲明
var count = 5;
var color = "blue";
var values = [1,2,3];
var now = new Date();

// 改進(jìn)后
var count = 5,
  color = "blue",
  values = [1,2,3],
  now = new Date();

改進(jìn)的版本是只使用一個(gè)var聲明,由逗號(hào)隔開。當(dāng)變量很多時(shí),只使用一個(gè)var聲明要比單個(gè)var分別聲明快很多。

使用數(shù)組和對(duì)象字面量

使用數(shù)組和對(duì)象字面量的方式代替逐條語(yǔ)句賦值的方式。

var values = new Array();
values[0] = 123;
values[1] = 456;
values[2] = 789;

// 改進(jìn)后
var values = [123, 456, 789];
var person = new Object();
person.name = "Jack";
person.age = 28;
person.sayName = function(){
  alert(this.name);
};

// 改進(jìn)后
var person = {
  name : "Jack",
  age : 28,
  sayName : function(){
    alert(this.name);
  }
};

字符串優(yōu)化

字符串拼接

早期瀏覽器未對(duì)加號(hào)拼接字符串方式優(yōu)化。由于字符串是不可變的,就意味著要使用中間字符串來(lái)存儲(chǔ)結(jié)果,因此頻繁的創(chuàng)建和銷毀字符串是導(dǎo)致它效率低下的原因。

var text = "Hello";
text+= " ";
text+= "World!";

把字符串添加到數(shù)組中,再調(diào)用數(shù)組的join方法轉(zhuǎn)成字符串,就避免了使用加法運(yùn)算符。

var arr = [],
  i = 0;
arr[i++] = "Hello";
arr[i++] = " ";
arr[i++] = "World!";
var text = arr.join('');

現(xiàn)在的瀏覽器都對(duì)字符串加號(hào)拼接做了優(yōu)化,所以在大多數(shù)情況下,加法運(yùn)算符還是首選。

減少回流和重繪

在瀏覽器渲染過程中,涉及到回流和重繪,這是一個(gè)損耗性能的過程,應(yīng)注意在腳本操作時(shí)減少會(huì)觸發(fā)回流和重繪的動(dòng)作。

  1. 回流:元素的幾何屬性發(fā)生了變化,需要重新構(gòu)建渲染樹。渲染樹發(fā)生變化的過程,就叫回流;

  2. 重繪:元素的幾何尺寸沒有變化,某個(gè)元素的CSS樣式(背景色或顏色)發(fā)生了變化。

觸發(fā)重排或重繪的操作有哪些?

  1. 調(diào)整窗口大小

  2. 修改字體

  3. 增加或者移除樣式表

  4. 內(nèi)容變化,比如用戶在<input/>框中輸入文字

  5. 操作class屬性

  6. 腳本操作DOM(增加、刪除或修改DOM元素)

  7. 計(jì)算offsetWidth和offsetHeight屬性

  8. 設(shè)置style屬性的值

如何減少重排和重繪,提升網(wǎng)頁(yè)性能?

1、腳本操作DOM元素

  1. 將DOM元素設(shè)置為display:none,設(shè)置過程中會(huì)觸發(fā)一次回流,但之后可以隨意改動(dòng),修改完后再顯示;

  2. 將元素clone到內(nèi)存中再進(jìn)行操作,修改完后重新替換元素。

2、修改元素的樣式

  1. 盡量批量修改,而不是逐條修改;

  2. 預(yù)先設(shè)定好id、class,再設(shè)置元素的className。

3、為元素添加動(dòng)畫時(shí)將元素CSS樣式設(shè)為position:fixed或position:absolute,元素脫離文檔流后不會(huì)引起回流。

4、在調(diào)整窗口大小、輸入框輸入、頁(yè)面滾動(dòng)等場(chǎng)景時(shí)使用節(jié)流函數(shù)(上面已提到過)。

HTTP

瀏覽器緩存

合理設(shè)置瀏覽器緩存是網(wǎng)頁(yè)優(yōu)化的重要手段之一。

Expires 和 Cache-Control

Expires出自HTTP1.0,Cache-Control出自HTTP1.1,同時(shí)設(shè)置兩者時(shí),Cache-Control 會(huì)覆蓋 Expires。

  1. Expires指定的是實(shí)際過期日期而不是秒數(shù)。但Expires存在一些問題,如服務(wù)器時(shí)間不同步或不準(zhǔn)確。所以最好使用剩余秒數(shù)而不是絕對(duì)時(shí)間來(lái)表達(dá)過期時(shí)間。

  2. Cache-Control可設(shè)置max-age值,單位秒,指定緩存過期時(shí)間。如:Cache-Control: max-age=3600。

ETag 和 Last-Modified

ETag 和 Last-Modified都由服務(wù)器返回在response headers中,其中ETag的優(yōu)先級(jí)比Last-Modified高,也就是說(shuō)服務(wù)器會(huì)優(yōu)先判斷ETag的值。

  1. ETag是附加到文檔上的任意標(biāo)簽,可能是文檔的序列號(hào)或版本號(hào),或者是文檔內(nèi)容的校驗(yàn)等。當(dāng)文檔改變時(shí)ETag值也會(huì)隨之改變。與ETag相關(guān)的是 If-None-Match,當(dāng)瀏覽器發(fā)起請(qǐng)求時(shí),會(huì)在If-None-Match字段攜帶ETag的值發(fā)給服務(wù)器;

  2. Last-Modified是文檔在服務(wù)器端最后被修改的時(shí)間。與Last-Modified相關(guān)的是If-Modified-Since,當(dāng)瀏覽器發(fā)起請(qǐng)求時(shí),會(huì)在If-Modified-Since字段攜帶Last-Modified的值發(fā)送給服務(wù)器。

強(qiáng)緩存和協(xié)商緩存

緩存的類型強(qiáng)緩存和協(xié)商緩存。兩者區(qū)別是,強(qiáng)緩存不會(huì)向服務(wù)器發(fā)請(qǐng)求,而協(xié)商緩存會(huì)發(fā)請(qǐng)求,匹配成功返回304 Not Modified,匹配不成功返回200;瀏覽器會(huì)先校驗(yàn)強(qiáng)緩存,若強(qiáng)緩存未命中,再進(jìn)行協(xié)商緩存校驗(yàn)。

如何配置瀏覽器緩存

  1. 在web服務(wù)器的返回響應(yīng)中添加Expires和Cache-Control;

  2. 在nginx或apache的配置文件中配置Expires和Cache-Control。

為什么要減少HTTP請(qǐng)求

在性能優(yōu)化中減少http請(qǐng)求的措施占了很大部分,比如:使用css雪碧圖代替多張圖片的請(qǐng)求、避免空src的圖片、使用內(nèi)聯(lián)圖片、使用外鏈的css和js、緩存等。

從輸入U(xiǎn)RL到頁(yè)面加載完成的過程包括:

  1. DNS解析

  2. TCP連接

  3. HTTP請(qǐng)求與響應(yīng)

  4. 瀏覽器渲染頁(yè)面

  5. 關(guān)閉連接

一個(gè)完整的http請(qǐng)求要經(jīng)歷這些過程,它是耗時(shí)耗資源的,因此減少請(qǐng)求數(shù)就變得很有必要。

以上是“網(wǎng)頁(yè)基本性能優(yōu)化規(guī)則有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI