快轉到主要內容

改善圖片處理

·1602 字·4 分鐘
目錄

在md裡面用gallery放圖時,發現圖已經載入,但layout是錯的,要等一段時間才會正常。這並不是載入速度慢,是hugo在渲染圖片時,無法正確算出要給多少空間去展現圖片。問了Gemini、chatGPT、Grok等工具,實際測試過後用了以下解法:

縮圖
#

手機拍的圖都蠻大的,但要在手機或電腦上看,其實可以縮到200~300KB;解析度縮成800X600(橫式)或是600X800(直式),可以改善下載和渲染、解碼的速度。
線上縮圖工具: iloveimg
另外,將jpeg轉換成webp會進一步改善圖片載入的速度,將相同品質的圖片壓縮得更小。
jpeg轉webp線上工具: piliapp

改善排版
#

blowfish很常用gallery做多圖的排版,當圖片載入後,browser必須計算長寬後決定要給你多大的空間,這邊會花時間,所以如果能"告訴"它要留多少空間,會讓速度改善不少。

  • img裡面調整class,加上aspect-xxx: class="aspect-xxx object-cover"
    • aspect-square: 呈現1:1正方形
    • aspect-video: 呈現16:9
    • aspect-[4/3]: 寬長比為4:3, 標準landscape圖片
    • aspect-[3/4]: 寬長比為3:4, 標準portrait圖片
    • object-cover 必加,不然會變形
沒有加aspect,瀏覽器必須等圖片下載完,知道寬高後,才開始計算佈局;加上後browser在下載前就會知道該圖會佔多少空間,跳過計算重排的時間
  • img裡設定decoding=“lazy”loading=“async”

    • 可以先檢查layouts/_default/_markup/render-image.html中有沒有找到這兩個設定,沒有的話,把theme/blowfish/下的render-image.html複製到layouts下的同一目錄,不然就直接加在img裡。
    • 若要修改layout/_default/_markup/render-image.html,參考下面程式碼:
      RenderImageResponsive
      ....
      {{- define "RenderImageResponsive" -}}
      {{- $imgObj := .imgObj -}}
      {{- $alt := .alt -}}
      {{- $originalWidth := $imgObj.Width -}}
      
      {{/* 1. 邏輯判斷:寬度是否小於高度 (直式) */}}
      {{- $isPortrait := lt $imgObj.Width $imgObj.Height -}}
      
      {{/* 2. 根據橫直決定縮圖策略,這能解決「解碼大圖」造成的卡頓 */}}
      {{- $img800 := "" -}}
      {{- if $isPortrait -}}
        {{/* 直式圖:限制高度為 800px,寬度自適應 */}}
        {{- $img800 = $imgObj.Resize "x800 webp" -}}
      {{- else -}}
        {{/* 橫式圖:限制寬度為 800px,高度自適應 */}}
        {{- $img800 = $imgObj.Resize "800x webp" -}}
      {{- end -}}
      
      <img
        {{/* 3. 根據橫直式動態加入不同的 CSS Class (搭配你的 Gallery 設定) */}}
        class="my-0 !rounded-lg !shadow-md w-full h-full object-cover {{ if $isPortrait }}img-portrait{{ else }}img-landscape{{ end }}"
        loading="lazy"
        decoding="async"
        alt="{{ $alt }}"
        /* 4. 傳入縮圖後的正確寬高這是消除 Layout Shift 紅色尖峰的關鍵 */
        width="{{ $img800.Width }}"
        height="{{ $img800.Height }}"
        src="{{ $img800.RelPermalink }}"
        data-zoom-src="{{ $imgObj.RelPermalink }}">
      {{- end -}}
  • 修改assets/css/custom.css

    custom.css
    /* ============================================================
       1. 效能優化區
       ============================================================ */
    img {
        /* 延遲非視口內的圖片渲染,減少首屏 CPU 解碼壓力 */
        content-visibility: auto;
        /* 強制 GPU 加速渲染,提升滑動時的流暢度 */
        transform: translateZ(0);
    }
    
    /* 全域濾鏡優化:移除不必要的毛玻璃與濾鏡計算,節省渲染資源 */
    * {
        backdrop-filter: none !important;
        filter: none !important;
    }
    
    /* ============================================================
       2. 佈局安全區 (解決「文字重疊/蓋字」問題)
       ============================================================ */
    
    /* 確保 Gallery/Grid 容器能完整閉合,不讓內部的浮動圖片影響後方文字 */
    /* 加上 .prose 確保只影響文章本體,不影響首頁卡片 */
    .prose .gallery::after, .prose .grid::after {
        content: "";
        display: table;
        clear: both;
    }
    
    /* Clearfix 萬用清除浮動:在容器末端強制「斷行」,這是防止文字竄位的物理防線 */
    .gallery::after, .grid::after {
        content: "";
        display: table;
        clear: both;
    }
    
    /* ============================================================
       3. 比例與形狀控制 (解決「正方形變長方形」問題)
       ============================================================ */
    
    /* 只有你在 Markdown 設定 aspect-square 時,才強制 1:1 並保持圖片不變形 */
    .aspect-square {
        aspect-ratio: 1 / 1 !important;
        object-fit: cover !important;
    }
    
    /* 支援自定義比例標籤 (如 aspect-[4/3]),並確保縮放時填滿容器 */
    [class*="aspect-["] {
        object-fit: cover !important;
    }
    
    /* ============================================================
       4. 網格寬度控制 (解決「並排失效/圖片過大」問題)
       ============================================================ */
    
    /* 確保設定了 grid-w 類別的圖片能正確橫向並排 */
    [class*="grid-w"] {
        display: inline-block !important;
        float: left !important;
        box-sizing: border-box; /* 確保邊框不撐破寬度 */
    }
    
    /* 針對 figure 標籤的基礎修復,確保內含圖片不會撐破父容器 */
    figure {
        max-width: 100%;
    }
    
    figure img {
        max-width: 100%;
        height: auto;
    }

美化
#

img裡的class可以對邊框做一些處理 <img = ...class="rounded-lg shadow-md ":

  • rounded-lg 大圓角 - 四邊做圓角處理
  • shadow-md 中等陰影 - 會在圖片下方和側邊加上一層淡淡的灰色陰影

另外,使用gallery和figure要和文字至少隔一行,避免css誤判。