成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這幾種解決方案讓你的首屏加載快到起飛!

開發 前端
preload?是告訴瀏覽器頁面必定需要的資源,瀏覽器一定會加載這些資源,而prefetch是告訴瀏覽器頁面可能需要的資源,瀏覽器不一定會加載這些資源。

首屏加載的意義不言而喻,畢竟第一印象最重要,直接影響用戶體驗和留存。當用戶使用你的產品的時候,一上來半天刷不出首頁,很多用戶往往就直接給你Ctrl+F4了。

那么問題來了,怎么做首屏優化。在了解怎么優化之前,我們需要知道首屏加載的幾個重要時刻。

圖片圖片

  • 首次加載
  • 什么時候加載出頁面
  • 什么時候用戶可以交互

為此,我們可以從以下幾個方面來進行相關的優化。

資源體積太大

資源壓縮與合并/代碼拆分

將小圖片內聯為Data URL,也可以額減小HTTP的請求數量,需要注意的是,瀏覽器緩存并不會存儲Data URL格式的圖片,放在css的background-image屬性中即可。由于使用Data URL在渲染和CPU消耗上更大,所以使用時也需要謹慎而不應該一味的濫用。

通過以上幾種方法,我們主要要解決的問題是以下幾個

  • 減少HTTP請求數量
  • 減少請求資源的大小
  • 減少不必要的代碼

需要注意的是,在CSS和JS合并的時候我們需要謹慎,并非所有CSS和JS合并都是好的,不能一味的為了做首屏或者性能優化而引發了其他方面的問題。在有若干個小文件的時候,或者是沒有沖突的同模塊的文件的時候是可以考慮合并的。但是如果我們把其他不同模塊的CSS和JS也合并到了一起,可能會給后續的解析處理和自己的代碼維護帶來問題,而且JS文件間還可能會出現命名空間的沖突。這些都是無腦的資源合并會帶來的問題。

傳輸壓縮

  • Gzip ??需要注意的是,太小的文件啟用Gzip以后可能反而會增大,這是因為壓縮前會寫入一段映射字典,但是這個是Byte層面的可以忽略不計。

HTTP2.0和HTTP1.1

圖片圖片

3630394917-5b229aa26f852_fix732.png

圖上簡單概括就是:

  • HTTP1.1的keep-alive默認開啟,而且keep-alive是按順序請求返回,等到上一個請求返回以后才會進行下一個請求,會有阻塞問題。keep-alive的請求順序如下:
  • 1.請求style.css
  • 2.返回style.css
  • 3.請求script.js
  • 4.返回script.js ??如何判斷是否開啟了keep-alive可以從Response Headers看到,切記是HTTP1.1中的。

圖片圖片

  • 但是HTTP2.0就不一樣了,HTTP2.0的多路復用可以一次性發送多個請求,不一定是按順序也不需要等待上一個請求返回。這些請求都有唯一標識,所以可以無序。

比較詳細的內容在面試點之《HTTP協議與TCP/IP協議》[1]中有。

HTTP緩存

在此之前,我們要熟悉兩個概念,強緩存和協商緩存。

圖片圖片

強緩存:瀏覽器直接從本地緩存中取數據,而不用去請求服務器。Expires/Cache-Control(優先級更高,且為通用字段,請求和返回報文中都可以使用)

圖片圖片

  • Cache-Control常見的屬性有很多:
  • max-age:單位是秒,意為緩存的持續時間(壽命)。比如Cache-Control:max-age=60;意為60秒內會直接使用該緩存,而max-age<=0時則每次都要發送請求驗證緩存是否有修改,改了的話返回200,沒改返回304;
  • no-store:不使用緩存,直接去服務器請求數據;
  • no-cache:不緩存過期資源;客戶端會要求緩存服務器不要從緩存拿數據,而是去請求源服務器,源服務器會告訴緩存服務器,使用緩存時先告訴我驗證一下。區別在于直接使用緩存是不會請求源服務器的。
  • public:表明響應可以被任何對象(發送請求的客戶端,代理服務器等等)緩存;
  • privite:表明響應只能被單個用戶緩存,不能作為共享緩存(即代理服務器不能緩存它);
  • Expires:GMT格式的時間字段,意為到期時間。超過此時間以后資源作廢。缺點在于是和本地時間比較,本地時間可能存在誤差。也可以設置為0或者負數,此時不使用緩存直接從服務器重新請求數據。

