- Jampack là một công cụ hậu xử lý nhận đầu ra của Static Site Generator để tối ưu hóa trải nghiệm người dùng và điểm số Core Web Vitals, chứ không phải bundler hay framework
- Tự động chuyển
<img> và <picture> trong HTML thành ảnh responsive, đồng thời thêm các định dạng như WebP·AVIF, srcset, sizes, width, height, loading="lazy", decoding="async"...
- Ảnh CDN có thể được xử lý responsive bằng
srcset dựa trên tham số URL, còn ảnh bên ngoài có thể được tải xuống dưới _jampack để chuyển thành ảnh cục bộ đã tối ưu hóa
- Tài nguyên above-the-fold được xử lý với mức ưu tiên cao, ảnh nhỏ được inline vào HTML, còn ảnh và iframe below-the-fold thì được lazy load
- Áp dụng bằng cách chạy
npx @divriots/jampack ./dist trên thư mục kết quả build của site tĩnh, và thực hiện nén CSS·JS·HTML·SVG·ảnh ở pass thứ hai
Vai trò của Jampack
- Jampack nhận đầu ra do Static Site Generator, tức SSG, tạo ra làm đầu vào và tối ưu hóa website tĩnh
- Mục tiêu là cải thiện trải nghiệm người dùng và điểm số Core Web Vitals
- README phân biệt Jampack là “không phải bundler cũng không phải framework”
- Bài giới thiệu có tại Read the introduction blog post
Tối ưu hóa hình ảnh
<img> thông thường sẽ được chuyển thành ảnh responsive
- Tạo file WebP cho
src gốc và thêm srcset
- Thêm các thuộc tính như
sizes="100vw", loading="lazy", decoding="async", width, height
- Phần tử
<picture> được chuyển thành cấu trúc responsive bao gồm nhiều định dạng ảnh
- Thêm
<source type="image/avif"> cho AVIF
- Thêm
<source type="image/webp"> cho WebP
- Ở
<img> gốc cũng có srcset, sizes, loading, decoding, width, height
- Tính năng tối ưu hóa ảnh được dẫn tiếp tới tài liệu
optimize-images, nhưng liên kết tương ứng trong README là đường dẫn tương đối
Xử lý ảnh CDN và ảnh bên ngoài
- Ảnh CDN có thể giữ nguyên URL từ xa nhưng vẫn thêm
srcset responsive
- Ví dụ tạo nhiều ứng viên theo độ rộng bằng cách gắn các tham số
w, fit=min, auto=format vào URL ảnh Unsplash
- Ảnh gốc cũng được thêm
loading="lazy", decoding="async", sizes="100vw"
- Ảnh bên ngoài có thể được tải xuống rồi chuyển thành file cục bộ đã tối ưu hóa
- Ví dụ chuyển ảnh Unsplash bên ngoài thành đường dẫn như
_jampack/ab99b9d280ce4cf7cfc810b59f3a7739.jpg.webp
- Ảnh đã chuyển đổi bao gồm
width, height, srcset, sizes, loading, decoding
Above-the-fold và tối ưu hóa CSS·liên kết
- Jampack tối ưu riêng các tài nguyên above-the-fold
- Ảnh được tải với mức ưu tiên cao hơn
- Ảnh nhỏ được nhúng vào HTML
- Tài nguyên below-the-fold được lazy load
- Ảnh và iframe là đối tượng áp dụng lazy load
- Critical CSS được inline vào HTML
- Mục đích là tránh FOUC có thể xảy ra trong lúc tải và parse stylesheet
- Phần CSS còn lại sẽ được lazy load
- Prefetch liên kết là tính năng để tăng tốc cho lần chuyển trang tiếp theo
- Có thể xử lý động khi liên kết đi vào viewport bằng quicklink
Nén tài nguyên và cách chạy
- Jampack nén mọi tài nguyên chưa bị đụng tới trong pass thứ hai, đồng thời giữ nguyên tên và định dạng
- Các công cụ nén theo phần mở rộng gồm:
- Khi website tĩnh nằm trong thư mục
dist, chạy bằng lệnh sau
npx @divriots/jampack ./dist
Trường hợp sử dụng và ý nghĩa tên gọi
1 bình luận
Các ý kiến trên Hacker News
Đúng là công cụ tôi đang tìm. Trước đây tôi tự viết script dựa trên Sharp để làm kiểu tối ưu hóa hình ảnh này, nhưng Jampack thay thế hoàn toàn việc đó và hoạt động tốt hơn nhiều
Sau khi build site tĩnh Quarto rồi chạy Jampack, kích thước thư mục giảm 32%, và hiện chưa thấy nhược điểm đáng chú ý nào
Theo PageSpeed Insights, trước Jampack thì trên mobile: hiệu năng 52, khả năng truy cập 73, best practices 100, SEO 85; còn desktop: hiệu năng 90, khả năng truy cập 75, best practices 100, SEO 82
Sau khi áp dụng, kết quả là mobile: hiệu năng 49, khả năng truy cập 80, best practices 100, SEO 92; desktop: hiệu năng 85, khả năng truy cập 82, best practices 100, SEO 91
Cũng có tài liệu nói rằng “trung vị điểm Lighthouse của 5 lần chạy ổn định gấp đôi so với 1 lần chạy”: https://developers.google.com/web/tools/lighthouse/variabili...
georges [at] divriots [dot] com
Làm tôi nhớ đến module PageSpeed cho Apache và Nginx: https://developers.google.com/speed/pagespeed/module
Repo GitHub cũng đã được lưu trữ: https://github.com/apache/incubator-pagespeed-ngx
Hay nó đã được chuyển sang nơi khác?
Chà, cái này khá đúng ý tôi. Tôi sẽ dùng thử
Nếu có ai thấy nó không ổn, mong chỉ ra các khiếm khuyết. Với tôi nó trông giống như biên dịch C thành assembly tối ưu cực cao, và có vẻ là công cụ làm thay rất chắc những việc tôi không muốn tự làm
Theo tôi, nếu viết HTML và CSS đơn giản, trực quan nhất thì trình duyệt trên mọi thiết bị nên cứ render tốt
Nếu thật sự phải triển khai sản phẩm tối ưu ở mức đó, có lẽ tốt hơn là bỏ qua hẳn HTML và CSS, triển khai WebAssembly được tối ưu cao rồi để developer dùng ngôn ngữ họ muốn
Sẽ hay nếu có cách subset font dựa trên phạm vi Unicode trong output của SSG, và cố định các trục OpenType dựa trên font-feature-settings được định nghĩa trong CSS
Tôi không rõ đó có phải là “cố định trục OpenType dựa trên font-feature-settings” mà bạn nói không, hay bạn có ý khác
Tôi cũng muốn tối ưu subset font, nhưng chưa rõ mức cải thiện sẽ lớn đến đâu. Không biết bạn từng làm thủ công việc này chưa
Khái niệm xác định CSS quan trọng cần inline thay vì để trong stylesheet riêng khá thú vị
Tôi đã kỳ vọng có cách phân biệt CSS quan trọng và không quan trọng một cách nguyên tắc. Ví dụ các hiệu ứng tương tác người dùng như
:hoverthì luôn xem là không quan trọngNhưng thư viện được dùng lại render trang rồi ước đoán tốt nhất xem quy tắc nào có thể được coi là quan trọng, nên hơi tiếc: https://github.com/GoogleChromeLabs/critters
Tất nhiên nếu inline cả font thì tôi hiểu, nhưng nếu chỉ phần style khác mà vượt 50KB thì đa phần là đi sai hướng
Nói nghiêm túc, inline cực kỳ có lợi cho hiệu năng ngay cả khi so với cache ấm, và ngưỡng để stylesheet hoặc script bên ngoài bắt đầu tốt hơn cao hơn bạn nghĩ, trong các điều kiện thị trường phổ biến có khi lên tới vài trăm KB
Khái niệm CSS quan trọng có cảm giác như một cách tiếp cận mang tính chủ bại, cố lấy lại một chút hiệu năng đã lãng phí thay vì sửa vấn đề gốc
Tuy vậy đây không phải là kỹ thuật có hệ thống, mà là phán đoán dựa trên ít kinh nghiệm và quan sát. Tôi mong ai đó đo lường khái niệm này tử tế hơn, nhưng chắc người đó không phải tôi
Cái này có vẻ bao phủ nhiều mục đích mà ngay từ đầu mọi người chọn SSG và plugin để làm. Đặc biệt nếu họ chọn Astro hoặc Eleventy thì càng đúng
Có lý do nào để thích đặt nó thành một bước riêng sau build không? Rebuild trong lúc phát triển sẽ nhanh hơn, nhưng trông như một đánh đổi với khả năng bỏ sót những bug tinh vi phát sinh khi thêm các khai báo như width cho ảnh
Với người ghét làm layout web và cũng không chịu học, nhưng thỉnh thoảng vẫn phải làm như tôi, công cụ này trông rất tuyệt
Trông ổn. Tuy nhiên cá nhân tôi không thích việc phải chờ ảnh khi cuộn trang xuống dưới màn hình đầu tiên
Theo mặc định, sau khi nội dung màn hình đầu kết thúc, các nội dung còn lại phía dưới có được tải trong nền không?
loading="lazy"với nghĩa là “đừng tải ảnh/iframe này cho đến khi nó gần xuất hiện”: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/im...Tuy nhiên tỷ lệ khung hình được chèn inline, nên layout sẽ không thay đổi sau khi tải xong. Nói cách khác, tránh được tội lỗi lớn nhất của lazy loading
loading="lazy"native của trình duyệtHiện chưa có cách thay đổi hành vi này, nhưng có thể thêm tùy chọn preload ảnh dưới màn hình đầu trong nền sau khi toàn bộ trang đã load. Ý tưởng khá hay
Dù vậy tôi lo nó sẽ tải cả những ảnh không cần thiết ở cuối trang. Nếu là tùy chọn thì mỗi người có thể bật hoặc tắt, nên có vẻ ổn
Có những static site generator nào đang được dùng trong môi trường production? Có vẻ công cụ này có thể tối ưu output của chúng tốt hơn
Ví dụ hôm qua tôi mất cả ngày làm theo ví dụ để chuyển website React của Divjoy thành HTML đơn giản và phục vụ từ S3 bucket. Tôi không ngờ lại khó đến vậy và giờ vẫn còn loay hoay
Lý tưởng là có thứ gì đó tự động deploy lên S3 bucket và nối luôn domain. Đau ở chỗ tôi đã trả tiền mà developer biến mất, Discord cũng bị bỏ mặc. Vì vậy tôi luôn thích FOSS hơn
Ở một mức độ nào đó, chúng có một phần các chức năng như vậy
Với một dự án của tôi thì không có thay đổi lớn. Ví dụ tổng kích thước bundle giảm, nhưng kích thước gzip lại tăng, nên thực tế là tôi bị lỗ ròng
Dù vậy phần cải thiện CSS có vẻ thật sự hữu ích
Ý tưởng trông rất hay, và nếu dự án có hình ảnh thì có lẽ đã có ích
Bạn có thể tắt tính năng này bằng cách đặt browserlist thành chuỗi rỗng: https://jampack.divriots.com/features/browser-compatibility/