<sub id="gqw76"><listing id="gqw76"></listing></sub>
      <sub id="gqw76"><listing id="gqw76"></listing></sub>

    1. <form id="gqw76"><legend id="gqw76"></legend></form>
    2. Web性能優化之瘦身秘笈

      Web 傳輸的內容當然是越少越好,最近一段時間的工作一直致力于 Web 性能優化,這是我近期使用過的一些縮減 Web 體積的手段

      這些手段主要是為了減少 Web 傳輸的內容大小,只有干貨

      CSS

      ??刪除無用的樣式

      在使用 UI 庫的時候,UI 庫提供的樣式并不是所有的都會使用到

      例如一個 button 組件一般都會提供 default/primary/success/warning/danger 五顏六色好幾款樣式

      但我們實際一個項目中也許只會用到其中的一兩種,為了減少樣式表的體積,需要將那些沒有使用的樣式挑選出來刪除掉

      使用 uncss 工具來刪除無用的樣式

      該工具提供有在線版,只需要復制自己的 HTML 以及 CSS,點擊按鈕就可以生成精簡后的樣式

      另外也可以通過瀏覽器工具 Coverage 挑選出未使用的樣式,如下圖

      coverage

      經過分析得出每個文件未使用樣式的百分占比,其中紅色標記的為未使用到的樣式,從下圖中可以看到具體未使用到的樣式有哪些

      coverage-style

      ?? 上面兩種方法都是通過樣式規則的選擇器在頁面上查找元素,如果能找到對應的元素,則說明該樣式規則有被使用
      隨著在頁面上進行各種操作,該百分比可能會降低,因為有些樣式會在某些操作執行之后才會被使用到,比如 :hover 偽類相關的樣式,在鼠標移入元素之前不會被標記為已使用的
      所以,這兩種方式都有一定的局限性,并不是挑選出的樣式就一定是沒有用的,也許某個樣式是在用戶執行相當復雜的操作后才會起作用,需要嚴格測試

      ?? 許多框架和庫也提供自定義打包版本,從源頭舍去那些無用的代碼

      ??刪除重復的樣式

      CSS 全名 層疊樣式表(Cascading Style Sheets),對同一個元素多次指定同一個樣式只會讓優先級高的覆蓋優先級低的

      在樣式規則的選擇器完全相同的情況下(比如這里 .selector-1 > .selector-2 和 .selector-1 > .selector-2 是完全相同的),被覆蓋的樣式可以安全地刪除,如下

      /* Before */
      .selector-1 > .selector-2 {
        display: none;
        width: 200px !important;
      }
      
      .selector-1 > .selector-2 {
        display: block;
        width: 100px;
      }
      
      /* After */
      .selector-1 > .selector-2 {
        width: 200px !important;
      }
      
      .selector-1 > .selector-2 {
        display: block;
      }
      

      通過瀏覽器的開發者工具可以輕松看到哪些樣式被覆蓋了

      uncss

      ?? 在選擇器不相同的時候,也有可能會匹配到同一個元素,這個時候本條規則并不適用,需要注意

      ?? 有時候同一個樣式屬性反復出現只是為了兼容一些舊瀏覽器,也需要注意

      ??使用復合屬性

      有些樣式屬性可以合并為一條,比如

      /* Before */
      .selector {
        flex-direction: column;
        flex-wrap: wrap;
      }
      
      /* After */
      .selector {
        flex-flow: column wrap;
      }
      

      合并之后字節數減少

      ??刪除過時的樣式

      有些樣式是為了兼容一些老舊瀏覽器而提供的,當前已經不需要再兼容這些瀏覽器了,對應的樣式可以刪除掉,比如如下這些

      - header {
      -   display: block;
      - }
      

      ?? 使用 autoprefixer 刪除過時的瀏覽器廠商前綴(比如 -moz-,-ms- 這些)

      ??利用繼承

      部分樣式會繼承給后代元素,后代元素沒有必要再寫一遍,除非是確實需要覆蓋的

      之所以會有這條是因為之前在項目中看到隨處可見的 box-sizing: border-box 屬性其實可以主動設置為繼承

      *,
      *:before,
      *:after {
        box-sizing: inherit;
      }
      
      html {
        box-sizing: border-box;
      }
      

      這樣所有元素都會繼承這個屬性,不用反復定義

      ??提取公共樣式

      將多個規則集中相同的樣式提取出來,并使用群組選擇器放在一起,比如

      /* Before */
      .badge {
        background-color: orange;
        border-raidus: 5px;
        color: #fff;
        font-size: 13px;
      }
      
      .label {
        background-color: orange;
        border-raidus: 5px;
        color: #fff;
        font-size: 12px;
      }
      
      /* After */
      .badge,
      .label {
        background-color: orange;
        border-raidus: 5px;
        color: #fff;
      }
      
      .badge {
        font-size: 13px;
      }
      
      .label {
        font-size: 12px;
      }
      

      csscss 可以用來分析冗余的 CSS 代碼

      這是一個 Ruby 工具,使用前需要先安裝 ruby1.9 或以上版本

      這個工具只是用來分析冗余樣式的,并不會主動刪除樣式,需要自己手動調整

      ?? 在 CSS 中,樣式的先后順序是有意義的,隨意移動樣式規則可能會讓樣式出現問題,需要經過嚴格測試

      ?? csso 可以用來刪除冗余,合并樣式規則

      ??壓縮 CSS

      壓縮主要是刪除無用的空白和注釋,或用更簡短的寫法代替

      推薦使用工具 cssnano 來壓縮 CSS

      該工具還提供了 在線版

      這是壓縮前的代碼

      cssnano

      這是壓縮后

      @charset "utf-8";h1:before{margin:10px 20px;color:red;font-weight:400;background-position:100% 100%;quotes:"?" "?";background:linear-gradient(180deg,#ffe500,#ffe500 50%,#121 0,#121);min-width:0}
      

      體積減少了一半

      ?? cssnano 自帶 autoprefixer 工具幫助清理瀏覽器廠商前綴

      JavaScript

      ??刪除無用的 JavaScript

      瀏覽器的 Coverage 工具也能挑選出未使用的 JavaScript 代碼,不再重復

      ?? 同樣的,挑選出來的代碼也不一定全是無用的,需要經過仔細測試

      ??刪除歷史遺留代碼

      同 CSS 一樣,JavaScript 也有一些代碼是為了兼容舊瀏覽器而存在的

      像 es5-shim.js 就是為了給那些不支持 ES5 的瀏覽器準備的,現在已經可以放心地從項目中去掉了,目前全球使用支持 ES5 的瀏覽器的用戶占比高達98%

      另外一些框架或庫的新版本通常將不會包含那些兼容舊瀏覽器的代碼,需要時保持更新即可,比如用 jQuery3.0 替換 jQuery1.12

      ??刪除功能重復的插件

      一個項目經手的人多了之后,會出現一些匪夷所思的膨脹,比如同一個項目中引入了好幾個功能相似的插件

      找出相關代碼,根據需求確定真正需要使用的插件,去掉其它多余的

      ?? 此條需要經過嚴格的測試

      ??用 CSS 代替 JavaScript 實現效果

      常見的比如鼠標移入區域的時候顯示元素,移出的時候隱藏元素,用 CSS 可以輕易實現

      .selector + .item {
        display: none;
      }
      
      .selector:hover + .item {
        display: block;
      }
      

      You-Dont-Need-JavaScript 這個倉庫展示了很多可以不依賴 JavaScript 實現的效果

      ??使用新的 API

      隨著 Web 標準的豐富以及瀏覽器的更新換代,越來越多的功能可以通過設備/瀏覽器原生的 API 來實現

      比如 IntersectionObserver 可以用來探測 DOM 元素是否位于窗口可視區域內,這就不需要借助插件來實現這些功能了

      相應的插件代碼可以從項目中安全地刪除,或者只為那些老舊設備/瀏覽器提供

      ??壓縮 JavaScript

      主要是刪除沒用的空白和注釋等等

      使用 Terser 來壓縮 JavaScript,通過 NPM 安裝 npm install terser -g

      執行命令 terser main.js -o main.min.js -c -m

      字體

      ??選擇合適的格式

      常用的字體格式有如下這些

      WOFF2/WOFF

      Web 開放字體格式(Web Open Font Format),加載快,壓縮率高

      WOFF2 是 WOFF 的升級版本,壓縮率更高

      SVG/SVGZ

      矢量圖形字體(Scalable Vector Graphics Font),僅有少部分瀏覽器支持(比如 iOS Safari 4.1-)

      EOT

      Embedded Open Type,IE 獨占

      TTF/OTF

      OpenType Font 和 TrueType Font,瀏覽器支持范圍最廣的格式

      根據目標設備選擇合適的字體格式,不同的字體格式兼容的瀏覽器也是不一樣的

      下圖是圖一套字體的不同文件格式的大小對比

      fonts

      我們應該優先選用壓縮率更高的 WOFF2 文件格式,如果瀏覽器不支持該格式,降級到 WOFF,甚至 OTF/TTF

      下面是完整定義字體的方式,瀏覽器會根據優先順序下載自身能識別但體積相對更小的字體文件

      @font-face {
        font-family: 'My Font';
        src: url('path/my-font.eot');
        src: url('path/my-font.eot?#iefix') format('embedded-opentype'),
             url('path/my-font.woff2') format('woff2'),
             url('path/my-font.woff') format('woff'),
             url('path/my-font.ttf')  format('truetype'),
             url('path/my-font.svg#svgFontName') format('svg');
      }
      
      • TTF/OTF 的兼容性僅比 WOFF 多出一點點而已,已經到了可以忽略不計的地步
      • SVG 字體和 EOT 是針對部分舊版本瀏覽器的兼容方案,目前已經沒有太大使用的價值

      所以上面的字體定義也可以精簡為如下,基本可以滿足市面上的主流瀏覽器

      @font-face {
        font-family: 'My Font';
        src: url('path/my-font.woff2') format('woff2'),
             url('path/my-font.woff') format('woff');
      }
      

      ??剔除多余的字體

      在一個字體文件中不是所有字體都會使用到,特別是在使用圖標字體的時候

      里面有很多圖標是我在項目中沒有用到的,這種時候就需要編輯字體文件,刪除那些沒用上的字體

      百度有個在線字體編輯工具 http://fontstore.baidu.com/static/editor/index.html 可以打開并編輯字體以及保存為其它格式

      這是經過我編輯過后的文件大小對比,文件大小差距很大,確實用到的字體比較少

      fonts-edit

      圖像

      在 Web 網頁中,圖像的體積占了大頭,減少圖像可以大幅增加性能

      ??選擇適合的圖像格式

      不同文件格式的圖像其文件大小,圖像質量是不一樣的,根據具體情況選擇合適的圖像格式

      常用 Web 圖像格式

      格式 透明 動畫 說明 瀏覽器支持
      GIF ?? ?? 顏色較少
      JPEG ? ? 有損格式,常用于照片
      PNG ?? ? 無損
      WebP ?? ?? 支持無損/有損壓縮,比JPEG,PNG和GIF更好的壓縮效果 較新
      AVIF ?? ?? 比WebP,JPEG,PNG和GIF更好的壓縮效果 最新
      JPEGXL ?? ?? 無損壓縮,更快的解碼和其他各種改進 暫無

      一些新的圖像格式擁有較高的性能,比如 AVIF 和 WebP

      不過這些新的圖像格式不是所有瀏覽器都支持,此時可以使用一個 <picture> 元素來包裹 <img> 元素,再通過使用 <source> 元素來為 <img> 元素提供多個備胎資源供其自行選擇

      <source> 元素可以有多個,srcset 屬性是必須的(注意是 srcset)

      <picture>
        <source type="image/avif" srcset="logo.avif">
        <source type="image/webp" srcset="logo.webp">
        <img alt="logo" src="logo.png">
      </picture>
      

      瀏覽器會自行忽略不支持的格式,如果瀏覽器支持 AVIF 格式就使用 logo.avif,如果支持 WebP 格式就使用 logo.webp

      如果上面倆都不支持,就會使用 logo.png,不支持 <picture> 元素的瀏覽器會直接顯示 <img> 元素

      值得一提的是 <picture> 元素內部必須包含一個 <img> 元素,否則圖像不會顯示(因為 <picture> 元素并不是一個獨立顯示的元素,而是為 <img> 元素服務的)

      還有 <img> 元素始終都不應該忘記的 alt 屬性,當任何圖像格式都無法顯示或者圖像下載失敗的時候,至少還能顯示替代的文字說明

      要在 CSS 中使用這些新的格式通常用 JavaScript 來判斷瀏覽器是否支持

      創建一個 Image 對象,然后加載一張較小的需要判斷格式的圖像,如果加載成功則說明瀏覽器支持該格式,下面是 Google 提供的判斷瀏覽器是否支持 WebP 的方法

      const img = new Image()
      img.onload = img.onerror = () => {
        document.body.classList.add(img.height > 0 ? 'webp' : 'no-webp')
      }
      img.src = 'data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA=='
      

      如果該瀏覽器支持,則給 <body> 元素添加 webp 類,否則添加 no-webp,在 CSS 中就可以這樣寫

      .webp .logo {
        background: url(./logo.webp);
      }
      
      .no-webp .logo {
        background: url(./logo.png);
      }
      

      這樣就能根據該瀏覽器是否支持 webp 格式加載不同格式的圖像了

      ?? 轉換圖像格式可以使用 Sqoosh,在圖像大小和質量之間手動調整權衡

      ??使用響應式圖像

      在 CSS 中使用媒體查詢結合 image-set 可以依據設備/瀏覽器的寬度以及像素比顯示不同分辨率的圖像

      ?? 為了方便一眼看出來,圖像的名稱包含了圖像的真實寬度,比如 logo-240.png 表示這張圖像寬度為 240 像素

      .logo {
        background-image: url(./images/logo-120.png);
        background-image: -webkit-image-set(url(./images/logo-120.png) 1x,
                                            url(./images/logo-240.png) 2x);
        background-image:         image-set(url(./images/logo-120.png) 1x,
                                            url(./images/logo-240.png) 2x);
      }
      
      @media (min-width: 600px) {
        .logo {
          background-image: url(./images/logo-240.png);
          background-image: -webkit-image-set(url(./images/logo-240.png) 1x,
                                              url(./images/logo-480.png) 2x);
          background-image:         image-set(url(./images/logo-240.png) 1x,
                                              url(./images/logo-480.png) 2x);
        }
      }
      
      @media (min-width: 1200px) {
        .logo {
          background-image: url(./images/logo-480.png);
          background-image: -webkit-image-set(url(./images/logo-480.png) 1x,
                                              url(./images/logo-960.png) 2x);
          background-image:         image-set(url(./images/logo-480.png) 1x,
                                              url(./images/logo-960.png) 2x);
        }
      }
      

      根據 移動優先 的原則,使用媒體查詢應該從小往大

      ?? 不支持 image-set 的瀏覽器將會使用前面定義的傳統 url 路徑

      ?? image-set 目前還在草案中,需要添加對應的瀏覽器廠商前綴,示例已添加

      ?? Safari 只支持 url 路徑和 1x/2x 這樣的設備像素比

      <img> 元素通過其新增的 srcset 和 sizes 屬性來實現響應式圖像

      <img alt="avator"
        src="avator-120.jpg"
        srcset="avator-120.jpg 120w, avator-240.jpg 240w, avator-480.jpg 480w"
        sizes="(max-width: 600px) 120px, 240px">
      

      srcset 屬性為圖像提供多個源供設備/瀏覽器自行選擇,其中圖像路徑后面的 120w/240w/480w 用于告訴設備/瀏覽器每張圖像的實際寬度

      sizes 屬性為圖像提供渲染尺寸,可以通過媒體查詢提供多個渲染尺寸以及一個默認尺寸(這里 240px 就是默認的渲染尺寸)

      設備/瀏覽器會根據這些信息選擇最合適的圖像加載顯示

      當設備/瀏覽器寬度在 600 像素以下時圖像將占據 120 像素的寬度,此時如果設備像素比為 1 則顯示 avator-120.jpg,如果設備像素比為 2 則顯示 avator-240.jpg,為 4 則應該顯示 avator-480.jpg

      當設備/瀏覽器寬度大于 600 像素的時候圖像將占據 240 像素的寬度,此時如果設備像素比為 1 則顯示 avator-240.jpg,如果設備像素比為 2 則顯示 avator-480.jpg

      瀏覽器寬度 設備像素比 顯示哪張圖像
      <= 600px 1 avator-120.jpg
      - 2 avator-240.jpg
      - 4 avator-480.jpg
      > 600px 1 avator-240.jpg
      - 2 avator-480.jpg

      ?? 設備像素比也有可能是小數,比如 1.5,設備/瀏覽器會選擇它自己認為最合適的那張圖像來顯示

      ?? 其中 src 屬性是給不支持 srcset 和 sizes 屬性的瀏覽器提供的

      ??圖像壓縮

      有些格式的圖像往往還會包含一些沒有用的信息,清理掉這些信息有助于縮小圖像體積

      這通常使用工具來進行

      使用 imagemin 壓縮圖像

      ??圖像懶加載

      頁面上有很多圖像我們一開始是看不到的,有的在我們滾動頁面之后才會出現在屏幕上,又有的在某個對話框彈出后才能看到

      對于這類圖像,我們可以推遲它們的加載時機,等到它們需要真正展示在屏幕上的時候才加載,而不是在頁面一開始時就加載,這將大大節省頁面初始化時加載的資源大小

      使用瀏覽器原生的懶加載方案,這非常簡單,只需要給圖像元素添加一個 loading="lazy" 屬性即可

      <img alt="avator" loading="lazy" src="avator.jpg">
      

      目前該屬性只得到一部分瀏覽器的支持,不支持的瀏覽器會忽略

      caniuse/loading-lazy-attr

      該屬性的 polyfill

      還可以使用 JavaScript 插件,市面上有不少這類型的插件

      ?? 引入一個插件會增加 JavaScript 的代碼量,但是延遲了部分圖像的加載時機,具體需要權衡

      ??使用其它方案替換圖像

      減少圖像最好的辦法就是沒有圖像

      使用 SVG 替換圖像

      warning

      上面這張圖像格式為 png 大小為 1.46kb

      下面是使用 SVG 來表示同樣的圖像的代碼,只有 300 多字節,體積大幅度減小

      <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
        <path d="M50 92.5H6.09a4.47 4.47 0 01-3.87-6.71l22-38 22-38a4.46 4.46 0 017.74 0l22 38 22 38a4.47 4.47 0 01-3.87 6.71z" fill="##ff7f00"></path>
        <path d="M57.41 78.1A7.41 7.41 0 1150 70.7a7.39 7.39 0 017.41 7.4zm-2.14-14.89H44.81l-1.72-36h13.82z" fill="#fff"></path>
      </svg>
      

      另外 SVG 既可以改變顏色,也可以任意放大縮小

      SVG 可以使用 SVGO 來優化

      使用純樣式替換圖像

      比如下面這個 loading 效果就是純樣式寫的

      相對于圖像來說,純代碼的字節數就少得多了

      @keyframes spin {
        to {
          transform: rotate(1turn);
        }
      }
      
      .loading {
        animation: spin 1.2s infinite linear;
        border: 4px solid rgba(0, 0, 0, 0.1);
        border-left-color: #46aaff;
        border-radius: 50%;
        height: 30px;
        width: 30px;
      }
      
      <div class="loading"></div>
      
      posted @ 2021-03-01 14:04  by.Genesis  閱讀(1846)  評論(2編輯  收藏
      最新chease0ldman老人|无码亚洲人妻下载|大香蕉在线看好吊妞视频这里有精品www|亚洲色情综合网

        <sub id="gqw76"><listing id="gqw76"></listing></sub>
        <sub id="gqw76"><listing id="gqw76"></listing></sub>

      1. <form id="gqw76"><legend id="gqw76"></legend></form>