協商緩存:瀏覽器發送請求到服務器,服務器判斷是否使用本地緩存。

Etag(響應頭中)和If-None-Match(請求頭中)【優先級更高】

圖片圖片

??兩者的值都是該資源的唯一標識字符串。第一次請求時,響應頭(Response Headers)中會添加一個Etag的字段,再次請求服務器時,會在請求頭報文(Request Headers)中添加If-None-Match字段,它的值就是上次響應頭(Response Headers)中的Etag值。服務器會比較兩個值是否相同。

  • 相同: 返回狀態碼304 Not Modified,直接取用本地緩存即可。
  • 不相同: 說明資源內容已經發生了變化,此時接受請求,返回最新的數據,并更新Etag值。Etag中可能會有W/這樣的標識,W/(大小寫敏感) 表示使用弱驗證器。弱驗證器很容易生成,但不利于比較。強驗證器是比較的理想選擇,但很難有效地生成。相同資源的兩個弱Etag值可能語義等同,但不是每個字節都相同。

需要特別注意的是,Etag變化并不代表文件內容一定變化,Etag的值取決于服務端的算法。比如Etag的值由最后一次修改時間+內容經過哈希算法而得,但是此時我編輯了內容并沒有修改內容,最后一次的修改時間會發現變化,此時的Etag值肯定也會變化,但是內容并沒有發生改變

Last-Modified(響應頭中)和If-Modified-Since(請求頭中)

圖片圖片

??如圖所示,兩者的值都是GMT格式的時間字符串,Last-Modified意為最后一次修改文件的時間,其實這個方法和上一種原理一樣,只不過一個是用唯一標識字符串來比較,一個是用最后一次修改的時間來比較。也是第一次請求時,響應頭(Response Headers)中會添加一個Last-Modified的字段,記錄了最后一次文件修改的時間,然后再次請求時,會在請求頭(Request Headers)中添加If-Modified-Since字段,值就是上一次響應時響應頭中Last-Modified的值。服務器會比較Last-Modefied和Last-Modefied-Since的值。

  • 相同: 返回狀態碼304 Not Modified,直接取用本地緩存即可。
  • 不相同: 說明資源內容已經發生了變化,此時接受請求,返回最新的數據,并更新Last-Modified值。
兩者的區別
  • 當一個文件周期性修改而文件內容并沒有修改的時候,Last-Modified還是會從服務器請求新的數據,這并不是我們希望看到的,這個時候Etag能更好的處理這種情況。
  • Last-Modified的精準度只有秒,當一秒內修改多次時,這種修改無法判斷。??所以Etag的精度和適用性要強于Last-Modefied,兩者雖然可以同時使用,但是服務器會優先驗證Etag。

首次進入白屏時間過長

骨架屏(vue-content-placeholders)

效果如下圖:(圖片來源網絡,侵刪)

圖片圖片

我使用的是這個插件vue-content-placeholders[2],其次,骨架屏是需要自己畫的,你需要把布局畫好做成一個組件,在需要的頁面引用,然后等數據請求回來以后隱藏掉再顯示正常的頁面就可以。通常僅僅在接口請求比較多的頁面用到骨架屏,畢竟當你的頁面改動的時候骨架屏的頁面布局也需要改動,如果每個頁面都使用骨架屏未免太浪費開發時間也增加了日后的維護成本。

  • root <content-placeholders>(以下三個屬性會應用到所有子組件中)
  • animated (default: true; type: Boolean):是否開啟動畫效果
  • rounded (default: false; type: Boolean):是否加上邊角度,等同于設置border-radius
  • centered (default: false; type: Boolean):是否同時垂直+水平居中顯示
  • <content-placeholders-heading />
  • img (default: false; type: Boolean):是否顯示圖片模塊

圖片圖片

  • <content-placeholders-text />
  • lines (default: 4; type: Boolean):顯示幾條

圖片圖片

  • <content-placeholders-img />

圖片圖片

可以在標簽上直接設置class和style

<content-placeholders class='xxx' :animated='true' :rounded='true' :centered='true'>
    <content-placeholders-heading class='xxx' style='xxxx' :img="true" />
