欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Nuxt 項目性能優(yōu)化調(diào)研分析

 更新時間:2020年11月07日 10:10:08   作者:lessfish  
這篇文章主要介紹了Nuxt 項目性能優(yōu)化調(diào)研分析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

性能優(yōu)化,這是面試中經(jīng)常會聊到的話題。我覺得性能優(yōu)化應(yīng)該因具體場景而異,因不同項目而異,不同的手段不同的方案并不一定適合所有項目,當然這其中不乏一些普適的方案,比如耳熟能詳?shù)奈募嚎s,文件緩存,CDN,DNS 預(yù)解析,等等,但是我更希望聽到的是因為不同的項目不同的需求,解決不同的問題而采取的不同的優(yōu)化手段,比如 BigPipe,分段輸出頁面的各個部分,對于 SNS 網(wǎng)站是非常合適的,減少了用戶的等待時間;相對應(yīng)的還有一個 BigRender,這是一個大的延遲加載,360 導(dǎo)航首頁目前還在使用,京東淘寶首頁也是這個思路,對于一些類門戶網(wǎng)站非常適用,但是如果你的網(wǎng)頁內(nèi)容不是非常多,就沒有必要了

今天要說的是 Nuxt。Nuxt 是支持 Vue SSR 的一個框架,底層需要運行 Node 服務(wù)。大概描述一下 Vue 的渲染過程,首先每個組件都會被編譯生成一個渲染函數(shù)(這部分基本 webpack 打包已經(jīng)做掉),然后渲染函數(shù)生成虛擬 dom,最后虛擬 dom 通過 patch 方法將真實 dom 渲染到頁面上。Nuxt 其實就是將這部分放到了服務(wù)端去做,在服務(wù)端拿到渲染頁面所需要的 html,從而使得 html 能夠直出,而客戶端其實還是會運行整個 Vue 的生命周期,這就帶來了一個問題,這部分操作放在了服務(wù)端其實是非常耗 cpu 的,創(chuàng)建組件實例和虛擬 DOM 節(jié)點的開銷,無法與純基于字符串拼接的模版的性能相當,如果是不加優(yōu)化的 Nuxt 項目,高并發(fā)下是很脆弱的,畢竟 Node 運行在單線程下,不適合 cpu 操作密集型的場景

使用 Nuxt 的項目無非看中了它的兩大優(yōu)點,一是服務(wù)端渲染滿足 SEO 的需求,二是首屏直出比 SPA 快,再加上如果如果公司是 Vue 系,使用 Nuxt 就更順理成章。但是不要忘了性能,高并發(fā)下 Nuxt 性能確實不樂觀,我測試了官網(wǎng)的 hackernews demo 項目,2 核 cpu + 4g 內(nèi)存,400 并發(fā)下它的吞吐量不超過 50,就算是最簡的 Nuxt 項目,吞吐量也就 300+,這就說明如果項目不做緩存,300+ 已經(jīng)是最大的吞吐量了,而最小 express demo 可以輕松到 3000,這就決定了高流量項目并不會輕易去使用 Nuxt

我們的項目目前其實是一個不加優(yōu)化的 Nuxt 項目,因為用戶不多,平時并沒有什么問題,但是一到展會,就會有不少用戶同時訪問,反饋頁面會很卡。同條件下做了壓測后,吞吐量也是 50 上下,平均響應(yīng)時長七八秒,所以卡是正?,F(xiàn)象

看了一下項目代碼,發(fā)現(xiàn)了幾個問題:

項目沒做緩存,所以每次訪問都會經(jīng)歷所有 Nuxt 生命周期,消耗 cpu,這點是最致命的

項目打包默認 gzip。Nuxt 項目打包會默認在服務(wù)端開啟 gzip,因為我們網(wǎng)關(guān)層已經(jīng)做了 gzip,所以這里是不必要的,測試了下關(guān)掉 gzip 吞吐量和響應(yīng)時間都能提高 20% 左右。具體做法是在 nuxt.config.js 中配置(還是得看 英文文檔,會告訴你如何不設(shè)置 To disable compression, use compressor: false,中文文檔當時三月份我寫這文的時候還沒加這個選項,而目前中文文檔也沒有翻譯這一句 2020-07-16)

render: {
 compressor: false
}

