日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ajax div 赋值重新渲染_优化向:单页应用多路由预渲染指南

發布時間:2023/12/2 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ajax div 赋值重新渲染_优化向:单页应用多路由预渲染指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

Ajax 技術的出現,讓我們的 Web 應用能夠在不刷新的狀態下顯示不同頁面的內容,這就是單頁應用。在一個單頁應用中,往往只有一個 html 文件,然后根據訪問的 url 來匹配對應的路由腳本,動態地渲染頁面內容。單頁應用在優化了用戶體驗的同時,也給我們帶來了許多問題,例如 SEO 不友好、首屏可見時間過長等。服務端渲染(SSR)和預渲染(Prerender)技術正是為解決這些問題而生的。

閱讀本文,你能夠了解到什么是預渲染、預渲染與服務端渲染的異同以及預渲染在?Vue.js 項目中的使用。

服務端渲染與預渲染

一些概念

  • 客戶端渲染:用戶訪問 url,請求 html 文件,前端根據路由動態渲染頁面內容。關鍵鏈路較長,有一定的白屏時間;

  • 服務端渲染:用戶訪問 url,服務端根據訪問路徑請求所需數據,拼接成 html 字符串,返回給前端。前端接收到 html 時已有部分內容;

  • 預渲染:構建階段生成匹配預渲染路徑的 html 文件(注意:每個需要預渲染的路由都有一個對應的 html)。構建出來的 html 文件已有部分內容。

  • 下圖簡單展示了客戶端渲染、服務端渲染和預渲染的請求流程。

    本文示例使用 vue-cli 生成,點擊這里查看示例。dist?目錄是啟用了預渲染的打包目錄,dist2?目錄則是普通客戶端渲染的打包目錄。通過對比目錄中的文件,你可以對預渲染有個初步的了解。若你還是不知道什么是預渲染,不妨先通讀全文。

    共同點

    針對單頁應用,服務端渲染和預渲染共同解決的問題:

  • SEO:單頁應用的網站內容是根據當前路徑動態渲染的,html 文件中往往沒有內容,網絡爬蟲不會等到頁面腳本執行完再抓取;

  • 弱網環境:當用戶在一個弱環境中訪問你的站點時,你會想要盡可能快的將內容呈現給他們。甚至是在 js 腳本被加載和解析前;

  • 低版本瀏覽器:用戶的瀏覽器可能不支持你使用的 js 特性,預渲染或服務端渲染能夠讓用戶至少能夠看到首屏的內容,而不是一個空白的網頁。

  • 預渲染能與服務端渲染一樣提高 SEO 優化,但前者比后者需要更少的配置,實現成本低。弱網環境下,預渲染能更快地呈現頁面內容,減少頁面可見時間。

    不適合的場景

    那什么場景下不適合使用預渲染呢:

  • 個性化內容:對于路由是 /my-profile 的頁面來說,預渲染就失效了。因為頁面內容依據看它的人而顯得不同;

  • 經常變化的內容:如果你預渲染一個游戲排行榜,這個排行榜會隨著新的玩家記錄而更新,預渲染會讓你的頁面顯示不正確直到腳本加載完成并替換成新的數據。這是一個不好的用戶體驗;

  • 成千上萬的路由:不建議預渲染非常多的路由,因為這會嚴重拖慢你的構建進程。

  • Prerender SPA Plugin

    prerender-spa-plugin 是一個 webpack 插件用于在單頁應用中預渲染靜態 html 內容。因此,該插件限定了你的單頁應用必須使用 webpack 構建,且它是框架無關的,無論你是使用 React 或 Vue 甚至不使用框架,都能用來進行預渲染。本文示例基于 Vue.js 2.0 + vue-router。

    下文會從生成項目講起,然后看下沒有配置預渲染前的樣子,再配置預渲染進行構建,對比前后的差別。

    生成項目

    首先生成一個項目并安裝依賴。

    vue init webpack vue-prerender-demo
    cd vue-prerender-demo && npm install復制代碼

    組件開發過程我們不關注,具體可以查看示例源代碼。開發完成視圖如下。

    路由配置

    這是一個新聞應用的頁面,包括了最新、最熱兩個列表頁和一個文章頁。路由配置如下。

    new Router({
    mode: 'history',
    routes: [
    {
    path: '/',
    component: Home,
    children: [
    {
    path: 'new',
    alias: '/',
    component: () => import('@/components/New')
    },
    {
    path: 'hot',
    component: () => import('@/components/Hot')
    }
    ]
    },
    {
    path: '/article/:id',
    component: Article
    }
    ]
    })復制代碼

    預渲染的單頁應用路由需要使用 History 模式而不是 Hash 模式。原因很簡單,Hash 不會帶到服務器,路由信息會丟失。vue-router 啟用 History 模式參考這里。

    History 模式需要后臺配置支持,最簡單的是通過 nginx 配置 try_files 指令。

    location / {
    try_files $uri $uri/ /index.html;
    }復制代碼

    沒有配置預渲染前

    配置完成后執行構建?npm run build,根據 nginx 配置,現在無論訪問哪個路由都會返回 dist/index.html。

    訪問 / 路由。

    可以看到,在 Fast 3G 網絡下,首屏可見時間是 4.34s,頁面至少在加載下面文件后才能被看到。

  • html

  • app.css?- 樣式

  • manifest.js?- webpack manifest

  • vendor.js?- 第三方庫

  • app.js?- 業務邏輯

  • 0.js?- 路由分包文件

  • 其中 vendor 文件包含了引用的第三方庫,文件規模較大。加載文件多,增加了白屏時間。所以,最有效的優化方案是減少首屏依賴文件。這里開始配置預渲染。

    預渲染配置

    安裝 prerender-spa-plugin,安裝時件略長,因為其依賴了 phantomjs,請耐心等待。

    npm install prerender-spa-plugin --save-dev復制代碼

    我們只在生產環境中進行預渲染,修改 build/webpack.prod.conf.js,在配置插件的地方加入如下代碼。

    var path = require('path')
    var PrerenderSpaPlugin = require('prerender-spa-plugin')

    {
    // ...
    plugins: [
    // ...
    new PrerenderSpaPlugin(
    // 輸出目錄的絕對路徑
    path.join(__dirname, '../dist'),
    // 預渲染的路由
    [ '/new', '/hot' ]
    )
    ]
    }復制代碼

    實例化 PrerenderSpaPlugin 需要至少兩個參數,第一個參數是單頁應用的輸出目錄,第二個參數指定預渲染的路由,這里執行了兩個路由?/new?和?/hot。執行構建?npm run build。

    預渲染效果

    訪問?/new?路由。

    同樣在 Fast 3G 網絡下,首屏可見時間縮短至 2.30s。事實上,只要加載 html 和 app.css 文件,頁面內容就能看到了。

    dist
    │ index.html

    ├─hot
    │ index.html

    ├─new
    │ index.html

    └─static復制代碼

    對比構建完成目錄,可以發現預渲染的目錄多了兩個文件?new/index.html,?hot/index.html。

    查看?new/index.html

    <html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>vue-prerender-demotitle><link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"><link href="/static/css/app.23611ac69a9fa48640e3bad8ceeab7bf.css" rel="stylesheet"><script type="text/javascript" charset="utf-8" async="" src="/static/js/0.41194d76e86bbf547b16.js">script>head><body><div id="app"><div><div class="mu-appbar mu-paper-1"><div class="left"><i class="mu-icon material-icons">homei>div><div class="mu-appbar-title"><span>新聞span>div><div class="right">div>div>
    ...div>div><script type="text/javascript" src="/static/js/manifest.4410c20c250c68dac5bc.js">script><script type="text/javascript" src="/static/js/vendor.d55f477df6e96ccceb5c.js">script><script type="text/javascript" src="/static/js/app.f199467bd568ee8a197a.js">script>body>html>復制代碼

    相比 index.html, new/index.html 中的??是有內容的,且??中多了當前路由分包的 js 文件。其余部分跟 index.html 一樣。雖然有多個 html,但從 /new 跳轉到其他路由時,還是單頁內跳轉的,不會有新的 html 請求。

    根據上面配置的 nginx 規則,路由對應的返回文件分別是:

    / -> index.html
    /new -> new/index.html
    /hot -> hot/index.html
    /article/:id -> index.html復制代碼

    其中,/new?和?/hot?路由返回的 html 包含了對應路由的內容,從而實現預渲染。沒有配置預渲染的路由跟原來一樣,還是訪問 /index.html,請求腳本,動態渲染。

    預渲染達到了類似服務端渲染的效果。區別在于預渲染發生在構建時,服務端渲染發生在服務器處理請求時。

    prerender-spa-plugin 原理

    那么 prerender-spa-plugin 是如何做到將運行時的 html 打包到文件中的呢?原理很簡單,就是在 webpack 構建階段的最后,在本地啟動一個 phantomjs,訪問配置了預渲染的路由,再將 phantomjs 中渲染的頁面輸出到 html 文件中,并建立路由對應的目錄。

    查看 prerender-spa-plugin 源碼 prerender-spa-plugin/lib/phantom-page-render.js。

    // 打開頁面
    page.open(url, function (status) {
    ...
    // 沒有設置捕獲鉤子時,在腳本執行完捕獲
    if (
    !options.captureAfterDocumentEvent &&
    !options.captureAfterElementExists &&
    !options.captureAfterTime
    ) {
    // 拼接 html
    var html = page.evaluate(function () {
    var doctype = new window.XMLSerializer().serializeToString(document.doctype)
    var outerHTML = document.documentElement.outerHTML
    return doctype + outerHTML
    })
    returnResult(html) // 捕獲輸出
    }
    ...
    })復制代碼

    最佳實踐

    指定捕獲鉤子

    默認情況下 html 會在腳本執行完被捕獲并輸出。你也可以指定一些鉤子,html 將會在特定時機被捕獲。

    var path = require('path')
    var PrerenderSpaPlugin = require('prerender-spa-plugin')

    {
    // ...
    plugins: [
    // ...
    new PrerenderSpaPlugin(
    path.join(__dirname, '../dist'),
    [ '/new', '/hot' ],
    {
    // 監聽到自定事件時捕獲
    // document.dispatchEvent(new Event('custom-post-render-event'))
    captureAfterDocumentEvent: 'custom-post-render-event',

    // 查詢到指定元素時捕獲
    captureAfterElementExists: '#content',

    // 定時捕獲
    captureAfterTime: 5000
    }
    )
    ]
    }復制代碼

    預渲染骨架屏

    本文實例中更多是變化的數據,時效性要求比較高,不太適合預渲染的場景。如果想用預渲染來減少白屏時間,讓頁面反饋更及時的話,可以預渲染骨架屏。

    <template>
    <div>
    <new-list v-if="news.length > 0">new-list>
    <new-list-skeleton>new-list-skeleton>
    div>
    template>復制代碼

    請求 news 數據需要一定時間,所以插件在腳本執行完捕獲的一般就是骨架屏。如果你想更靈活地指定捕獲時機,可以使用自定義事件鉤子,在組件掛載且請求數據前捕獲。

    {
    mounted () {
    document.dispatchEvent(new Event('sketelon-render-event'))
    fetchNews()
    }
    }復制代碼

    訪問頁面時,用戶首先看到預渲染的骨架屏(左圖),等待 js 加載完成后,再拉取數據渲染出正確的內容。

    代理完整路徑

    如果你配置了引用資源鏈接為帶域名的完整路徑。

    // config/index.js

    module.exports = {
    build: {
    ...
    assetsPublicPath: '//www.example.com/'
    },
    ...
    }復制代碼

    那么構建時需要將域名代理到本地,否則 prerender-spa-plugin 捕獲的將會是線上的代碼。

    127.0.0.1 www.example.com復制代碼

    預渲染根路由

    通常情況下,動態路由如 /users/:id 不會配置預渲染,因為你沒法枚舉出所有的 User ID。訪問動態路由時,服務器會返回根路由 / 的 html,所以根路由也不適合做預渲染。但根路由往往是一個網站的首頁,是訪問量最大的一個路由。通過一些 nginx 可以解決這個問題。

    location = / {
    try_files /home/index.html /index.html;
    }

    location / {
    try_files $uri $uri/ /index.html;
    }復制代碼

    用戶訪問 / 路由,實際上是訪問了 /home/index.html,用 router 中配置的 /home 作為首頁。/index.html 可以作為其他沒有匹配到路由的響應。

    結語

    預渲染是實現成本較低,效果提升明顯的性能優化方案。預渲染有它適合的場景,當你的頁面內容變化不大,又想讓它更快地呈現給用戶時,試試預渲染吧。

    ?? 看完兩件事

    如果你覺得這篇內容對你挺有啟發,我想邀請你幫我兩個小忙:

  • 點個「在看」,讓更多的人也能看到這篇內容(喜歡不點在看,都是耍流氓 -_-)

  • 關注公眾號「Vue社區」,每周重點攻克一個前端面試重難點,

    公眾號后臺回復「電子書」即可免費獲取 27本 精選的前端電子書!

    回復「100」免費獲取 100本 最棒的前端電子書!

  • 總結

    以上是生活随笔為你收集整理的ajax div 赋值重新渲染_优化向:单页应用多路由预渲染指南的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 日韩精品一区二区三区四区 | 欧日韩在线 | 中文字幕亚洲乱码熟女一区二区 | 国产剧情在线观看 | 怨女1988国语版在线观看高清 | 国产一线二线三线在线观看 | 殴美一级黄色片 | 中国美女囗交视频 | 国产又大又粗又爽的毛片 | www.色午夜.com| 伊人天堂在线 | 欧美人喂奶吃大乳 | 日本黄色不卡视频 | 久久久久久久久久久综合 | 激情文学综合网 | 貂蝉被到爽流白浆在线观看 | 婷婷影院在线观看 | 亚洲最大黄色网址 | 久久久久九九九 | 在线免费观看亚洲视频 | 激情综合五月婷婷 | 国产极品久久久 | 免费亚洲婷婷 | 樱花影院最新免费观看攻略 | 国产精品久久久久久亚洲色 | 欧美 变态 另类 人妖 | 国产视频91在线 | 91中文字幕在线视频 | 国产网站免费在线观看 | 国产成人免费在线观看 | 色婷婷av一区二区三区之红樱桃 | 伊人久久久久久久久久久久 | аⅴ天堂中文在线网 | 涩涩视频网址 | 日韩特黄 | 久久一视频 | 深夜视频一区二区三区 | 国产成人久久精品麻豆二区 | 久久国产人妻一区二区免色戒电影 | 欧美一级黄色片网站 | 麻豆导航| 成人黄色一级 | 亚洲第一视频区 | 国产成人免费 | 色无极亚洲影院 | 日本特黄一级大片 | а√天堂中文在线资源8 | 亚洲精品91在线 | 欧美高清在线 | 正在播放国产一区 | 久久先锋 | 五月激情在线 | 国产精品ⅴa有声小说 | 欧美精品欧美精品系列 | 五月激情综合网 | 国内黄色一级片 | 九色视频网 | 国产美女免费 | 国产乱码精品一区二区三区不卡 | 色爽爽爽爽爽爽爽爽 | 日韩久久成人 | 极品销魂美女少妇尤物 | 全部免费毛片在线播放一个 | 好看的黄色网址 | 黑人无套内谢中国美女 | 精品欧美色视频网站在线观看 | 成年人激情视频 | 稀缺呦国内精品呦 | av自拍偷拍 | 男生桶女生肌肌 | 午夜污 | 草草影院网址 | 免费观看全黄做爰的视频 | 欧美aaa大片| 欧美日韩一区二区三区不卡 | 中文字幕五码 | 日本少妇吞精囗交视频 | 黄色三级在线观看 | 欧美日韩国产网站 | 久久久久99精品成人片 | 中文字幕乱码中文乱码b站 国产一区二区三区在线观看视频 | av亚洲在线 | 久久草视频在线 | 久久久久久久影视 | 夜夜骑夜夜 | 成人黄色短片 | 在线不欧美| 涩涩爱在线| 丁香婷婷综合网 | 五月婷婷六月丁香综合 | 免费亚洲一区二区 | 欧美一区二区免费在线观看 | 男女草逼 | www.xxx在线观看| 高h喷汁呻吟3p | 韩国精品视频 | 青青久在线视频 | 综合色在线视频 | 亚洲高清毛片一区二区 |