</content-placeholders>
<content-placeholders style='xxxx' :animated='true' :rounded='true' :centered='true'>
    <content-placeholders-text class='xxx' style='xxxx' :lines="3" />
    <content-placeholders-img class='xxx' style='xxxx' />
</content-placeholders>

vue文件引入需要的骨架屏組件即可。

<template>
  <div>
    <Placeholders-Component v-if="isShow"></Placeholders-Component>
    <div v-else class="main">
      ·······
    </div>
  </div>
</template>
<script>
import PlaceholdersComponent from "./PlaceholdersComponent";//引入寫好的骨架屏組件
export default {
  components: {
    PlaceholdersComponent,
  },
  data() {
    return {
      hidden: true,
    };
  },
};
</script>

懶加載

  • Vue的路由懶加載(官方文檔[3]) ??在我們的項目構建加載時,JavaScript文件才是最影響加載時長的,此時我們把各個路由切分成塊,按需加載路由,這樣會節約相當多的時間。

使用方法也很簡單:

const Foo = () => import('./Foo.vue')
    const Bar = () => import('./Bar.vue')
    
    const router = new VueRouter({
        routes: [{ 
            path: '/foo',
            component: Foo 
        },{ 
            path: '/bar',
            component: Bar 
        }]
    })
  • 圖片懶加載 ??在我的《前端性能優化(二):圖片[4]》文中已經講了比較詳細的圖片懶加載在此就不多解釋了。

預渲染

我使用的是Vue.js官網介紹使用的prerender-spa-plugin。這個插件的配置很多,它的GitHub地址在這里[5]。

Vue.js的官網中給到該預渲染插件如下描述:

圖片圖片

預渲染也有一些需要注意的點:

  • 如果路由過多,成百上千(當然這應該是極少數情況)的時候,使用預渲染會非常緩慢。雖然說每次更新只用執行一次,但是需要的時間會非常長。
  • 接口請求過多的時候不建議使用預渲染,而是使用SSR;如果沒有SEO的需求,骨架屏是個更簡單方便的選擇,不需過多的配置更不需要后臺配合。
  • 預渲染不執行JavaScript,只試用于純靜態頁面,當然你也可以配置等接口請求返回拿到數據以后再預渲染,這種僅僅適用于少量接口請求。而SSR比預渲染的不同就是多了一步執行JavaScript。
安裝
npm i prerender-spa-plugin -D
webpack.prod.conf.js
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer

const webpackConfig = merge(baseWebpackConfig, {
    plugins:[
        new PrerenderSPAPlugin({
            // 必需 - 要預渲染的 webpack 輸出應用程序的路徑。
            staticDir: path.join(__dirname, '../dist'),
            
            // 必需 - 要渲染的路由
            routes: ['/', '/about'],
          
            renderer: new Renderer({
                inject: {
                    foo: 'bar'
                },
                
                // 渲染時顯示瀏覽器窗口。用于調試。false意為打開,true是不打開
                headless: false,
                
                // 可選 - 等待渲染,直到在文檔上調度指定的事件。
                // 例如,使用 `document.dispatchEvent(new Event('event-home'))` 
                renderAfterDocumentEvent: 'event-home'
            })
        }),
    ]
})
main.js
new Vue({
    el: '#app',
    store,
    router,
    components: { App },
    template: '<App/>',
    mounted() {
        document.dispatchEvent(new Event('event-home'))
    }
})

npm run build以后我們會得到如下的文件,這個時候我們會發現,是多了一個about的文件夾。這是由于配置了new PrerenderSPAPlugin中的routes。

圖片圖片

圖片圖片

而且此時我們會發現,在打包好的index.html文件中,id為app的div標簽中有其他標簽內容。倘若我們不使用預渲染,打包出的文件里,這個標簽里是空的不會有任何標簽。

圖片圖片

圖片圖片

SSR(服務端渲染)

  • 分頁首屏加載
  • 各好的SEO
  • 搜索排名很重要的時候
  • 大型架構,動態頁面,且面對公眾用戶

具體使用可參考Vue的官方文檔

Service workers

Service workers可以很好的解決離線時候的首頁加載問題。但是鑒于文章長度限制,就在此處不細說了。

優化資源加載的順序

某乎有位大佬說的很詳細,鏈接在此[6]。

prefetch