API 請求比較亂。很多請求并沒有很好地區(qū)分客戶端和服務(wù)端,而是都由服務(wù)端去做了,造成服務(wù)端壓力過大,其實多數(shù)和用戶有關(guān)的請求理應(yīng)放到客戶端。有的接口為了方便,一次性返回了所有內(nèi)容,也沒有做客戶端/服務(wù)端區(qū)分。另外,服務(wù)端的接口請求可以并發(fā),用類似 Promise.all 的形式去控制

SEO。有的內(nèi)容頁面,很長,有五個部分,除了內(nèi)容外,還有猜你喜歡等其他部分,詢問了 SEO 同事,說這幾部分都是需要 SEO 的,我不是很懂 SEO,但是在我看來,ssr 只應(yīng)該渲染首屏內(nèi)容,而 UI 在設(shè)計的時候應(yīng)該把主要內(nèi)容設(shè)計到首屏,從而滿足 SEO

對此我覺得可以從兩個方向去優(yōu)化:

緩存。緩存是最重要的方案,針對 Nuxt 項目可以做三級緩存,頁面緩存、組件緩存以及 API 緩存。頁面緩存是最重量級的緩存方案,能不能做頁面緩存可以從以下兩個點判斷:

同一個 URL,對于 登錄 / 非登錄 用戶,服務(wù)端渲染的內(nèi)容是相同的(注意是服務(wù)端渲染內(nèi)容,而非前端)

同一個 URL,對于不同的登錄用戶,服務(wù)端渲染的內(nèi)容是相同的,即沒有一些個性化的渲染(常見的個性化渲染,比如針對不同用戶渲染不同的猜你喜歡內(nèi)容等)

其實也就是返回的 html 代碼相同就好,主要關(guān)注下返回的全局 store 是否一致,另外也不能做一些服務(wù)端才能做的操作,比如 set-cookie 等

控制好首屏模塊個數(shù),對返回的結(jié)果進行精簡,最小化,保證吐出到瀏覽器的內(nèi)容足夠小。這就是前面說的并不要對所有模塊都做 ssr,需要首屏呈現(xiàn)的/需要爬蟲爬的,我們直出,其他部分做 CSR 就行了

而我們的網(wǎng)站大部分頁面是滿足做頁面緩存條件的,測試了下如果做頁面緩存,吞吐量能到 500+,這個數(shù)據(jù)這個時候其實是和頁面大小有關(guān)系了,頁面緩存的性能是能滿足需求的。而有另一類頁面,相同的 URL 會返回不同的內(nèi)容,而且整頁都是不同內(nèi)容,它的實現(xiàn)是獲取 cookie 中的不同 city-id,渲染不同城市的內(nèi)容,很顯然這部分頁面做不了頁面緩存了,API 緩存和組件緩存理論上都是可以試試的

做緩存優(yōu)化,至少需要訪問一次,第二次才能生效,那么還有另一種情況,對于這樣的路由 /store/:id,并發(fā)打開 id 0~1000,很顯然每個頁面都是不一樣的店鋪數(shù)據(jù),并不能命中緩存(可能命中組件緩存,暫時忽略),這個時候只能從 Nuxt 生命周期上去優(yōu)化了,那么以上方向的第二點,控制首屏模塊個數(shù)就能用到了。所以本文一開始我就說,不同的方案是適配不同的場景的,解決不同的問題會采取不同的手段

補充知識:Nuxt實現(xiàn)的SSR頁面性能優(yōu)化的進一步探索與實踐

前言

本文之前,先簡單介紹以下幾個概念:

SSR指服務(wù)端渲染,即頁面是通過服務(wù)端渲染生成后返回給客戶端的,SSR主要為了提高頁面加載速度,改善用戶體驗,也可用于SEO搜索引擎優(yōu)化。

Nuxt.js 官方定義: Nuxt.js 是一個基于 Vue 的通用應(yīng)用框架。 通過對客戶端/服務(wù)端基礎(chǔ)架構(gòu)的抽象組織,Nuxt.js 主要關(guān)注的是應(yīng)用的 UI渲染。我們的目標是創(chuàng)建一個靈活的應(yīng)用框架,你可以基于它初始化新項目的基礎(chǔ)結(jié)構(gòu)代碼,或者在已有 Node.js 項目中使用 Nuxt.js。

個人理解:Nuxt.js 就是預(yù)設(shè)了開發(fā)服務(wù)端渲染應(yīng)用所需要的各種配置, 使用 Webpack 和 Node.js 進行封裝的基于Vue的SSR框架。

