Build Powerful ACF Custom Blocks That Load in Under 300ms
Last Updated: March 25, 2026

This guide shows you how to build custom WordPress blocks using Advanced Custom Fields (ACF) Pro—entirely in PHP—without React. You’ll learn to plan, implement, and optimize ACF blocks that load in under 300ms, follow WordPress standards, and offer seamless backend editing. Includes real code, performance tips, and benchmarks.
ACF custom blocks are a major upgrade for WordPress developers who think in PHP, prefer simplicity, and care about performance. Instead of wrestling with React, JSX, and complex JavaScript build tools, ACF Pro lets you build custom Gutenberg blocks using the tools you already know—PHP, HTML, and smart templating.
Whether you’re running an agency, working on client projects, or maintaining your own high-performance site, ACF blocks let you create reusable, dynamic content components that integrate seamlessly with the WordPress editor. And the best part? You can do it all without ever leaving the PHP world.
This guide is for developers who want their blocks to be fast (we’re talking under 300ms), maintainable, and editor-friendly. You’ll learn how to:
block.json and ACF’s local JSON for speedIf you’re tired of slow blocks, bloated builds, or endless JavaScript configs—this guide will show you a better, faster, and leaner way to build in WordPress.
Let’s dive in.

Advanced Custom Fields Pro enables you to register and render blocks using PHP templates. This allows for faster development cycles, reduced build complexity, and a more familiar experience for backend-focused WordPress developers.
get_field() and have_rows() in templatesadd_action('acf/init', function () {
acf_register_block_type([
'name' => 'testimonial',
'title' => __('Testimonial'),
'render_template' => 'blocks/testimonial/template.php',
'category' => 'formatting',
'icon' => 'format-quote',
'keywords' => ['quote', 'testimonial'],
]);
});block.json| Feature | ACF Custom Blocks | Native WordPress Blocks |
|---|---|---|
| Primary Language | PHP | React + JavaScript |
| Learning Curve | Low (PHP devs) | High (non-React devs) |
| Dev Tools Needed | None | Webpack, Babel, etc. |
| Backend Performance | Fast | Slower for non-React devs |
| Editor Experience | ACF UI | Live inline editing |

Look for content patterns: testimonials, service grids, bios. Identify repeatable structures.
Use tools like PageSpeed Insights or performance.now() in browser dev tools.
/your-theme/
├── /blocks/
│ └── /my-custom-block/
│ ├── block.json
│ ├── template.php
│ └── style.css
└── /acf-json/{
"name": "acf/my-custom-block",
"title": "My Custom Block",
"acf": {
"renderTemplate": "blocks/my-custom-block/template.php"
},
"style": ["file:./style.css"],
"supports": {
"spacing": { "margin": ["top", "bottom"], "padding": true },
"color": { "background": true, "text": true }
}
}function my_register_blocks() {
register_block_type(__DIR__ . '/blocks/my-custom-block');
}
add_action('init', 'my_register_blocks');<?php
$name = get_field('name');
if ($name):
echo '<h2>' . esc_html($name) . '</h2>';
endif;
if (have_rows('features')): ?>
<ul>
<?php while (have_rows('features')): the_row(); ?>
<li><?php the_sub_field('label'); ?></li>
<?php endwhile; ?>
</ul>
<?php endif; ?>esc_html(), esc_attr()Store field group config in /acf-json/ to avoid DB queries.
Use paginated UI if blocks load many repeated fields.
Only enqueue CSS/JS when the block is rendered.
<?php
$start = microtime(true);
// your block render code
$end = microtime(true);
echo "<!-- Rendered in " . ($end - $start) . " seconds -->";
?>| Metric | Target |
| Editor Load Time | < 1s/block |
| Typing Responsiveness | 60fps |
| Time to First Byte (TTFB) | < 200ms |
| Largest Contentful Paint | < 2.5s |
get_field() chains
Understanding the internal flow helps in debugging and optimizing ACF custom blocks:
1. block.json
↓
2. acf_register_block_type()
↓
3. render_template.php (via acf/init)
↓
4. get_field() / have_rows()
↓
5. Escaped and sanitized output (HTML)
↓
6. Editor + Frontend Renderacf/init, registers the block server-side with ACF.$block, $content, $is_preview, and $post_id as variables.post_id or context.esc_html(), esc_attr() before being printed.Yes, ACF custom blocks are exclusive to the Pro version.
Yes, define supports in block.json to enable margin, padding, and color pickers.
As long as ACF Pro is maintained (active since 2011), blocks built with it will remain compatible. Use clear templating and best practices.
Yes. While ACF blocks are PHP-driven, you can enqueue block-specific JS and CSS files conditionally when rendering the block.
Use inline microtime(true) benchmarking in your templates, browser dev tools, or plugins like Query Monitor to measure block rendering speed.
Avoid overloading blocks with deeply nested repeaters or unpaginated media fields. Keep logic clean and avoid unnecessary database calls in templates.

get_field(), block.json, and smart templating.block.json.microtime(true) and audit bottlenecks like nested fields or image queries.ACF custom blocks are a fast, developer-friendly way to build scalable WordPress content systems. With a focus on PHP, modular design, and performance, they offer an excellent alternative to React-based block development.
Start lean. Think modular. Measure everything.
And keep your blocks under 300ms.
Do you like this article? Share it and send us your feedback! Check out our articles page, where you might find other interesting posts. Also, if you want to learn more about business, check out the WPRiders Blog!