1. 程式人生 > 實用技巧 >優化國際網站從一分鐘到4~6秒

優化國際網站從一分鐘到4~6秒

前言

  前幾天開會的時候,被老闆質問為何開啟網址等了8、9秒?當時我既然語塞,因為安卓和IOS開啟也很慢,但不會像PC網頁這麼慢到接近10秒才打開。而且更要命的是伺服器在新加坡,老闆就是在新加坡開啟這麼慢,我在國內開啟往往花了一分鐘以上,最慢的時候達到3分40秒,這速度是要命的!因為3秒定律,過了3秒使用者是沒有耐心直接關閉,如果是國外的網址願意多等一會,但也不可能願意等這麼久!

  於是乎這周除了修復幾個bug和新增了一些功能之外,我首要的任務就是優化網站載入!

  當然以下優化都是建立在網速正常的情況下。

優化vue專案

  第一步:增加頁面載入動畫

    國際網站給多個國家使用,因為再怎麼優化,首次進入都一定有幾秒的等待時間,這個時候加一個炫酷的動畫往往能使使用者分心,不會過於焦躁,而網站在第一次載入之後,後面更新了也不需要再等待那麼久,利用快取基本能秒更新。

    

    有興趣的夥伴可以到我的github下載:https://github.com/13632756286/Loading-

  第二步:vue-router 路由懶載入

    見名知意,路由懶載入既是元件的延遲載入,通常vue的頁面在執行後進入都會有一個預設的頁面,而其他頁面只有在點選後才需要加載出來。使用懶載入可以將頁面中的資源劃分為多份,從而減少第一次載入的時候耗時。

    相關程式碼:

       1. router/index.js

const Home = resolve => require(['@/views/Home/HomePage'], resolve);
const Login 
= resolve => require(['@/views/Login/LoginPage'], resolve); const Error = resolve => require(['@/components/Error/Error'], resolve); const PrintPage = resolve => require(['@/views/Print/printPage'], resolve); const PayNow = resolve => require(['@/views/Print/PayNow'], resolve); const HomePage = resolve => require(['@/components/Home/homePage'], resolve); const router
= new Router({ routes: [ { path: '/home', name: 'home', component:Home, children:[ { path: "",name: 'homePage',component: HomePage, props:true }, { path: "printPage",name: 'printPage',component: PrintPage, props:true }, { path: "payNow",name: 'payNow',component: PayNow, props:true } ], }, { path: '/login', name: 'login', component:Login, }, { path: '/register', component:Login, }, { path:'/*', component:Error } ] });

  

      2.父元件引入子元件時:

  components: {
    // 元件的按需懶載入
    navMenu: resolve => require(["@/components/Util/Menu/navMenu.vue"], resolve),
    TransactionsBox: resolve => require(["@/components/Home/transactions.vue"], resolve),
    topUp: resolve => require(["@/components/Home/topUp.vue"], resolve),
    DebitCard: resolve => require(["@/components/Home/debitCard.vue"], resolve),
    SettingsBox: resolve => require(["@/components/Home/settings.vue"], resolve),
    ProfileSelect: resolve => require(["@/components/Util/Select/profileSelect.vue"], resolve),
    headerBox: resolve => require(["@/components/Util/Head/header.vue"], resolve),
    AddCardDialog: resolve => require(['@/components/Util/CardBox/addCardDialog.vue'],resolve)
  }

      3. 關閉vuecli 3預設開啟的prefetch(預先載入模組)

        首屏載入的時候,預設會把分割的十幾個路由檔案全部下載,提前獲取使用者未來可能訪問的內容,在這裡建議關閉,可以在vue.config.js中設定:

module.exports = {
    chainWebpack: config => {
        // 移除 prefetch外掛
        config.plugins.delete('prefetch')
    }
}

        或者修改其選項:

module.exports = {
    config.plugin('prefetch').tap(options => {
        options[0].fileBlacklist = options[0].fileBlacklist || [];
        options[0].fileBlacelist.push(/myasyncRoute(.)+?\.js$/);
        return options;
    })
}

      當prefetch外掛被禁用時,你可以通過webpack的內聯註釋手動選定要提前獲取的程式碼:

