延遲加載(懶加載)和預加載是常用的 web 優化的手段。。
一、延遲加載(懶加載)
原理: 當在真正需要數據的時候,才真正執行數據加載操作。
目的: 延遲加載機制是為了避免一些無謂的性能開銷而提出來的
實現延遲加載的幾種方法
1. 讓 js 最后加載
使用方法: 把 js 外部引入的文件放到頁面底部
用途: 讓 js 最后引入,從而加快頁面加載速度
說明:
流覽器之所以會采用同步模式,通常加載 js 文件或者放<script>標簽都在結構最后面,也是因為它會阻止瀏覽器后續操作的原因,所以放在后面,當頁面結構和樣式全部渲染完成再執行 js,提升用戶體驗
2. defer 屬性
使用方法: 為 <script>標簽定義了 defer屬性。
用途: 讓腳本在執行時不會影響頁面的構造。也就是說,腳本會被延遲到整個頁面都解析完畢之后再執行
1
2
3
4
5
6
7
8
9
10
|
<!DOCTYPE html> < html > < head > < script src = "test1.js" defer = "defer" ></ script > < script src = "test2.js" defer = "defer" ></ script > </ head > < body > <!-- 這里放內容 --> </ body > </ html > |
說明:
- 雖然<script>元素放在了<head>元素中,但包含的腳本將延遲瀏覽器遇到</html>標簽后再執行。
- 當瀏覽器解析到 script 腳本,有 defer 時,瀏覽器會并行下載有 defer 屬性的 script,而不會阻塞頁面后續處理。
- 所有的 defer 腳本保證是按順序依次執行的。(但實際上延遲腳本并不一定會按照順序執行,因此最好只包含一個延遲腳本)
- defer 屬性只適用于外部腳本文件。
3. async 屬性
使用方法: 為 <script>標簽定義了 async屬性。
用途: 不讓頁面等待腳本下載和執行,從而異步加載頁面其他內容。
1
2
3
4
5
6
7
8
9
10
|
<!DOCTYPE html> < html > < head > < script src = "test1.js" async></ script > < script src = "test2.js" async></ script > </ head > < body > <!-- 這里放內容 --> </ body > </ html > |
瀏覽器會立即下載腳本,但不妨礙頁面中的其他操作,比如下載其他資源或等待加載其他腳本。加載和渲染后續文檔元素的過程和 main.js 的加載與執行并行進行,這個過程是異步的。它們將在 onload 事件之前完成。
說明:
- 瀏覽器會立即下載腳本,但不妨礙頁面中的其他操作,加載和渲染后續文檔元素的過程和腳本的加載與執行并行進行。
- 這個過程是異步的,它們將在 onload 事件之前完成。
- 所有的 defer 腳本不能控制加載的順序。。
- asyncr 屬性只適用于外部腳本文件。
4. 動態創建 DOM 方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//這些代碼應被放置在</body>標簽前(接近HTML文件底部) <script type= "text/javascript" > function downloadJSAtOnload() { varelement = document.createElement( "script" ); element.src = "defer.js" ; document.body.appendChild(element); } if (window.addEventListener) window.addEventListener( "load" ,downloadJSAtOnload, false ); else if (window.attachEvent) window.attachEvent( "onload" ,downloadJSAtOnload); else window.onload =downloadJSAtOnload; </script> |
5. 使用 jquery 的 getScript 方法
使用方法:
1
|
Query.getScript(url,success(response,status)) |
- url(必寫):將要請求的 URL 字符串
- success(response,status)(可選):規定請求成功后執行的回調函數。
其中的參數
response - 包含來自請求的結果數據
status - 包含請求的狀態("success", "notmodified", "error", "timeout" 或 "parsererror")
用途: 通過 HTTP GET 請求載入并執行 JavaScript 文件。
1
2
3
4
5
6
|
//加載并執行 test.js: $.getScript( "test.js" ); //加載并執行 test.js ,成功后顯示信息 $.getScript( "test.js" , function (){ alert( "Script loaded and executed." ); }); |
6.使用 setTimeout 延遲方法的加載時間
用途: 延遲加載 js 代碼,給網頁加載留出時間
1
2
3
4
5
6
7
8
9
10
|
<script type= "text/javascript" > function A(){ $.post( "/lord/login" ,{name:username,pwd:password}, function (){ alert( "Hello World!" ); }) } $( function (){ setTimeout( "A()" ,1000); //延遲1秒 }) </script> |
常用實例 - 圖片懶加載
原理: 一張圖片就是一個<img>標簽,瀏覽器是否發起請求圖片是根據<img>的 src 屬性,所以實現懶加載的關鍵就是,在圖片沒有進入可視區域時,先不給<img>的 src 賦值,這樣瀏覽器就不會發送請求了,等到圖片進入可視區域再給 src 賦值。
1
2
|
< img class = "lazy" src = "img/loading.gif" lazy-src = "img/pic1.jpg" > < img class = "lazy" src = "img/loading.gif" lazy-src = "img/pic2.jpg" > |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
function lazyload(){ var visible; $( 'img' ).each( function () { if ( typeof ($( this ).attr( "lazy-src" ))!= "undefined" ){ // 判斷圖片是否需要懶加載 visible = $( this ).offset().top - $(window).scrollTop(); //圖片距離頂部的距離 if ((visible > 0) && (visible < $(window).height())) { // 判斷圖片是否在可視區域 visible = true ; // 圖片在可視區域 } else { visible = false ; // 圖片不在可視區域 } if (visible) { $( this ).attr( 'src' , $( this ).attr( 'lazy-src' )); } } }); } // 打開頁面觸發函數 lazyload(); // 滾屏時觸發函數 window.onscroll = function (){ lazyload(imgs); } |
二、 預加載
原理: 提前加載圖片,當用戶需要查看時可直接從本地緩存中渲染
目的: 犧牲前端性能,換取用戶體驗,使用戶的操作得到最快的反映。
實現預加載的幾種方法
1. css 實現
原理: 可通過 CSS 的background 屬性 將圖片預加載到屏幕外的背景上。只要這些圖片的路徑保持不變 ,當它們在 Web 頁面的其他地方被調用時,瀏覽器就會在渲染過程中使用預加載(緩存)的圖片。簡單、高效,不需要任何 JavaScript。
1
2
3
4
5
|
#preload -01 { background : url (http://domain.tld/image -01 .png) no-repeat -9999px -9999px ; } #preload -02 { background : url (http://domain.tld/image -02 .png) no-repeat -9999px -9999px ; } #preload -03 { background : url (http://domain.tld/image -03 .png) no-repeat -9999px -9999px ; } |
2. js 預加載圖片
原理: 通過寫函數進行預加載。將該腳本封裝入一個函數中,并使用 addLoadEvent(),延遲預加載時間,直到頁面加載完畢。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
function preloader() { if (document.images) { var img1 = new Image(); var img2 = new Image(); var img3 = new Image(); img1.src = "http://domain.tld/path/to/image-001.gif" ; img2.src = "http://domain.tld/path/to/image-002.gif" ; img3.src = "http://domain.tld/path/to/image-003.gif" ; } } function addLoadEvent(func) { var oldonload = window.onload; if ( typeof window.onload != 'function' ) { window.onload = func; } else { window.onload = function () { if (oldonload) { oldonload(); } func(); } } } addLoadEvent(preloader); |
3. 使用 ajax 實現預加載
原理: 使用 Ajax 實現圖片預加載的方法,利用 DOM,不僅僅預加載圖片,還會預加載 CSS、JavaScript 等相關的東西
1
2
3
4
5
6
7
8
9
10
11
12
13
|
window.onload = function () { setTimeout( function () { // XHR to request a JS and a CSS var xhr = new XMLHttpRequest(); xhr.open( 'GET' , 'http://domain.tld/preload.js' ); xhr.send( '' ); xhr = new XMLHttpRequest(); xhr.open( 'GET' , 'http://domain.tld/preload.css' ); xhr.send( '' ); // preload image new Image().src = "http://domain.tld/preload.png" ; }, 1000); }; |
上面代碼預加載了“preload.js”、“preload.css”和“preload.png”。1000 毫秒的超時是為了防止腳本掛起,而導致正常頁面出現功能問題。
三、 懶加載與預加載的對比
1、概念
延遲加載也叫懶加載: 當在真正需要數據的時候,才真正執行數據加載操作。
預加載:提前加載,當用戶需要查看時可直接從本地緩存中渲染
2、區別
- 兩種技術的本質:兩者的行為相反,一個是提前加載,一個是遲緩甚至不加載。
- 懶加載會對前端有一定的緩解壓力作用,預加載則會增加前端的壓力。
3、意義
懶加載的主要目的是優化前端性能,減少請求數或延遲請求數。
預加載是犧牲前端性能,換取用戶體驗,使用戶的操作得到最快的反映。
四、 參考資料
【1】http://www.jfrwli.cn/article/149051.html
【2】http://www.jfrwli.cn/article/125873.html
到此這篇關于js中延遲加載和預加載的具體使用的文章就介紹到這了,更多相關js中延遲加載和預加載內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://juejin.cn/post/6917440746303946765