背景

我們部門從事的都是面對用戶的業(yè)務(wù)需求開發(fā),面對用戶,意味著對頁面的體驗要求會更高,最直觀體驗是頁面首屏的加載速度,加載速度優(yōu)化是我們體驗優(yōu)化的長期、重要的一部分;本文的起源正是首屏加載速度優(yōu)化。

頁面加載速度優(yōu)化的核心包括三點:減少資源文件的請求數(shù)量;減小每個資源文件的大小;提高每個資源的加載速度;

諸如合并API訪問,壓縮混淆文件,支持webp圖片,資源cdn緩存等等常用辦法,都是以上面三個核心為出發(fā)點的; 這些常用辦法基本都可以通過webpack配置,公司基礎(chǔ)服務(wù),代碼較小的變更完成。

我們負責的各主流量入口頁面,已基本做過以上常用的優(yōu)化,但由于主入口頁面資源量較大的原因,優(yōu)化后并不能達到預(yù)期的效果,我們需要探索其它優(yōu)化方案。 我們快速想到了用SSR的方案進一步解決加載速度問題,從零開始的搭建服務(wù)端渲染應(yīng)用相當復(fù)雜,肯定會涉及到服務(wù)端的開發(fā),作為獨立的前端團隊,成本較高昂; 我們決定嘗試是否能找到一種成本較低的現(xiàn)有SSR框架,以達到目的;

因主入口頁面技術(shù)棧為vue,方案調(diào)研中自然而然的看到了Nuxt.js此種基于Vue的SSR框架; Nuxt.js和項目技術(shù)棧匹配度急高,學習成本極低,自然成為我們的第一選擇;

我們引入Nuxt.js,最初只是利用了服務(wù)端異步獲取API接口數(shù)據(jù)和服務(wù)端渲染兩項功能,去重構(gòu)了我們的項目,重構(gòu)后效果基本達到我們的預(yù)期,正常網(wǎng)絡(luò)狀態(tài)下,基本可以達到秒開; 入口頁面,團隊是作為一個長期的項目進行不定期優(yōu)化的,我們逐步圍繞Nuxt.js框架,對項目做了進一步優(yōu)化升級,本文主要介紹我們Nuxt.js頁面優(yōu)化的進一步探索與實踐; 至于如何搭建初步的Nuxt項目,需要感興趣的各位自行查看官方文檔及自我實踐了,本文不做贅述。

探索與實踐

我們主要的探索與實踐可行方向主要有兩個:

一、Nuxt.js特性合理應(yīng)用

應(yīng)用到的特性主要包括asyncData異步獲取數(shù)據(jù)、mounted不支持服務(wù)端渲染、no-ssr組件不在服務(wù)端渲染中呈現(xiàn);

通過相關(guān)特性做到API數(shù)據(jù)和頁面結(jié)構(gòu)合理拆分,首屏所需數(shù)據(jù)和結(jié)構(gòu)通過服務(wù)端獲取并渲染,非首屏數(shù)據(jù)和結(jié)構(gòu)通過客戶端獲取并渲染。

示例代碼:

no-ssr結(jié)構(gòu)拆分

<template> 
 <div> 
 <!-- 頂部banner --> 
 <banner :banner="banner" /> 
 <!-- 非首屏所需結(jié)構(gòu),通過no-ssr組件達到不在服務(wù)端渲染目的--> 
 <no-ssr> 
  <!-- 商品列表 --> 
  <prod-list :listData="listData"/> 
 </no-ssr> 
 </div> 
</template>

API數(shù)據(jù)拆分

export default { 
 async asyncData({ app, query }) { 
 try { 
  // 獲取頁面頂部輪播圖信息 
  const getBanner = () => { 
  return app.$axios.$get('zz/zy/banner') 
  } 
  // 獲取底部配置信息 
  const getFooter = () => { 
  return app.$axios.$get('zz/zy/footer', { 
   params: { 
   smark: query.smark 
   } 
  }) 
  } 
  // 并發(fā)獲取首屏數(shù)據(jù),服務(wù)端獲取 
  const [banner, footer] = await Promise.all([getBanner(), getFooter()]) 
  return {banner: banner, footer: footer} 
 } catch (e) { 
  console.log('interface timeout or format error => ', e) 
  return {} 
 } 
 }, 
 mounted() { 
 // 非首屏使用的數(shù)據(jù), 客戶端獲取 
 this.loadListData() 
 }, 
 methods: { 
 loadListData() { 
  this.$axios.$get('zz/zy/list').then(() => { 
  // 數(shù)據(jù)處理邏輯 
  }) 
 } 
 } 
}

