Hugo Asset Pipeline: Minifikasi, Bundling, dan Optimasi Assets
Hugo Asset Pipeline: Minifikasi, Bundling, dan Optimasi Assets
Hugo memiliki asset pipeline yang powerful untuk memproses dan mengoptimalkan CSS, JavaScript, dan asset lainnya. Dengan Hugo Pipes, Anda dapat minify, bundle, fingerprint, dan transform assets dengan mudah. Panduan ini akan membahas cara memaksimalkan Hugo asset pipeline untuk performa website yang optimal.
Asset pipeline yang efisien sangat penting untuk website performance karena assets (terutama CSS dan JavaScript) adalah kontributor utama terhadap ukuran halaman dan waktu loading. Hugo Pipes menyediakan abstractions yang powerful untuk asset processing tanpa memerlukan tools eksternal.
Dasar-Dasar Hugo Pipes
Hugo Pipes adalah API untuk memproses assets di Hugo. Dengan Hugo Pipes, Anda dapat transform assets melalui series of operations.
Operasi Dasar
{{/* Ambil asset */}}
{{ $css := resources.Get "css/main.css" }}
{{/* Transform dengan PostCSS */}}
{{ $css = $css | resources.PostCSS }}
{{/* Minify */}}
{{ $css = $css | minify }}
{{/* Fingerprint untuk cache busting */}}
{{ $css = $css | fingerprint }}
{{/* Output */}}
<link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}">
Chaining Operations
{{/* Multiple transformations */}}
{{ $style := resources.Get "scss/main.scss" |
resources.ToCSS |
resources.PostCSS (dict "config" "postcss.config.js") |
minify |
fingerprint }}
CSS Processing
SCSS/SASS Compilation
Hugo Extended diperlukan untuk SCSS/SASS processing:
{{/* assets/css/main.scss */}}
$primary-color: #3498db;
.container {
background: $primary-color;
.header {
color: white;
font-size: 1.5rem;
}
}
{{/* Compile SCSS */}}
{{ $scss := resources.Get "scss/main.scss" | resources.ToCSS | minify }}
<link rel="stylesheet" href="{{ $scss.RelPermalink }}">
PostCSS Processing
// postcss.config.js
module.exports = {
plugins: {
'postcss-import': {},
'tailwindcss': {},
'autoprefixer': {},
'cssnano': {},
},
}
{{/* PostCSS processing */}}
{{ $css := resources.Get "css/main.css" | resources.PostCSS | minify }}
CSS Bundling
{{/* Multiple CSS files */}}
{{ $styles := slice
(resources.Get "css/reset.css")
(resources.Get "css/base.css")
(resources.Get "css/components.css")
(resources.Get "css/utilities.css")
}}
{{ $combined := $styles | resources.Concat "css/bundle.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $combined.RelPermalink }}">
JavaScript Processing
JavaScript Minification
{{/* Minify single file */}}
{{ $js := resources.Get "js/main.js" | minify }}
<script src="{{ $js.RelPermalink }}"></script>
{{/* Multiple files */}}
{{ $scripts := slice
(resources.Get "js/lib/jquery.js")
(resources.Get "js/lib/bootstrap.js")
(resources.Get "js/main.js")
}}
{{ $combined := $scripts | resources.Concat "js/app.js" | minify | fingerprint }}
<script src="{{ $combined.RelPermalink }}"></script>
ESBuild Integration
Hugo mendukung ESBuild melalui PostCSS atau langsung:
// esbuild.config.js
import esbuild from 'esbuild';
esbuild.build({
entryPoints: ['assets/js/main.js'],
bundle: true,
outfile: 'assets/js/bundle.js',
minify: true,
sourcemap: true,
target: ['es2020'],
});
TypeScript Processing
# Install TypeScript
npm install -D typescript
# Compile TypeScript
npx tsc --project tsconfig.json --outDir assets/js/
Asset Fingerprinting
Fingerprinting adalah teknik untuk menambahkan hash ke filenames, memungkinkan long-term caching tanpa masalah versioning:
{{ $css := resources.Get "css/main.css" | minify | fingerprint }}
<link rel="stylesheet"
href="{{ $css.RelPermalink }}"
integrity="{{ $css.Data.Integrity }}"
crossorigin="anonymous">
Berbeda Fingerprints untuk Berbeda Environments
{{- if hugo.IsProduction -}}
{{ $css = $css | fingerprint }}
{{- else -}}
{{ $css = $css | resources.PostCSS }}
{{- end -}}
CSS Variables dan Theming
CSS Custom Properties
/* assets/css/theme.css */
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333;
--bg-color: #fff;
--spacing-unit: 8px;
--border-radius: 4px;
}
[data-theme="dark"] {
--primary-color: #5dade2;
--secondary-color: #58d68d;
--text-color: #f5f5f5;
--bg-color: #1a1a1a;
}
{{/* Inline critical CSS variables */}}
{{ $vars := resources.Get "css/theme.css" | resources.ToCSS | minify | resources.FromString "critical.css" }}
<style>
{{ $vars.Content | safeCSS }}
</style>
JavaScript Module Bundling
ES Modules
// assets/js/module.js
export function calculateReadingTime(text) {
const wordsPerMinute = 200;
const words = text.trim().split(/\s+/).length;
return Math.ceil(words / wordsPerMinute);
}
export function formatDate(date) {
return new Intl.DateTimeFormat('id-ID', {
year: 'numeric',
month: 'long',
day: 'numeric'
}).format(date);
}
{{/* Use ES modules */}}
{{ $module := resources.Get "js/module.js" | js.Build "js/module.js" | minify | fingerprint }}
<script type="module" src="{{ $module.RelPermalink }}"></script>
Dynamic Imports
// assets/js/main.js
// Dynamic import untuk code splitting
async function loadComments() {
const { renderComments } = await import('./comments.js');
renderComments();
}
document.getElementById('load-comments').addEventListener('click', loadComments);
Image Processing dalam Asset Pipeline
Inline SVG
{{/* Inline SVG icons */}}
{{- $icon := resources.Get "icons/search.svg" | resources.ExecuteAsTemplate "icons/search.svg" . -}}
<span class="icon">{{ $icon.Content | safeHTML }}</span>
SVG Optimization
{{/* Optimize SVG */}}
{{ $svg := resources.Get "images/logo.svg" | minify }}
<img src="{{ $svg.RelPermalink }}" alt="Logo">
Critical CSS
Critical CSS adalah CSS yang diperlukan untuk rendering above-the-fold content. Inline critical CSS untuk menghindari render blocking:
{{/* layouts/partials/critical-css.html */}}
{{- $critical := resources.Get "css/critical.css" | toCSS | minify -}}
<style>
{{ $critical.Content | safeCSS }}
</style>
{{/* layouts/_default/baseof.html */}}
<head>
{{ partial "critical-css.html" . }}
{{- $styles := resources.Get "css/main.css" | toCSS | minify | fingerprint -}}
<link rel="preload" href="{{ $styles.RelPermalink }}" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="{{ $styles.RelPermalink }}"></noscript>
</head>
Build Performance Optimization
Incremental Processing
{{/* Cache expensive operations */}}
{{ $style := resources.Get "scss/main.scss" |
resources.ToCSS |
resources.PostCSS |
minify |
fingerprint |
resources.Copy "css/main.css" }}
Parallel Processing
Hugo automatically processes assets in parallel where possible. Untuk operasi yang expensive, consider:
{{/* Process independently */}}
{{ $css := resources.Get "css/main.css" | minify }}
{{ $js := resources.Get "js/main.js" | minify }}
Asset Organization
Recommended Structure
assets/
├── css/
│ ├── main.css
│ ├── critical.css
│ └── vendor/
│ ├── normalize.css
│ └── bootstrap.css
├── js/
│ ├── main.js
│ ├── vendor/
│ │ ├── jquery.js
│ │ └── framework.js
│ └── modules/
│ ├── utils.js
│ └── components.js
├── scss/
│ ├── main.scss
│ ├── _variables.scss
│ ├── _mixins.scss
│ └── components/
├── images/
│ ├── logo.svg
│ └── sprites/
└── fonts/
├── inter-var.woff2
└── jetbrains-mono.woff2
Vendor Assets
{{/* Load vendor CSS */}}
{{ $vendorCSS := slice
(resources.Get "css/vendor/normalize.css")
(resources.Get "css/vendor/bootstrap.css")
) | resources.Concat "css/vendor.css" | minify | fingerprint }}
Production vs Development
Conditional Processing
{{- if hugo.IsProduction -}}
{{- $style := resources.Get "scss/main.scss" |
resources.ToCSS |
resources.PostCSS (dict "config" "postcss.prod.config.js") |
cssnano |
minify |
fingerprint -}}
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
{{- else -}}
{{- $style := resources.Get "scss/main.scss" |
resources.ToCSS |
resources.PostCSS -}}
<link rel="stylesheet" href="{{ $style.RelPermalink }}">
{{- end -}}
Troubleshooting
Common Issues
Issue: CSS tidak ter-render
Solution: Pastikan menggunakan Hugo Extended dan path assets benar.
Issue: Fingerprint tidak berubah
Solution: Clear Hugo cache dengan hugo server --gc.
Issue: SCSS tidak compile
Solution: Install Dart Sass atau gunakan Hugo Extended yang sudah include Sass.
Best Practices Summary
| Practice | Description |
|---|---|
| Fingerprint assets | Enable long-term caching |
| Minify output | Reduce file size |
| Bundle files | Fewer HTTP requests |
| Critical CSS | Inline untuk above-the-fold |
| Defer non-critical JS | Non-blocking rendering |
| Use Hugo Extended | Full asset processing |
| Version control assets | Track changes |
Kesimpulan
Hugo asset pipeline menyediakan semua tools yang diperlukan untuk asset processing yang efficient. Dengan memahami dan memanfaatkan Hugo Pipes, Anda dapat achieve optimal performance untuk website Hugo Anda.
Artikel Terkait
Link Postingan: https://www.tirinfo.com/hugo-asset-pipeline/