昨天的文章《經(jīng)典面試題-Web前端性能優(yōu)化方法(1)》中,我們講解了幾個Web前端性能優(yōu)化的措施,今天我們繼續(xù)來學(xué)習(xí)下其他性能優(yōu)化的方法。
延遲加載
一個頁面的展示如果每次都要等到所有內(nèi)容都加載完畢,頁面的加載速度勢必會受到很大影響,這個時候延遲加載的優(yōu)勢就體現(xiàn)出來了。
延遲加載是保證頁面初次加載時,所需要的最小內(nèi)容集,其他的內(nèi)容在需要的時候再進行加載,這可以保證頁面只需加載最少的資源,加快響應(yīng)速度。
JS延遲加載
Javascript文件延遲加載有幾種方法,這里我就簡單的表述幾種
讓js最后加載
在引入外部js文件時,我們將js文件放在<body>的結(jié)束標(biāo)簽之前,這樣可以讓js文件在最后引入,從而可以加快頁面加載速度。下面這張圖就是百度首頁的js文件,可以看到這些文件是放在頁面的底部的
讓js文件最后加載
使用setTimeout方法
使用setTimeout方法,動態(tài)的添加js腳本到head中
setTimeout方法
Google幫助頁面的推薦方案
將下面代碼添加至</body>標(biāo)簽之前,然后修改defer.js為項目中具體的js文件路徑。
Google幫助頁面推薦方案
需要注意的是這個外部引入的文件中不應(yīng)該包含頁面正常加載需要的js代碼,而應(yīng)該是一些在頁面加載后才執(zhí)行的js代碼,例如綁定的click,change事件。
使用lazyload.js插件
lazyload.js是一款jQuery插件,使用方法如下
lazyload.js插件
圖片延遲加載
現(xiàn)在很多的Web或者App應(yīng)用中的圖片都是進入可視區(qū)域時才去加載,這就用到了延遲加載的知識,圖片的延遲加載也有幾種方法,這里也總結(jié)一下。
使用lazyload.js插件
lazyload.js是一款jQuery插件,需要在lazyload.js之前引入jQuery文件,如下圖所示
lazyload延遲加載
原生Javascript代碼圖片滾動加載
使用Javascript代碼控制圖片在滾動到可視區(qū)域時才加載,代碼如下
Javascript實現(xiàn)圖片延遲加載
CSS文件延遲加載
CSS文件的延遲加載同樣有幾種方法,這里做下總結(jié)
使用lazyload.js插件
這里同js文件的延遲加載一樣,引入lazyload.js
lazyload延遲加載
使用setTimeout方法實現(xiàn)
我們同樣可以使用setTimeout方法去實現(xiàn)css的延遲加載
setTimeout實現(xiàn)css延遲加載
總結(jié)
今天這篇文章主要針對延遲加載來實現(xiàn)Web性能優(yōu)化的,后面會繼續(xù)更新Web性能優(yōu)化的文章。
您將了解到11個非常有用的單行代碼,它能幫助我們做很多事,不要小瞧了HTML哦!!!
HTML 和 CSS 是前端開發(fā)世界的支柱。雖然精通 CSS 和 JavaScript 對于創(chuàng)建出色的網(wǎng)站至關(guān)重要,但人們經(jīng)常低估您僅使用一個普通的舊 HTML 文件就可以完成的工作。從延遲加載圖像到為視頻添加字幕,HTML 能夠完成大多數(shù)開發(fā)人員并不完全了解的許多事情。以下是您可以立即使用的 11 個 HTML 單行代碼
向 HTML 元素添加簡單的工具提示不需要 CSS 或 JavaScript。 使用 title 屬性,您可以輕松添加工具提示以向用戶提供額外信息。
<body>
<p>
<abbr title="World Health Organization">WHO</abbr> was founded in 1948.
</p>
<p title="Free Web tutorials">W3Schools</p>
</body>
當(dāng)您希望用戶下載鏈接而不是導(dǎo)航到文件時,下載屬性非常有用。 此外,您還可以設(shè)置用戶將下載的文件的文件名
<a href="/images/myw3schoolsimage.jpg" download>
<a href="link/to/your/file" download="filename">Download link</a>
沒有人喜歡HTML在不該打斷的地方打斷文字。 使用<wbr>,您可以輕松地找到可以打斷單詞的點(機會)。 當(dāng)單詞太長,瀏覽器很有可能會在不正確的地方打斷它時,這很有用。
<p>This is a veryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryvery<wbr>longwordthatwillbreakatspecific<wbr>placeswhenthebrowserwindowisresized.</p>
使用DIR =“AUTO”,瀏覽器將根據(jù)內(nèi)容的語言更改文本對齊。當(dāng)您處理不遵循左邊的語言時,這非常有用。使用此屬性的潛在地點是社交媒體聊天應(yīng)用程序。
<p dir="auto">This text is following dir=auto</p>
通過使用細(xì)節(jié)和摘要語義元素,您可以創(chuàng)建一個非?;镜苋菀椎氖诛L(fēng)琴。將accordion元素與details元素打包,而標(biāo)題則使用summary元素。最后,使用p段落元素來編寫手風(fēng)琴的主要內(nèi)容。
<details>
<summary>Epcot Center</summary>
<p>Epcot is a theme park at Walt Disney World Resort featuring exciting attractions, international pavilions, award-winning fireworks and seasonal special events.</p>
</details>
通過將contentteditable屬性設(shè)置為true,可以使任何內(nèi)容都可編輯。 不管它是div還是p,它都是可編輯的。 此外,還可以使用isContentEditable屬性來查找某個元素是否可編輯。
<p contenteditable='true'>This is a paragraph. Click the button to make me editable.</p>
只需使用 HTML,您就可以使用 <track> 元素為視頻文件添加字幕。 使用 src 屬性指向字幕文件,使用 srclang 屬性設(shè)置語言。
<video width="320" height="240" controls>
<source src="forrest_gump.mp4" type="video/mp4">
<source src="forrest_gump.ogg" type="video/ogg">
<track src="fgsubtitles_en.vtt" kind="subtitles" srclang="en" label="English">
<track src="fgsubtitles_no.vtt" kind="subtitles" srclang="no" label="Norwegian">
</video>
你可以通過設(shè)置加載屬性為“l(fā)azy”來按需加載圖片(也叫惰性加載)。 這是一種簡單但非常有效的優(yōu)化技術(shù),只加載對用戶可見的部分,其他圖像稍后根據(jù)用戶的需要加載。
<img src="/w3images/wedding.jpg" alt="Wedding" style="width:100%">
<img src="/w3images/rocks.jpg" alt="Rocks" style="width:100%">
<!-- off-screen images -->
<img src="/w3images/paris.jpg" alt="Paris" style="width:100%" loading="lazy">
<img src="/w3images/nature.jpg" alt="Nature" style="width:100%" loading="lazy">
<img src="/w3images/underwater.jpg" alt="Underwater" style="width:100%" loading="lazy">
<img src="/w3images/ocean.jpg" alt="Ocean" style="width:100%" loading="lazy">
<img src="/w3images/mountainskies.jpg" alt="Mountains" style="width:100%" loading="lazy">
如果您在您的網(wǎng)站上多次調(diào)用一個公共域,您可以使用**<base>**元素來設(shè)置一個基本URL,如下面提供的代碼片段所示。 現(xiàn)在,src在圖像元素中的實際值是“www.w3schools.com/images/stic… 如果您使用過像Axios這樣的庫,那么設(shè)置基URL是一種非常常見的做法。
<head>
<base href="https://www.w3schools.com/" target="_blank">
</head>
<body>
<img src="images/stickman.gif" width="24" height="39" alt="Stickman">
<a href="tags/tag_base.asp">HTML base Tag</a>
</body>
您可以在使用右鍵單擊時收聽事件,也可以嘗試使用OnContextMenu和OnPaste屬性粘貼內(nèi)容并處理這些事件。如果您不希望用戶能夠粘貼到密碼等某些字段上,則可以在該輸入字段上寫入Onpaste =“返回false”,用戶將無法粘貼到那里。同樣,oncontextmenu在用戶右鍵單擊該元素時會觸發(fā)。
<input type="text" onpaste="return false" value="Paste something in here">
<div oncontextmenu="myFunction()" contextmenu="mymenu">
當(dāng)設(shè)置為 true 時,拼寫檢查屬性會告訴瀏覽器必須檢查用戶在此元素中輸入的語法和拼寫錯誤。 這是一個方便的屬性,可幫助用戶編寫正確無誤的內(nèi)容。
是我們的*Vue.js Performance系列中的第1部分。
雖然移動優(yōu)先方法成為標(biāo)準(zhǔn)且不確定的網(wǎng)絡(luò)條件是我們應(yīng)該始終考慮的事情,但是保持應(yīng)用程序快速加載變得越來越困難。在本系列中,我將深入研究我們在Vue Storefront中使用的Vue性能優(yōu)化技術(shù),并且您可以在Vue.js應(yīng)用程序中使用它們使它們立即加載并順利執(zhí)行。我的目標(biāo)是讓這個系列成為關(guān)于Vue應(yīng)用程序性能的完整而完整的指南。
Webpack bundling如何工作?
本系列中的大多數(shù)技巧都將集中在使我們的JS包。要了解它,首先我們需要了解Webpack如何捆綁所有文件。
捆綁我們的資源時,Webpack正在創(chuàng)建一個稱為依賴圖的東西(點擊這里查看它的樣子)。它是一個基于導(dǎo)入鏈接所有文件的圖表。假設(shè)我們main.js在webpack配置中有一個被指定為入口點的文件,它將成為我們依賴圖的根?,F(xiàn)在,我們將在此文件中導(dǎo)入的每個js模塊將成為圖中的節(jié)點,并且在這些節(jié)點中導(dǎo)入的每個模塊都將成為其節(jié)點。
Webpack使用此依賴關(guān)系圖來檢測它應(yīng)該包含在輸出包中的文件。輸出包只是一個(或我們將在后面的部分中看到的多個)javascript文件,其中包含依賴圖中的所有模塊。
該捆綁包本質(zhì)上是我們整個應(yīng)用程序的JavaScript。
我們可以用下圖來說明這個過程:
現(xiàn)在我們知道捆綁是如何工作的,很明顯我們的項目越大,初始JavaScript包就越大。
更大的捆綁包,下載和解析我們的用戶所需的時間越長。用戶必須等待的時間越長,他離開我們網(wǎng)站的可能性就越大。事實上,根據(jù)谷歌的數(shù)據(jù),53%的移動用戶留下的頁面加載時間超過3秒。
總而言之,更大的捆綁=更少的用戶,這可以直接轉(zhuǎn)化為潛在收入的損失。Bing就是一個很好的例子 - 延遲2秒導(dǎo)致每位訪客的收入損失4.3% 。
延遲加載
那么當(dāng)我們?nèi)匀恍枰砑有鹿δ懿⒏倪M我們的應(yīng)用程序時,我們?nèi)绾吻袛嗬壈笮??答案很簡?-? 延遲加載和代碼分割。
顧名思義,延遲加載是延遲加載應(yīng)用程序的部件(塊)的過程。換句話說,只有在我們真正需要的時候才加載它們。代碼分割就是將應(yīng)用程序分割成這些延遲加載的塊的過程。
在大多數(shù)情況下,當(dāng)用戶訪問您的網(wǎng)站時,您不需要立即使用Javascript包中的所有代碼。
例如,我們不需要花費寶貴的資源來為首次訪問我們網(wǎng)站的訪客加載“我的頁面”區(qū)域。或者可能存在每個頁面上不需要的模態(tài),工具提示和其他零件和組件。
當(dāng)只需要幾個部分時,在每個頁面加載時下載,解析和執(zhí)行整個包的所有內(nèi)容都是浪費。
延遲加載允許我們拆分捆綁包并僅提供所需的部分,這樣用戶就不會浪費時間下載和解析不會使用的代碼。
要查看我們網(wǎng)站中實際使用了多少JavaScript代碼,我們可以轉(zhuǎn)到devtools -> cmd + shift + p -> type coverage - >hit ‘record’.?,F(xiàn)在我們應(yīng)該能夠看到實際使用了多少下載的代碼。
標(biāo)記為紅色的所有內(nèi)容都是當(dāng)前路線上不需要的東西,可以延遲加載。如果您正在使用源映射,則可以單擊此列表中的任何文件,并查看未調(diào)用哪些部分。正如我們所看到的,甚至vuejs.org還有很大的改進空間。
通過延遲加載適當(dāng)?shù)慕M件和庫,我們設(shè)法將Vue Storefront的捆綁大小減少了60%!這可能是獲得性能提升的最簡單方法。
好的,我們知道延遲加載是什么,它非常有用?,F(xiàn)在是時候看看我們?nèi)绾卧谖覀冏约旱腣ue.js應(yīng)用程序中使用延遲加載。
動態(tài)導(dǎo)入
我們可以使用webpack動態(tài)導(dǎo)入輕松地加載我們應(yīng)用程序的某些部分。讓我們看看它們的工作原理以及它們與常規(guī)進口的區(qū)別。
如果我們以這樣的標(biāo)準(zhǔn)方式導(dǎo)入JavaScript模塊:
// cat.js const Cat = { meow: function () { console.log("Meowwwww!") } } export default Cat // main.js import Cat from './cat.js' Cat.meow()
它將作為main.js依賴關(guān)系圖中的a的節(jié)點添加并與其捆綁在一起。
但是,如果我們Cat僅在某些情況下需要我們的模塊,例如對用戶交互的響應(yīng),該怎么辦?將此模塊與我們的初始捆綁包捆綁在一起是一個壞主意,因為它始終不需要。我們需要一種方法告訴我們的應(yīng)用程序什么時候應(yīng)該下載這段代碼。
這是動態(tài)導(dǎo)入可以幫助我們的地方!現(xiàn)在看一下這個例子:
// main.js const getCat = () => import('./cat.js') // later in the code as a response to some user interaction like click or route change getCat() .then({ meow } => meow())
我們來看看這里發(fā)生的事情:
Cat我們創(chuàng)建了一個返回import()函數(shù)的函數(shù),而不是直接導(dǎo)入模塊。現(xiàn)在,webpack會將動態(tài)導(dǎo)入的模塊的內(nèi)容捆綁到一個單獨的文件中。表示動態(tài)導(dǎo)入模塊的函數(shù)返回一個Promise,它將使我們在解析時訪問模塊的導(dǎo)出成員。
然后,我們可以在需要時下載此可選塊。例如,作為對某個用戶交互的響應(yīng)(如路由更改或單擊)。
通過動態(tài)導(dǎo)入,我們基本上隔離了Cat將被添加到依賴圖中的給定節(jié)點(在這種情況下)并在我們決定需要時下載該部分(這意味著我們也切斷了導(dǎo)入的模塊Cat.js)。
讓我們看另一個更好地說明這種機制的例子。
假設(shè)我們有一個非常小的網(wǎng)上商店,有4個文件:
如果不深入研究細(xì)節(jié),讓我們看看這些文件是如何在整個應(yīng)用程序中分布的:
// category.js const category = { init () { ... } } export default category // product.js import gallery from ('./productGallery.js') const product = { init () { ... } } export default product // main.js const getProduct = () => import('./product.js') const getCategory = () => import('./category.js') if (route === "/product") { getProduct() .then({init} => init()) // run scripts for product page } if (route === "/category") { getCategory() .then({init} => init()) // run scripts for category page }
在上面的代碼中,根據(jù)當(dāng)前路由,我們動態(tài)導(dǎo)入其中的一個product或category模塊,然后運行init由它們兩者導(dǎo)出的函數(shù)。
知道動態(tài)導(dǎo)入是如何工作的我們知道product并且category最終會以單獨的捆綁包結(jié)束,但是productGallery未動態(tài)導(dǎo)入的模塊會發(fā)生什么?正如我們所知,通過使模塊動態(tài)導(dǎo)入,我們正在削減依賴圖的一部分。在此部件中導(dǎo)入的所有內(nèi)容都將捆綁在一起,因此productGallery最終將與product模塊捆綁在一起。
換句話說,我們只是為依賴圖創(chuàng)建某種新的入口點。
延遲加載Vue組件
現(xiàn)在我們知道延遲加載是什么以及為什么需要它。現(xiàn)在是時候看看我們?nèi)绾卧赩ue應(yīng)用程序中使用它了。
好消息是它非常簡單,我們可以懶得加載整個單一文件組件,它的CSS和HTML使用與以前相同的語法!
const lazyComponent = () => import('Component.vue')
......這就是你所需要的!現(xiàn)在只有在請求時才會下載組件。以下是調(diào)用Vue組件動態(tài)加載的最常用方法:
const lazyComponent = () => import('Component.vue') lazyComponent()
<template> <div> <lazy-component /> </div> </template> <script> const lazyComponent = () => import('Component.vue') export default { components: { lazyComponent } } // Another syntax export default { components: { lazyComponent: () => import('Component.vue') } } </script>
請注意,僅當(dāng)請求組件在模板中呈現(xiàn)時,才會調(diào)用lazyComponent函數(shù)。例如這段代碼:
<lazy-component v-if="false" />
在DOM中需要組件之前,組件將不會加載,只要v-if值更改為true即可。
總結(jié)和接下來會發(fā)生什么
延遲加載是使您的Web應(yīng)用程序更高效并減少捆綁包大小的最佳方法之一。我們學(xué)習(xí)了如何使用Vue組件進行延遲加載。
在本系列的下一部分中,我將向您展示在任何Vue.js應(yīng)用程序上獲得顯著性能提升的最有用(也是最快)的方法。
您將學(xué)習(xí)如何使用異步路由拆分Vue代碼以及此過程的建議最佳實踐。
翻譯自:https://vueschool.io/articles/vuejs-tutorials/lazy-loading-and-code-splitting-in-vue-js/?source=post_page---------------------------
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。