二、服務(wù)端引入緩存

服務(wù)端開發(fā)意味著緩存可作為性能優(yōu)化的最直接法門,Nuxt.js作為一種服務(wù)端渲染框架,也不例外;針對不同的頁面,不同的數(shù)據(jù)狀態(tài),可主要區(qū)分為下面三類緩存:

1、API接口數(shù)據(jù)緩存

將服務(wù)端獲取的數(shù)據(jù),全部緩存到node進程內(nèi)存中,定時刷新,有效期內(nèi)請求都通過緩存獲取API接口數(shù)據(jù),減小數(shù)據(jù)獲取時間;

此種緩存適用于緩存的部分API數(shù)據(jù),基本保持不變,變更不頻繁,與用戶個人數(shù)據(jù)無關(guān)。

示例代碼:

 import LRU from 'lru-cache' 
 const CACHED = new LRU({ 
 max: 100, // 緩存隊列長度 
 maxAge: 1000 * 60 // 緩存時間 
 }) 
 export default { 
 async asyncData({ app, query }) { 
  try { 
  let banner, footer 
  if (CACHED.has('baseData')) { 
   // 存在緩存,使用緩存數(shù)據(jù) 
   let data = CACHED.get('baseData') 
   data = JSON.parse(data) 
   banner = data.banner 
   footer = data.footer 
  } else { 
   // 獲取頁面頂部輪播圖信息 
   const getBanner = () => { 
   return app.$axios.$get('zz/zy/banner') 
   } 
   // 獲取底部配置信息 
   const getFooter = () => { 
   return app.$axios.$get('zz/zy/footer', { 
    params: { 
    smark: query.smark 
    } 
   }) 
   } 
   [banner, footer] = await Promise.all([getBanner(), getFooter()]) 
   // 將數(shù)據(jù)寫入緩存 
   CACHED.set('baseData', JSON.stringify({ banner: banner, footer: footer})) 
  } 
  return {mods: mods, footer: footer} 
  } catch (e) { 
  console.log('interface timeout or format error => ', e) 
  return {} 
  } 
 } 
 }

2、組件級別緩存

將渲染后的組件DOM結(jié)構(gòu)存入緩存,定時刷新,有效期通過緩存獲取組件DOM結(jié)構(gòu),減小生成DOM結(jié)構(gòu)所需時間;

適用于渲染后結(jié)構(gòu)不變或只有幾種變換、并不影響上下文的組件。

示例代碼:

nuxt.config.js配置項修改

const LRU = require('lru-cache') 
module.exports = { 
 render: { 
 bundleRenderer: { 
  cache: LRU({ 
  max: 1000, // 緩存隊列長度 
  maxAge: 1000 * 60 // 緩存1分鐘 
  }) 
 } 
 } 
}

需要做緩存的 vue 組件, 需增加 name 以及 serverCacheKey 字段,以確定緩存的唯一鍵值。

export default { 
 name: 'zzZyHome', 
 props: ['type'], 
 serverCacheKey: props => props.type 
}

如果組件依賴于很多的全局狀態(tài),或者狀態(tài)取值非常多,緩存會因頻繁被設(shè)置而導(dǎo)致溢出,這樣的組件做緩存就沒有多大意義了;

另外組件緩存,只是緩存了dom結(jié)構(gòu),如created等鉤子中的代碼邏輯并不會被緩存,如果其中邏輯會影響上下邊變更,是不會再執(zhí)行的,此種組件也不適合緩存。

3、頁面整體緩存

當整個頁面與用戶數(shù)據(jù)無關(guān),依賴的數(shù)據(jù)基本不變的情況下,可以對整個頁面做緩存,減小頁面獲取時間;

頁面整體緩存前提是在使用Nuxt.js腳手架工具create-nuxt-app初始化項目時,必須選擇集成服務(wù)器框架,如express、koa,只有這樣才具有服務(wù)端中間件擴展的功能。

示例代碼:

服務(wù)端中間件middleware/page-cache.js

