ما هو ضغط HTML؟
ضغط HTML هو عملية تقليل حجم مستند HTML دون تغيير طريقة عرضه في المتصفح. يقوم ضاغط HTML بإزالة الأحرف الموجودة فقط لتسهيل قراءة المطوّر: المسافات البيضاء بين الوسوم، والتعليقات، وعلامات الإغلاق الاختيارية، وقيم الخصائص الزائدة. الناتج مطابق وظيفياً للمصدر لكنه أصغر حجماً بالبايت، مما يعني تنزيلاً أسرع وزمن ظهور أقصر للمستخدمين.
تُحلّل المتصفحات HTML إلى شجرة DOM وتتجاهل معظم المسافات البيضاء أثناء هذه العملية. تسلسل من المسافات وفواصل الأسطر بين وسمَي div لا يؤثر بصرياً على الصفحة المعروضة. كذلك يتجاهل المحلّل التعليقاتِ. يستفيد الضغط من هذه القواعد بحذف ما سيتجاهله المحلّل على أي حال، حتى لا يُنقل عبر الشبكة أصلاً.
تتفاوت وفورات ضغط HTML حسب المستند. القوالب المشبعة بالتعليقات، والصفحات المُصيَّرة من الخادم بمسافات بادئة عميقة، ومخرجات أنظمة إدارة المحتوى ذات الأنماط المضمّنة غالباً ما ترى انخفاضاً في الحجم بنسبة 15-30% من الضغط وحده. لمستندات صغيرة تكون الوفورات المطلقة متواضعة، لكن في المواقع عالية الحركة حتى بضعة كيلوبايتات لكل طلب صفحة تتراكم لتوفير نطاق ترددي حقيقي عبر ملايين الطلبات.
لماذا تستخدم هذا الضاغط؟
الصق HTML الخاص بك واحصل على الناتج المضغوط فوراً. لا أدوات بناء للتثبيت، ولا ملفات إعداد، ولا حسابات مطلوبة.
حالات استخدام ضاغط HTML
ما الذي يحذفه ضغط HTML؟
يُطبّق ضاغط HTML الكامل عدة تحويلات تتجاوز إزالة المسافات البيضاء. يسرد الجدول أدناه أكثر التقنيات شيوعاً، مُرتَّبة من الأكثر أماناً (بلا خسارة دائماً) إلى الأكثر عدوانية (قد يُفسد حالات حافة عند التطبيق الأعمى).
| التقنية | قبل | بعد |
|---|---|---|
| Whitespace between tags | <div> <p> text </p> </div> | <div><p>text</p></div> |
| HTML comments | <!-- TODO: fix later --> | (removed entirely) |
| Redundant attribute quotes | class="main" | class=main |
| Boolean attribute values | disabled="disabled" | disabled |
| Empty attribute values | id="" | (attribute removed) |
| Optional closing tags | </li>, </td>, </p> | (removed when safe) |
| Type on script/style | type="text/javascript" | (removed — default) |
| Protocol in URLs | https://cdn.example.com | //cdn.example.com |
الضغط النصي مقابل ضغط Gzip
يتساءل المطوّرون أحياناً هل الضغط النصي لا يزال ضرورياً عندما يُطبّق الخادم بالفعل Gzip أو Brotli. الإجابة المختصرة: نعم، وهما يعملان معاً على أفضل وجه.
يُقلّل الضغط النصي المدخلات التي يعالجها Gzip، فيكون الناتج المضغوط أصغر أيضاً. توصي إرشادات PageSpeed من Google بتطبيق كليهما. في صفحة نموذجية، يوفّر الضغط النصي 15-25% من الحجم الخام ويضغط Gzip النتيجة بنسبة 60-80% إضافية. مجتمعَين، قد ينخفض إجمالي حجم النقل إلى 10-20% من المستند الأصلي غير المضغوط.
أمثلة برمجية
فيما يلي أمثلة عملية لضغط HTML في أربع بيئات. كل مثال يحذف التعليقات ويطوي المسافات البيضاء.
import { minify } from 'html-minifier-terser'
const html = `
<div class="card">
<!-- user profile -->
<p> Hello, world! </p>
</div>
`
const result = await minify(html, {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeEmptyAttributes: true,
})
// → '<div class="card"><p>Hello, world!</p></div>'import htmlmin html = """ <div class="card"> <!-- user profile --> <p> Hello, world! </p> </div> """ result = htmlmin.minify(html, remove_comments=True, remove_empty_space=True) # → '<div class="card"><p>Hello, world!</p></div>'
package main
import (
"fmt"
"github.com/tdewolff/minify/v2"
"github.com/tdewolff/minify/v2/html"
)
func main() {
m := minify.New()
m.AddFunc("text/html", html.Minify)
input := `<div class="card">
<!-- user profile -->
<p> Hello, world! </p>
</div>`
result, _ := m.String("text/html", input)
fmt.Println(result)
// → <div class=card><p>Hello, world!</div>
}# Install globally npm install -g html-minifier-terser # Minify a file html-minifier-terser --collapse-whitespace --remove-comments input.html -o output.html # Pipe from stdin cat index.html | html-minifier-terser --collapse-whitespace --remove-comments # With all common optimizations html-minifier-terser \ --collapse-whitespace \ --remove-comments \ --remove-redundant-attributes \ --remove-empty-attributes \ --minify-css true \ --minify-js true \ input.html -o output.min.html