HTML Minifier & Compressor
Remove redundant comments, spaces & linebreaks without breaking scripts, styles, or pre blocks
Templates:
Original Size
0 B
Minified Size
0 B
Saved Bandwidth
0 B
0%
Lines Reduction
0 → 0
Minification Rules & Protection Engine
Smart Safety Active
Raw Input HTML
Minified HTML
Syntax Protection
Safeguards <pre> code tabs, textareas, CSS blocks, and script tags so formatting and executable functions remain 100% intact.
Instant PageSpeed Boost
Eliminating bloated comments, indentations and trailing whitespace dramatically reduces payload size and Time to First Byte (TTFB).
100% Client-Side Privacy
All processing occurs instantly inside your browser RAM. Your HTML markup, source tokens, and copy are never uploaded to any remote server.
Action completed!
`;
protectedStore.push(cleanedTag);
return `___HTM_PROTECTED_BLOCK_${protectedStore.length - 1}___`;
} else {
protectedStore.push(full);
return `___HTM_PROTECTED_BLOCK_${protectedStore.length - 1}___`;
}
});
// 4. Remove HTML Comments (preserve IE conditional comments like /g, '');
}
// 5. Strip Whitespace between adjacent HTML tags (> < -> ><)
if (optTagGap) {
processed = processed.replace(/>\s+<');
}
// 6. Collapse internal whitespace
if (optWhitespace) {
processed = processed.replace(/\s+/g, ' ');
processed = processed.replace(/\s+>/g, '>');
processed = processed.replace(/<\s+/g, '<');
}
// 7. Restore protected blocks
for (let i = 0; i < protectedStore.length; i++) {
processed = processed.replace(`___HTM_PROTECTED_BLOCK_${i}___`, protectedStore[i]);
}
return processed.trim();
}
// Core execution function
window.htmProcessMinify = function() {
const raw = inputEl.value;
const minified = minifyHTML(raw);
outputEl.value = minified;
// Update real-time stats
const origBytes = new Blob([raw]).size;
const miniBytes = new Blob([minified]).size;
const diff = origBytes - miniBytes;
const percent = origBytes > 0 ? ((diff / origBytes) * 100).toFixed(1) : 0;
statOriginal.textContent = formatSize(origBytes);
statMinified.textContent = formatSize(miniBytes);
statSavedBytes.textContent = (diff >= 0 ? '-' : '+') + formatSize(Math.abs(diff));
statPercent.textContent = (diff >= 0 ? `${percent}% smaller` : `+${Math.abs(percent)}%`);
const origLines = getLineCount(raw);
const miniLines = getLineCount(minified);
statLines.textContent = `${origLines} → ${miniLines}`;
// Update preview if currently visible
if (isPreviewMode) {
renderIframePreview(minified);
}
};
// Live Auto Trigger
window.htmOnInput = function() {
if (liveToggle.checked) {
window.htmProcessMinify();
}
};
window.htmAutoTrigger = function() {
window.htmProcessMinify();
};
// Load sample template
window.htmLoadSample = function(key) {
if (SAMPLES[key]) {
inputEl.value = SAMPLES[key];
window.htmProcessMinify();
window.htmToast(`Loaded "${key.charAt(0).toUpperCase() + key.slice(1)}" template!`);
}
};
// Clear Input
window.htmClearInput = function() {
inputEl.value = '';
outputEl.value = '';
statOriginal.textContent = '0 B';
statMinified.textContent = '0 B';
statSavedBytes.textContent = '0 B';
statPercent.textContent = '0%';
statLines.textContent = '0 → 0';
if (isPreviewMode) {
renderIframePreview('');
}
inputEl.focus();
window.htmToast('Cleared input workspace');
};
// Copy Output
window.htmCopyOutput = function() {
const text = outputEl.value;
if (!text) {
window.htmToast('Nothing to copy. Minify some HTML first!');
return;
}
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(() => {
window.htmToast('Copied minified HTML to clipboard!');
}).catch(() => fallbackCopy(text));
} else {
fallbackCopy(text);
}
};
function fallbackCopy(text) {
const temp = document.createElement('textarea');
temp.value = text;
temp.style.position = 'fixed';
temp.style.top = '-9999px';
document.body.appendChild(temp);
temp.select();
try {
document.execCommand('copy');
window.htmToast('Copied minified HTML to clipboard!');
} catch (e) {
window.htmToast('Failed to copy');
}
document.body.removeChild(temp);
}
// Download Output File
window.htmDownload = function() {
const content = outputEl.value;
if (!content) {
window.htmToast('Nothing to download');
return;
}
const blob = new Blob([content], { type: 'text/html;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'index.min.html';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
window.htmToast('Downloaded index.min.html');
};
// Handle File Upload
window.htmHandleUpload = function(evt) {
const file = evt.target.files && evt.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
inputEl.value = e.target.result;
window.htmProcessMinify();
window.htmToast(`Uploaded ${file.name}`);
evt.target.value = '';
};
reader.onerror = function() {
window.htmToast('Error reading uploaded file');
};
reader.readAsText(file);
};
// Toggle Live Preview
window.htmTogglePreview = function() {
isPreviewMode = !isPreviewMode;
if (isPreviewMode) {
outputEl.style.display = 'none';
previewFrame.style.display = 'block';
previewLabel.textContent = 'Show Code';
renderIframePreview(outputEl.value);
} else {
outputEl.style.display = 'block';
previewFrame.style.display = 'none';
previewLabel.textContent = 'Live Preview';
}
};
function renderIframePreview(content) {
try {
const doc = previewFrame.contentDocument || previewFrame.contentWindow.document;
doc.open();
doc.write(content || 'No HTML to preview
');
doc.close();
} catch(e) {
console.warn('Preview render warning:', e);
}
}
// Toast Notification System
window.htmToast = function(msg) {
const toast = document.getElementById('htm-toast-box');
toast.textContent = msg;
toast.classList.add('show');
clearTimeout(window.__htmToastTimer);
window.__htmToastTimer = setTimeout(() => {
toast.classList.remove('show');
}, 2400);
};
// Initialize with Landing Page sample
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => window.htmLoadSample('landing'));
} else {
window.htmLoadSample('landing');
}
})();