自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

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

圖片圖片

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

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

資源體積太大

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

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

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

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

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

傳輸壓縮

  • 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的多路復用可以一次性發(fā)送多個請求,不一定是按順序也不需要等待上一個請求返回。這些請求都有唯一標識,所以可以無序。

比較詳細的內(nèi)容在面試點之《HTTP協(xié)議與TCP/IP協(xié)議》[1]中有。

HTTP緩存

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

圖片圖片

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

圖片圖片

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

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

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

圖片圖片

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

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

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

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

圖片圖片

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

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

首次進入白屏時間過長

骨架屏(vue-content-placeholders)

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

圖片圖片

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

  • 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]) ??在我們的項目構(gòu)建加載時,JavaScript文件才是最影響加載時長的,此時我們把各個路由切分成塊,按需加載路由,這樣會節(jié)約相當多的時間。

使用方法也很簡單:

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

預渲染

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

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

圖片圖片

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

  • 如果路由過多,成百上千(當然這應該是極少數(shù)情況)的時候,使用預渲染會非常緩慢。雖然說每次更新只用執(zhí)行一次,但是需要的時間會非常長。
  • 接口請求過多的時候不建議使用預渲染,而是使用SSR;如果沒有SEO的需求,骨架屏是個更簡單方便的選擇,不需過多的配置更不需要后臺配合。
  • 預渲染不執(zhí)行JavaScript,只試用于純靜態(tài)頁面,當然你也可以配置等接口請求返回拿到數(shù)據(jù)以后再預渲染,這種僅僅適用于少量接口請求。而SSR比預渲染的不同就是多了一步執(zhí)行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'
                },
                
                // 渲染時顯示瀏覽器窗口。用于調(diào)試。false意為打開,true是不打開
                headless: false,
                
                // 可選 - 等待渲染,直到在文檔上調(diào)度指定的事件。
                // 例如,使用 `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以后我們會得到如下的文件,這個時候我們會發(fā)現(xiàn),是多了一個about的文件夾。這是由于配置了new PrerenderSPAPlugin中的routes。

圖片圖片

圖片圖片

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

圖片圖片

圖片圖片

SSR(服務端渲染)

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

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

Service workers

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

優(yōu)化資源加載的順序

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

prefetch

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

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

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

圖片圖片

preload

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

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

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

圖片圖片

兩者的異同

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

補充

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

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

圖片圖片

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

2020-12-09 09:30:57

前端開發(fā)技術

2013-08-21 11:15:54

iOS橫豎屏方案

2021-05-08 08:01:05

Session登錄瀏覽器

2022-02-10 08:57:45

分布式線程鎖

2023-05-06 15:32:04

2021-07-06 06:39:58

Kafka消息隊列系統(tǒng)

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

數(shù)據(jù)庫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

2022-03-04 00:08:00

數(shù)據(jù)數(shù)據(jù)安全安全

2024-12-20 13:00:00

C++編程C++17

2023-09-29 11:29:12

Spring異常處理類
點贊
收藏

51CTO技術棧公眾號