const LRU = require('lru-cache') 
let cachePage = new LRU({ 
 max: 100, // 緩存隊列長度 
 maxAge: 1000 * 60 // 緩存1分鐘 
}) 
export default function(req, res, next){ 
 let url = req._parsedOriginalUrl 
 let pathname = url.pathname 
 // 通過路由判斷,只有首頁才進行緩存 
 if (['/home'].indexOf(pathname) > -1) { 
 const existsHtml = cachePage.get('homeData') 
 if (existsHtml) { 
  return res.end(existsHtml.html, 'utf-8') 
 } else { 
  res.original_end = res.end 
  // 重寫res.end 
  res.end = function (data) { 
  if (res.statusCode === 200) { 
   // 設(shè)置緩存 
   cachePage.set('homeData', { html: data}) 
  } 
  // 最終返回結(jié)果 
  res.original_end(data, 'utf-8') 
  } 
 } 
 } 
 next() 
}

nuxt.config.js配置項修改,引入服務(wù)端中間件

//針對home路由做緩存 
serverMiddleware: [ 
 { path: '/home', handler: '~/middleware/page-cache.js' }, 
]

總結(jié)

本文主要是針對Nuxt.js框架實現(xiàn)的頁面,性能優(yōu)化方案進一步探索和實踐的總結(jié),匯總一些思路與方向;期望各位小伙伴在其它SSR相關(guān)頁面優(yōu)化過程中,能起到一定的啟發(fā)作用。

以上這篇Nuxt 項目性能優(yōu)化調(diào)研分析就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue數(shù)據(jù)代理的實現(xiàn)流程逐步講解

    Vue數(shù)據(jù)代理的實現(xiàn)流程逐步講解

    通過一個對象代理對另一個對象中的屬性的操作(讀/寫),就是數(shù)據(jù)代理。要搞懂Vue數(shù)據(jù)代理這個概念,那我們就要從Object.defineProperty()入手,Object.defineProperty()是Vue中比較底層的一個方法,在數(shù)據(jù)劫持,數(shù)據(jù)代理以及計算屬性等地方都或多或少的用到了本函數(shù)
    2023-01-01
  • Vue cli 引入第三方JS和CSS的常用方法分享

    Vue cli 引入第三方JS和CSS的常用方法分享

    下面小編就為大家分享一篇Vue cli 引入第三方JS和CSS的常用方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • vue使用urlEncode問題

    vue使用urlEncode問題

    這篇文章主要介紹了vue使用urlEncode問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue腳手架vue-cli的卸載與安裝方式

    vue腳手架vue-cli的卸載與安裝方式

    pm是nodejs的包管理和分發(fā)工具,它可以讓javascript開發(fā)者能夠更加輕松的共享代碼和共用代碼片段,下面這篇文章主要給大家介紹了關(guān)于vue腳手架vue-cli卸載與安裝的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • vue2.x?el-table二次封裝實現(xiàn)編輯修改

    vue2.x?el-table二次封裝實現(xiàn)編輯修改

    本文主要介紹了vue2.x?el-table二次封裝實現(xiàn)編輯修改,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Vue中Mustache引擎插值語法使用詳解

    Vue中Mustache引擎插值語法使用詳解

    在Vue中通過Mustache模板引擎將data中的文本數(shù)據(jù)插入到HTML中,下面這篇文章主要給大家介紹了關(guān)于Vue中Mustache模板引擎插值語法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • vue中關(guān)于_ob_:observer的處理方式

    vue中關(guān)于_ob_:observer的處理方式

    這篇文章主要介紹了vue中關(guān)于_ob_:observer的處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • vue2.0 keep-alive最佳實踐

    vue2.0 keep-alive最佳實踐

    這篇文章主要為大家詳細介紹了vue2.0 keep-alive的最佳實踐,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 基于Vue制作組織架構(gòu)樹組件

    基于Vue制作組織架構(gòu)樹組件

    最近公司在做一個基于vue開發(fā)的項目,項目需要開發(fā)一個展示組織架構(gòu)的樹組件,在網(wǎng)上搜了半天,沒有找到合適的,下面小編給大家分享一個基于Vue制作組織架構(gòu)樹組件,需要的朋友參考下吧
    2017-12-12
  • 原生echart和vue-echart的使用詳解

    原生echart和vue-echart的使用詳解

    這篇文章主要為大家詳細介紹了原生echart和vue-echart的使用,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02

最新評論