I’m working with a customer who sends really long marketing emails. The problem is that MJML generates quite bulky HTML code, and our emails keep getting cut off by Gmail since they exceed the 102kb threshold.
Even after compressing the HTML output, we’re still hitting around 132kb on average. I’m looking for ways to make the generated code smaller.
Are there alternative MJML elements that produce less HTML than <mj-wrapper> and <mj-group>? Or maybe some optimization tricks I’m missing?
The emails need to display properly across Gmail, Yahoo Mail, AOL, and Outlook clients.
So far I’ve tried compressing the final HTML which cuts the size by roughly 30%. I’ve also converted some text sections to image blocks where possible, but I need more solutions.
Those optimization tricks work, but manually tweaking every campaign gets old fast. What if you’re running dozens of templates or managing multiple clients?
I hit this wall when our team ramped up to 3-4 campaigns weekly. Spending entire afternoons optimizing MJML templates was killing productivity.
So I automated the whole thing. Built a workflow that takes raw MJML and runs it through optimization layers automatically.
Step one strips wrapper bloat and consolidates CSS. Step two processes the HTML to kill duplicate styles and compress tables. Step three runs compatibility checks so smaller files still render properly.
It handles dynamic content too - product catalogs get different treatment than static newsletters.
Runs automatically on every deploy, zero manual work. Dropped our average email size from 132kb to 78kb consistently.
You don’t need custom code for this. I use Latenode since it connects MJML processing with HTML minification and email testing in one flow.
switch up ur workflow - preprocess templates b4 MJML compilation insted of optimizing after. strip whitespace and comments 1st, then feed it to the compiler. manually inline ur CSS rther than letting MJML do it auto. u’ll get way more control over repeated code. this approach saved me when everything else failed.
Gmail’s 102kb limit caught me off guard too. Here’s what actually saved me space: Ditch nested <mj-wrapper> elements and go straight to <mj-section> when you can. Wrappers create tons of extra table markup you probably don’t need. Skip <mj-group> for columns. Just use <mj-column> with percentage widths directly - cuts out all that redundant container HTML. Stop repeating styles everywhere. Move your common properties to <mj-attributes> in the head instead of inlining everything. Way less duplicate CSS. Don’t break up text blocks thinking it’ll help. Smaller <mj-text> sections actually make things worse because of extra wrapper markup. Keep text consolidated. When nothing else worked, I split really long emails into a main message plus a ‘read more’ link to the web version. Not great for engagement, but it kept us under the limit without losing content.
Same headaches here. The biggest win for me was fixing MJML’s inline style mess. It repeats font declarations and colors on every element - adds tons of bloat in longer emails. I stopped fighting MJML’s defaults and started using global classes in the head section with css-class attributes instead. Cut about 40% of bloat right there. MJML also spits out pointless align and valign attributes even when they’re already defaults - just strip those with find-replace in your build. I also ditched the long single emails entirely. Now I send shorter focused messages that link to landing pages for full content. Keeps Gmail users under 102kb, loads faster, and engagement actually went up because people aren’t overwhelmed.
I switched to <mj-raw> for sections that don’t need responsive behavior. Yeah, writing plain HTML tables sounds scary, but it creates way leaner code than MJML’s bloated markup. Headers and footers especially - this saves tons of space.
Consolidating media queries helped a lot too. MJML creates separate breakpoints for every single component, but you can override this with custom CSS classes applied strategically. Cuts out massive amounts of duplicate responsive code.
<mj-spacer> elements are incredibly wasteful. Skip the spacers and use padding/margin attributes directly on containers instead. Way more efficient.
Here’s something that surprised me - replace <mj-image> with background images on <mj-section> elements when you can. Background images don’t generate the same heavy HTML structure as image tags, especially when you don’t need alt text or links.
One thing though - some email clients actually handle slightly larger but well-structured HTML better than tiny messy code. Test thoroughly before you go crazy with optimization.
Been fighting this exact problem for months with our marketing campaigns. Gmail’s 102kb limit is absolutely brutal for complex layouts.
The real issue isn’t just MJML bloat - it’s the entire email workflow. You could spend weeks manually optimizing each template, but that doesn’t scale.
I built an automated pipeline that handles multiple optimization steps. First, it processes MJML compilation with custom minification rules. Then it runs CSS inlining optimization to remove duplicate styles. After that, it applies smart image compression and converts repetitive HTML patterns into compact structures.
The key is conditional logic that applies different strategies based on content type. Text-heavy newsletters get HTML structure optimization. Product catalogs get image handling and lazy loading fallbacks.
I also set up automatic A/B testing to compare file sizes and deliverability across different email clients. This catches compatibility issues before emails go out.
You can build this workflow without custom code using automation tools. I’ve been using Latenode for email optimization pipelines because it handles MJML processing, HTML minification, and client testing in one flow.