樹醬但願將前端的樂趣帶給你們 本文已收錄 github.com/littleTreem… 喜歡就star✨html
前沿:按需加載是性能優化其中的一個環節,能夠是圖片的按需加載,也就是lazyload來實現按需加載的場景,也能夠是組件庫的引入,只需部分組件的使用而無需全局引入整個組件庫的場景,又能夠是路由的按需加載,當路由被訪問的時候才加載對應組件的場景,以此來實現更高效率的使用等等,本文把「懶加載」也劃分爲按需加載前端
場景:當一個頁面存在須要多個圖片加載的場景時,能夠經過咱們常常看到的所謂「懶加載」,當滑動到圖片相應的位置時再加載圖片的信息,以此來實現按需加載,舉個最簡單的例子,你去逛淘寶的時候,電商網站圖片信息是不少的,這個時候若是把當前頁面下的圖片都將資源請求過來,是很消耗資源的,對網站的體驗也是極其很差,只須要加載你當前「視線」下的圖片便可,vue技術棧中
vue-lazyload
便可實現,下面聊聊它的使用和原理vue
本質上懶加載就是,在適當的時候加載用戶須要看的資源(可視區域),當頁面開發時將src路徑先預先設置好屬性,這樣頁面加載時圖片就不會立刻向服務器請求資源,而是當圖片滾動到可視區內時,再給src賦值並加載資源,而
vue-lazyload
就是基於這個概念實現的一個vue的工具庫,官方介紹:A Vue.js plugin for lazyload your Image or Component in your application。使用文檔點我👈webpack
npm i vue-lazyload
複製代碼
在main.js中經過vue實例加載插件git
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload);
複製代碼
頁面中的使用,經過給圖片定義v-lazy屬性,以下所示github
<ul>
<li v-for="img in list">
<img v-lazy="img.src" >
</li>
</ul>
複製代碼
經過幾個核心的點來介紹下vue-lazyload原理web
經過Lazy和LazyClass獲得了lazy這個對象,看看Lazy類的構造函數,源碼連接點我vue-cli
vue-lazyload是經過指令的方式來實現的,定義v-lazy指令,該指令對應的幾個回調函數:bind、update、componentUpdated和unbind分別綁定的是lazy對象的add、update、lazyLoadHandler和remove方法,以下所示npm
關於vue指令能夠看官方文檔進一步瞭解:官方文檔element-ui
指令被bind時會建立一個listener,並將其添加到listener queue裏面, 而且搜索target dom節點,爲其註冊dom事件
checkInView方法被封裝到_lazyloadHandler的方法,本質上是lazy構造器中使用的lazyloadHandler()函數,經過checkInView()函數檢測位置是否須要加載,若是須要返回true,並觸發load函數加載圖片
它還經過throttle節流函數來限制一個函數在必定時間內只能執行一次,由於像scroll這些事件觸發頻率高,不作限制的話,一秒以內可能執行幾十次
場景:當我須要使用某個組件庫的某個組件時,不想所有加載整個組件庫,這個時候就須要按需加載了,能夠解決一個首屏加載問題,下降首屏加載時間,舉個例子,我如今須要用到element-ui庫中的button組件,那我應該如何按需加載呢?
以element-ui爲例子,若是全局加載,會致使打包出來的包體積過大,影響交互體驗,以下所示就是一個webpack打包後的webpack-bundle-analyzer工具分析出來的report,你能夠經過 vue-cli中的命令生成report.html查看
"scripts": {
"build": "vue-cli-service build --report",
}
複製代碼
那怎麼去經過按需加載去使用組件庫,答案是經過babel插件:babel-plugin-component(element 經過fork ant-design庫的 )
在babel轉碼的時候,把整個庫element-ui的引用,變爲element-ui/lib/button具體模塊的引用。這樣webpack收集依賴module就不是整個element-ui,而是裏面的button
相似如何的轉換
如何安裝
npm install babel-plugin-component –D
複製代碼
使用以下所示👇
在main.js中使用以下
簡單理解就是把咱們的組件變成了一個函數,起初不執行它,只有你須要它的時候,也就是頁面加載時,才觸發它加載進來。
簡單而言則是路由懶加載,當咱們用webpack打包並構建應用時,輸出的bundle 包會變得很是大,影響頁面加載和體驗。若是能將不一樣路由對應的組件分割成不一樣的代碼塊,而後當路由被訪問的時候才加載對應組件,而不是一開始所有加載,這樣就更加高效了
能夠將異步組件定義爲返回一個 Promise (返回的 Promise 應該 resolve 組件自己)
咱們能夠使用動態 import語法來定義代碼分塊點 (split point)
咱們看看import一個組件返回的是什麼? promise!
那麼如何定義一個可以被 Webpack 自動代碼分割的異步組件呢?以下所示
若是你使用的是 Babel去支持import加載,則須要添加 syntax-dynamic-import
插件,才能使 Babel 能夠正確地解析語法,不然會報語法錯誤,以下所示
使用webpack的require.ensure來實現按需加載,不過目前已經被上一節提到的 import() 取代
往期文章