這次帶給大家前端網頁基本效能優化,的注意事項有哪些,以下就是實戰案例,一起來看一下。
頁面最佳化
靜態資源壓縮
#借助建置工具(webpack、gulp)適當壓縮圖片、腳本及樣式等網頁靜態資源。
CSS雪碧圖、base64內嵌圖片
將站內小圖示合併成一張圖,使用css定位截取對應圖示;適當使用內嵌圖片。
樣式置頂、腳本置底
頁面是逐步呈現的過程,樣式置頂能更快呈現頁面給使用者;<script> 標籤置頂會阻塞頁面後面資源的下載。 </script>
使用外鏈的css和js
多個頁面引用公共靜態資源,資源重複使用減少額外的http請求。
避免空src的圖片
避免不必要的http請求。
<!-- 空src的图片依然会发起http请求 --> <img src="/static/imghwm/default1.png" data-src="" class="lazy" alt="前端網頁基本效能優化" >
避免在html中縮放圖片
圖片盡量按需求使用指定規格的尺寸,而不是載入一張大圖片再將它縮小。
<!-- 实际图片尺寸为600x300,在html中缩放为了200x100 --> <img src="/static/imghwm/default1.png" data-src="/static/images/a.png" class="lazy" alt="前端網頁基本效能優化" >
Preload預先載入
給link標籤的rel設定preload屬性,可以讓瀏覽器在主渲染機制介入前就預先載入資源。這種機制可以更早的取得資源且不阻塞頁面的初始化。
nbsp;html> <meta> <title>Document</title> <link> <link> <link> <script></script>
例子中預先載入了css和js文件,在之後的頁面渲染中,一旦使用它們就會立即呼叫。
可指定as的型別載入不同類型的資源。
style
script
#video
audio
image
font
document
-
...
該方式也可跨網域預先載入資源,設定crossorigin屬性即可。
<link>
CSS
#選擇器
選擇器的優先權從高到低排列為:
ID選擇器
類別選擇器
-
標籤選擇器
相鄰選擇器
h1 + p{ margin-top: 15px; }
選擇緊接在h1元素後出現的段落,h1和p元素擁有共同的父元素。
子選擇器
h1 > strong {color:red;}
後代選擇器
h1 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元素绑定事件使用事件委托。
- 1
- 2
- 3
// 不合理的方式:给每个元素都绑定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 <p style="text-align: left;">在上面函数中多次使用到document全局变量,尤其在for循环中。因此将document全局变量存储为局部变量再使用是更优的方案。</p><pre class="brush:php;toolbar:false">function updateUI(){ var doc = document; var imgs = doc.getElementsByTagName("img"); for (var i=0, len=imgs.length; i <p style="text-align: left;">值得注意的一点是,在javascript代码中,任何没有使用var声明的变量都会变为全局变量,不正当的使用会带来性能问题。</p><p style="text-align: left;"><strong>避免不必要的属性查询</strong></p><p style="text-align: left;">使用变量和数组要比访问对象上的属性更有效率,因为对象必须在原型链中对拥有该名称的属性进行搜索。</p><pre class="brush:php;toolbar:false">// 使用数组 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>
// 绑定事件 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請求與回應
瀏覽器渲染頁面
#關閉連線
相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章!
推薦閱讀:
以上是前端網頁基本效能優化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

文章討論了CSS FlexBox,這是一種佈局方法,用於有效地對齊和分佈響應設計中的空間。它說明了FlexBox用法,將其與CSS網格進行了比較,並詳細瀏覽了瀏覽器支持。

本文討論了使用CSS創建響應網站的技術,包括視口元標籤,靈活的網格,流體媒體,媒體查詢和相對單元。它還涵蓋了使用CSS網格和Flexbox一起使用,並推薦CSS框架

本文討論了CSS盒裝屬性,該屬性控制了元素維度的計算方式。它解釋了諸如Content-Box,Border-Box和Padding-Box之類的值,以及它們對佈局設計和形式對齊的影響。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SublimeText3 Linux新版
SublimeText3 Linux最新版

Dreamweaver CS6
視覺化網頁開發工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具