首屏優化系列(一)


title: 首屏優化系列(一) date: 2018-6-23 13:53:30 tags:html

  • Promise
  • 圖片懶加載
  • 路由懶加載 categories: 前端

需求描述:優化首屏加載速度,減小白屏時間。前端

八一八本次項目中使用的優化手段,以及本身從中得到的知識。 因爲本次項目較爲複雜,模塊較多,(固然不比大型電商網站),首頁的請求就有8個,而且是精簡以後的,稍有不慎,白屏現象就會很嚴重。體驗極差。 ## 首頁模塊劃分 1. 分類 2. 輪播圖 3. 推薦 4. 收藏數 5. 購買數 6. 案例展現 7. 主內容展現 8. 合做機構展現

其中位於首屏的是一、二、三、四、5,對於6在大屏幕上也會展現。vue

優化手段

Skeleton Screen (骨架屏)

  簡單來講,骨架屏就是在頁面內容未加載完成的時候,先使用一些圖形進行佔位,待內容加載完成以後再把它替換掉。體驗的效果就是,在頁面徹底渲染完成以前,用戶會看到一個樣式簡單,描繪了當前頁面的大體框架,可以感知到頁面正在逐步加載,最終骨架屏中各個佔位部分被徹底替換。顯示效果以下: git

此處沒有單獨爲整個頁面寫一個組件,而是爲每一個模塊引入組件,如推薦課程這裏顯示5個課程,則在這部分數據的長度爲0時,顯示5個佔位背景,當此模塊數據請求完成,這部分就消失,顯示真實數據。這種手段只用在了課程首頁,由於只有這個頁面內請求較多。此外這種寫法也不易維護,很繁瑣。

路由懶加載

  把不一樣路由對應的組件分割爲不一樣的代碼塊,當路由被訪問的時候,再加載對應的組件,對中大型項目來講,會顯得很高效,對開發者而言,也方便維護。不過這裏要對生產環境和開發環境作區分,由於若是項目很大的話,每次更改代碼觸發的熱更新時間都會很長,因此只在生產環境中使用路由懶加載。github

// 生產環境 _import_production.js
module.exports = file => () => import('@/pages/' + file + '.vue');
// 開發環境 _import_development.js
module.exports = file => require('@/pages/' + file + '.vue').default; // vue-loader at least v13.0.0+
// router.js中引用
const _import = require('./_import_' + process.env.NODE_ENV);
{
    path: 'course',
    component: _import('course/index'),
    name: 'course'
}
複製代碼

圖片懶加載(vue-lazyload)

// 安裝
npm install vue-lazyload --save-dev
// 使用 main.js
import Vue from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload'

Vue.use(VueLazyload)
Vue.use(VueLazyload, {
    preLoad: 1.8,
    error: require('@/assets/lazy/error.png'),
    loading: require('@/assets/lazy/loading.png'),
    attempt: 1,
    listenEvents: ['scroll']
});

new Vue({
  el: 'body',
  components: {
    App
  }
});
// 在使用圖片的地方加上v-lazy便可
<img v-lazy="img.src" >
複製代碼

更多使用方式可參考vue-lazyload 這裏呈現的效果就是,請求完成數據,再去請求阿里雲存放的圖片,這個階段中,圖片資源加載過程當中,顯示loading的狀態,加載完畢,顯示圖片,若是圖片加載失敗,顯示失敗的圖片。npm

Promise

  回到咱們最初的問題,課程首頁的請求數爲8,請求都爲異步請求,而咱們的瀏覽器對同一域下的請求數量是有限制的,超過限制數目的請求會被阻塞,以谷歌瀏覽器的6個併發請求量爲例,課程首頁的數據請求和圖片請求加起來成百上千個,上面,咱們對圖片請求已經作了處理,使用懶加載的方式,另外,放在和數據請求不一樣的域下,咱們須要考慮的就是數據請求,目前爲8個,我作過這樣的測試,若是同時發出的話,每一個請求的時間大概是50ms,當每次單獨發送一個請求的時候,每一個請求的請求時間大約十幾毫秒,因此我當時的解決方案就是使用setTimeOut,進行延遲請求,這樣作的話,我須要單獨測試每一個請求的時間,而後爲他們寫延遲時間,這樣效率是很低的。此外,跟promise比,setTimeOut的執行優先級會下降,後來採用了promise的方式,以下:promise

return new Promise((resolve,reject) => {

})
複製代碼

採用這種方式的另外一個緣由是,若是全部異步請求同時觸發的話,瀏覽器會爲他們分配執行的優先級,而採用這種方式,請求的順序會按照咱們調用的順序執行。而瀏覽器分配的話,可能頁面底部的請求會先執行。在請求較少的狀況下,這種差別是體現的不明顯。瀏覽器

提到promise,我以爲最大的好處就是如它設計的初衷那樣,解決了層層回調的問題(難以維護,且不優雅)--鏈式調用,還有Promise.all()的用法,對於組合數據很方便。緩存

瀏覽器緩存(localStorage)

對於不頻繁修改的數據作了緩存,而且根據變換頻率,緩存時間不一樣。性能優化

if (cacheTime < 0) cacheTime = 3600000;
var result = { data: response.data, expiration: new Date().getTime() + cacheTime };
localStorage.setItem(cacheName, JSON.stringify(result));
複製代碼

詳細的緩存方法,已上傳至github:前往查看

PageSpeed Tools

  這個工具能夠在谷歌的插件商店中下載,很好用,能列出全部須要優化的點。 本地所提示的圖片問題,如使用瀏覽器緩存,須要在服務器設置etag和expire time 。   測試加載的時間能夠用

console.time('加載時間');
console.timeEnd('加載時間');
複製代碼

參考文章:

  1. 網站性能優化實戰——從12.67s到1.06s的故事
  2. Event Loop淺談
  3. JavaScript 工做原理之十一-渲染引擎及性能優化小技巧
  4. 基於Vue的SPA如何優化頁面加載速度
  5. 爲vue項目添加骨架屏
  6. 瀏覽器容許的併發請求資源數是有限制的-分析
  7. 變態的靜態資源緩存與更新 目前還只是個渣渣,以上只是個人我的理解,若有不足,還請指出,不勝感激。
相關文章
相關標籤/搜索