import(/* webpackPrefetch: true */ './someAsyncComponent.vue');

      設定完畢之後,首屏就只會載入當前頁面的路由元件了。

  第三步:使用CDN減小程式碼體積加快請求速度

    CDN的好處:

      1.CDN採取的是就近原則下載,速度較快;

      2.減少打包體積,這也意味著請求該網址的下載速度會更快;

    相關程式碼

      1. public/index.html

  <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
  <link href="https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet">
  <script src="https://cdn.bootcss.com/element-ui/2.13.0/index.js"></script>
  <script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
  <script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
  <script src="https://cdn.bootcss.com/vue-i18n/8.17.0/vue-i18n.min.js"></script>
  <script src="https://cdn.bootcss.com/vuex/3.1.3/vuex.min.js"></script>

      2. 刪除main.js當中的相關程式碼,例:importElementUIfrom'element-ui';import'element-ui/lib/theme-chalk/index.css';Vue.use(ElementUI); 等等,如果這些程式碼沒有刪除,那麼打包的時候還是會自動在node_modules中引入下載,打包的體積還是會很大!

      3. vue.config.js中設定禁止引入上述的包進行打包(如果沒有vue.config.js就自己在根目錄建立)

configureWebpack: config => {
      return {
        externals: { //externals 裡的庫不會被webpack打包
          'echarts': 'echarts',
          'vue': 'Vue',
          'vue-router': 'VueRouter',
          'ElementUI': 'ELEMENT',
          'axios': 'axios',
          'vue-resource': 'VueResource',
          'vuex': 'Vuex',
          'vue-i18n': 'VueI18n',
          "qs": "qs",
          "jquery": "$"
        },
      }
    }
  }

  第四步:去掉編譯檔案中map檔案

    在編譯好後,我們會看到資料夾下有特別多的.map檔案,這些檔案主要是幫助我們線上除錯程式碼,檢視樣式。所以為了避免部署包過大,通常都不生成這些檔案。

    在config/index.js檔案中將productionSourceMap的值設定為false. 再次打包就可以看到專案檔案中已經沒有map檔案;

  第五步--重點:開啟gzip壓縮(壓縮率最高可達70%)

    1.cnpm i compression-webpack-plugin 下載compression-webpack-plugin外掛;

    2. vue.config.js中新增下面的程式碼:

configureWebpack: config => {
      return {
        plugins: [
          new CompressionPlugin({
            filename: '[path].gz[query]',
            algorithm: 'gzip',
            // test: /\.js$|\.html$|\.css/, //匹配檔名
            test: /\.(js|css|woff|ttf|json|txt|html|ico|svg)(\?.*)?$/i,
            threshold: 10240, //對超過10k的資料進行壓縮
            minRatio: 0.8, // 壓縮比小於這個才壓縮
            deleteOriginalAssets: false //是否刪除原始檔
          }),
        ],
        // plugins: plugins,
        externals: { //externals 裡的庫不會被webpack打包
          'echarts': 'echarts',
          'vue': 'Vue',
          'vue-router': 'VueRouter',
          'ElementUI': 'ELEMENT',
          'axios': 'axios',
          'vue-resource': 'VueResource',
          'vuex': 'Vuex',
          'vue-i18n': 'VueI18n',
          "qs": "qs",
          "jquery": "$"
        },
      }
    }

    注意:有些瀏覽器並不支援.gz檔案,因此deleteOriginalAssets:false,就會同時生成.js和.gz檔案,只要通過瀏覽器請求頭知道支援.gz檔案,那麼就自動使用.gz,否則使用.js。

    3. 要使伺服器返回.gz檔案,還需要對伺服器進行配置,根據RequestHeaders的Accept-Encoding標籤進行鑑別,如果支援gzip就返回.gz檔案,如果後端用SpringBoot ,還需要我們手動開啟,在配置檔案中新增兩行:

server:
  compression:
    enabled: true
    mime-types: application/json,application/xml,text/html,text/plain,text/css,application/x-javascript

  如果後端用的不是SpringBoot,那麼可以參考這篇文章來進行配置:https://blog.csdn.net/qq_40999917/article/details/107936750