主要加載較晚才會用到的資源,告知瀏覽器后,瀏覽器就會在閑時去加載對應的資源,很適合在懶加載時使用。

<link rel="prefetch" href="xxxxx.css">

對于使用prefetch獲取資源,其優先級默認為最低Lowest,可以認為當瀏覽器空閑的時候才會去獲取的資源。

圖片圖片

preload

主要用來加載當前頁面很重要的資源。

<link rel="preload" href="xxxxx.png" as="image">

瀏覽器通過as值能得知資源類型,還能根據as的值發送適當的Accept頭部信息。甚至可以通過as來標識他們請求資源的優先級(比如說使用as="style"屬性將獲得最高的優先級,即使資源不是樣式文件)

圖片圖片

兩者的異同

  • 如果關閉了瀏覽器,倘若請求還沒有結束,preload會立刻結束請求,但是prefetch會繼續請求。
  • 如果preload還未下載完就已經開始解析所需資源,此時并不會二次請求,而是等待此次請求完畢。
  • 倘若對同一個資源同時使用preload和prefetch則會導致二次加載。
  • preload是告訴瀏覽器頁面必定需要的資源,瀏覽器一定會加載這些資源,而prefetch是告訴瀏覽器頁面可能需要的資源,瀏覽器不一定會加載這些資源。

補充

關于Vue中的一些優化(并非首屏優化),我推薦黃軼老師的這篇文章《揭秘 Vue.js 九個性能優化技巧》[7]。

在我個人理解看來,性能優化的最終目的并不是完全追求時間上的長短,核心目的是給用戶更好的體驗,在提升了幀數的情況舍棄一點點加載或者渲染時間在整體體驗上要比完全追求數值上的長短有意義的多。也就是上面文章中這位朋友分享的觀點:

圖片圖片

責任編輯:武曉燕 來源: 量子前端
相關推薦

2020-12-09 09:30:57

前端開發技術

2022-02-10 08:57:45

分布式線程鎖

2021-05-08 08:01:05

Session登錄瀏覽器

2013-08-21 11:15:54

iOS橫豎屏方案

2021-07-06 06:39:58

Kafka消息隊列系統

2023-05-06 15:32:04

2022-01-05 16:16:02

查詢編程工程師

2009-07-13 10:36:18

2017-12-26 14:05:21

潤乾大屏可視化

2011-07-29 10:21:03

iPad 橫豎屏 切換

2018-10-10 10:23:53

數據庫RedisNoSQL

2011-10-25 11:40:54

打印機常見問題

2023-10-20 07:29:16

框架模型Prompt

2012-05-30 09:22:29

2023-11-06 08:00:38

接口高可用機制

2012-05-30 13:25:48

2023-11-10 08:18:27

JavaGraalVM

2024-12-20 13:00:00

C++編程C++17

2022-03-04 00:08:00

數據數據安全安全

2010-06-09 08:49:54

IBM SSCT
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国产91久久久久久吃药 | 一级一级一级毛片 | 精品在线播放 | 国产不卡一区 | 国产精品高潮呻吟久久 | 一级久久久久久 | 久久黄色精品视频 | 国产成人亚洲精品自产在线 | 蜜臀久久99精品久久久久野外 | 一区二区三区在线 | 欧 | 精国产品一区二区三区 | 日韩在线欧美 | 中文字幕乱码一区二区三区 | 国产精品一区二区不卡 | 一区二区视频 | 国产成人av电影 | 二区中文 | 亚洲精品久久久久久首妖 | 久久中文字幕视频 | 欧美一级片在线观看 | 精品久久久久久亚洲精品 | 亚洲一区成人 | www.久久艹| 国产欧美一区二区三区在线播放 | 国产一区二区三区四区在线观看 | 亚洲欧美在线一区 | 涩涩视频在线播放 | 手机看片在线播放 | a级黄色毛片免费播放视频 国产精品视频在线观看 | 毛片一级片 | 欧美一级黄色免费 | 亚洲成av| 黄色国产在线播放 | 麻豆一区二区三区精品视频 | 亚洲人成一区二区三区性色 | 亚洲乱码国产乱码精品精98午夜 | 欧美精三区欧美精三区 | 国产在线一区二 | 美女天天干天天操 | 国产成人精品a视频 | 久久婷婷av|