Static resource processing
Static resource handling is an indispensable part of front-end engineering, involving the loading, compression, caching strategies, and deployment optimization of files such as images, fonts, stylesheets, and scripts. Proper static resource management can significantly improve page performance, reduce server pressure, and lower development and maintenance costs.
Classification and Characteristics of Static Resources
Front-end static resources are typically categorized as follows:
- Media Resources: Binary files including images (PNG/JPG/SVG), videos (MP4/WebM), and audio (MP3/WAV).
- Style Resources: CSS files and preprocessor files like SASS/LESS.
- Script Resources: JavaScript/TypeScript files.
- Font Files: Font formats such as WOFF/WOFF2/TTF.
- Document Resources: Text-based resources like PDF/JSON/XML.
These resources share common characteristics:
- Relatively fixed content with infrequent changes.
- Can be cached by browsers.
- Require specific loading strategies (e.g., lazy loading).
- Most need compression and optimization.
Core Objectives of Engineering Processing
Resource Version Control
Achieving long-term caching through file hashing is a common practice. Webpack configuration example:
output: {
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js',
assetModuleFilename: 'assets/[hash][ext][query]'
}
On-Demand Loading
Dynamic imports for code splitting:
// Using React.lazy for component lazy loading
const LazyComponent = React.lazy(() => import('./LazyComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}
Resource Compression and Optimization
Common optimization techniques include:
- Converting images to WebP format.
- Tree Shaking for CSS/JS.
- Font subsetting.
- Sprite sheet generation.
Modern Build Tool Practices
Webpack Resource Handling
Complete resource configuration example:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|webp)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024 // Convert to base64 if under 8kb
}
},
generator: {
filename: 'images/[hash][ext][query]'
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: {
filename: 'fonts/[hash][ext][query]'
}
}
]
}
};
Vite-Specific Handling
Vite has built-in optimizations for static resources:
// Explicit URL import
import imgUrl from './img.png?url'
// Import as a string
import imgSrc from './img.png?raw'
// Specify processing methods
import logo from './logo.png?w=200&format=webp'
Advanced Caching Strategies
CDN Deployment Configuration
Typical CDN resource path rules:
https://cdn.example.com/[project]/[environment]/[version]/static/js/main.abcd1234.js
Service Worker Caching
Workbox configuration example:
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
// Precompile resources
precacheAndRoute(self.__WB_MANIFEST);
// Custom caching strategy
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({
cacheName: 'image-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 100,
maxAgeSeconds: 30 * 24 * 60 * 60,
}),
],
})
);
Performance Monitoring and Optimization
Resource Loading Waterfall Chart
Using the Performance API for monitoring:
const resourceTimings = performance.getEntriesByType('resource');
resourceTimings.forEach(resource => {
console.log(`${resource.name} loading time: ${resource.duration.toFixed(2)}ms`);
});
Critical Resource Preloading
HTML head declarations:
<link rel="preload" href="critical.css" as="style">
<link rel="prefetch" href="lazy-module.js" as="script">
Exception Handling Mechanisms
Resource Loading Failure Handling
Global error listener example:
window.addEventListener('error', (event) => {
if (event.target.tagName === 'IMG') {
event.target.src = '/fallback-image.png';
event.target.alt = 'Failed to load';
}
}, true);
Font Loading Fallback Solutions
CSS font fallback strategy:
@font-face {
font-family: 'CustomFont';
src: url('font.woff2') format('woff2'),
url('font.woff') format('woff');
font-display: swap;
}
body {
font-family: 'CustomFont', system-ui, sans-serif;
}
Special Handling in Micro-Frontend Scenarios
Resource Sharing Strategies
Avoid duplicate loading via externals:
module.exports = {
externals: {
react: 'React',
'react-dom': 'ReactDOM'
}
};
Sub-Application Resource Isolation
CSS scoping example:
// Using Shadow DOM
const shadow = document.getElementById('app').attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
/* Styles only apply within this Shadow DOM */
</style>
<div class="app-content"></div>
`;
Automated Testing and Validation
Resource Integrity Verification
Jest test case example:
test('Critical resources should be below threshold', () => {
const bundleStats = require('./dist/stats.json');
expect(bundleStats.assets['main.js'].size).toBeLessThan(1024 * 500);
expect(bundleStats.assets['main.css'].size).toBeLessThan(1024 * 50);
});
Cache Hit Rate Testing
Puppeteer test script:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// First load
await page.goto('https://example.com');
const firstLoad = await page.evaluate(() =>
performance.getEntriesByType('resource')
);
// Second load
await page.reload();
const secondLoad = await page.evaluate(() =>
performance.getEntriesByType('resource')
);
// Verify cache hits
const cachedResources = secondLoad.filter(res =>
res.duration < firstLoad.find(f => f.name === res.name).duration * 0.1
);
console.log(`Cache hit rate: ${(cachedResources.length/secondLoad.length*100).toFixed(1)}%`);
await browser.close();
})();
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn