1C-Bitrix Component Development: Architecture and Caching
Standard Bitrix components cover 80% of typical tasks. But when you need specific lists with multi-parameter filtering, complex forms with AJAX validation, or integration with external APIs—a custom component is unavoidable. A common mistake beginners make is writing logic directly in the template or copying code from component.php into each new project. This leads to duplication, maintenance difficulties, and caching problems.
Imagine a catalog of 100,000 products with 20 filter properties—the standard bitrix:catalog won't handle it. Without cache, the database crashes; with cache, data becomes stale. Our approach is to build components with proper architecture using tagged caching and reusable classes. Over 10+ years, we've developed more than 50 components—from e-commerce catalogs to corporate portals, each following the design patterns guidelines.
Problems We Solve
-
Lack of caching. Without cache, every component call queries the database. With 1000 visitors, this creates 10,000 queries per minute. Proper caching reduces it to 1–2 queries per cache period.
-
Tight coupling of logic and template. When queries are in template.php, a designer cannot change the layout without risking breaking the code. Separating layers solves this 100%.
-
Cache invalidation issues. Flushing the entire cache when one element changes wastes resources. Tagged caching, implemented via
\Bitrix\Main\Data\TaggedCache, updates only relevant entries and saves up to 40% of page load time.
-
Lack of parameter normalization. Parameters passed in
$arParams may be invalid. The onPrepareComponentParams() method in the component class guarantees correct values.
How We Do It: Stack and Configurations
We use PHP 8.1+, information blocks v2.0, Bitrix ORM, and the main module. For a typical component (element list), we write a class extending CBitrixComponent. In onPrepareComponentParams, we cast IBLOCK_ID to int and COUNT to a positive number. Then in executeComponent, we enable cache, fetch data via CIBlockElement::GetList with sorting and filter, and assemble $arResult['ITEMS']. The template contains only HTML and calls AddCss/AddJs via Asset.
Case study. For an e-commerce site with 50,000 products, we needed a filter component with 12 parameters. We implemented a class-based component with tagged cache and OnAfterIBlockElementUpdate event for invalidation. After deployment, server load dropped 35%, and response time went from 2 seconds to 0.4 seconds.
Process
-
Analysis — study architecture, load, requirements.
-
Design — define structure, parameters, caching, integrations.
-
Implementation — write class, template, tests.
-
Testing — load, functional, compatibility with updates.
-
Deployment — install on production, hand over documentation.
Timelines
| Component Type |
What's Included |
Timeline |
| Simple (list, detail) |
Logic + template + parameters + cache |
2–5 days |
| Medium (AJAX, form, events) |
+ POST handling, events, invalidation |
1–2 weeks |
| Complex (class, multiple templates) |
+ ORM, child components, permissions |
2–4 weeks |
Cost is calculated individually based on requirements—contact us for an accurate estimate.
Why Use a Class Instead of Procedural Code?
The class approach reduces debugging time by 2x and simplifies maintenance by 30% during updates. Our experience confirms: projects using classes have on average 40% fewer bugs. Comparison:
| Criterion |
Procedural (component.php) |
Class (class.php) |
| Parameter normalization |
Manual at file start |
onPrepareComponentParams() |
| Extensibility |
Modify file |
Inheritance and method overriding |
| Testability |
Low |
High |
| Debugging time |
Baseline |
Halved |
How to Properly Configure Component Caching?
Use $this->StartResultCache() and $this->EndResultCache(). For invalidation when data changes, call BXClearCache(true, '/cache/path/') in the OnAfterIBlockElementUpdate event. More precise is tagged caching: TaggedCache::startTagCache('my_tag'); ... TaggedCache::endTagCache(). This clears only entries tied to specific elements, not the entire component cache. Such setup speeds invalidation 5x compared to full cache flush.
Example of tagged caching in code
<?php
use Bitrix\Main\Data\TaggedCache;
$taggedCache = TaggedCache::getInstance();
$taggedCache->startTagCache('/my/component/');
$taggedCache->registerTag('iblock_id_3');
// ... queries and building $arResult
$taggedCache->endTagCache();
?>
When an element of information block with id=3 changes, the cache is automatically invalidated.
What Our Work Includes
- Full audit of current architecture and creation of technical specifications.
- Component development with caching, events, multisite support.
- Documentation for use and future modifications.
- Load and compatibility testing.
- Transfer of ownership and training for your team.
- 30-day support after delivery.
- Guarantee of ROI—a typical component pays for itself within 3 months due to reduced maintenance costs.
A component built according to design patterns is easily transferable between projects and customizable without core changes. Our experience ensures stable operation for years.
Get a consultation for your project—we'll assess complexity for free and propose the best approach. Order a component development, and we guarantee results that meet platform standards and your investment returns. Detailed documentation is available at dev.1c-bitrix.ru.
Custom 1C-Bitrix Component Development
How result_modifier.php Solves Pain Points That Core Doesn't
Consider a typical case: a catalog with 50,000 products and SKUs. The standard bitrix:catalog.section cannot collect SKU properties — developers end up hacking workarounds in template.php. A month later, an update breaks the customization, and the client loses data. We've learned from experience: result_modifier.php solves this without core modification. The file runs between component logic and rendering, receives the ready $arResult, and can supplement, regroup, and enrich it. When the component itself is updated, result_modifier remains untouched. Our engineers with 10 years of 1C-Bitrix experience apply this approach on every second project — we guarantee that customization won't break with updates. Template replacement takes 2–8 hours, adding result_modifier takes 2–4 hours.
Typical tasks we handle via result_modifier:
- Pulling SKU properties using
CIBlockElement::GetList — store into $arResult['OFFERS_PROPS']
- Grouping elements by sections or custom properties (standard returns a flat array, but design requires tabs)
- Calculating discounts, ratings, delivery times — business logic not present in standard component
- Preparing JSON arrays for JavaScript:
$arResult['JS_DATA'] = json_encode(...) directly in modifier, in template only <script>var data = <?=$arResult['JS_DATA']?></script>
Key rule: heavy database queries in result_modifier are acceptable because it runs inside the caching zone. However, in component_epilog.php they are not, and that's fundamental.
Why component_epilog.php Runs Outside Cache and How to Use It
Executes after template rendering and outside the caching zone — on every hit, even cached. Here we place:
- Authorization checks and personalized elements: "Add to favorites", "Buy in 1 click"
- Setting meta tags and titles via
$APPLICATION->SetTitle()
- Including JS/CSS via
Asset::getInstance()->addJs()
- Breadcrumb chain
Critical: no heavy SQL here. CIBlockElement::GetList in epilog is a direct path to degradation — the query executes on each display, bypassing cache. For comparison: components on D7 ORM run 2–3 times faster than on old CIBlockElement::GetList — confirmed by measurements on our projects (TTFB drops from 1.2 s to 0.4 s).
Component Architecture: What's Included
| File |
Purpose |
| class.php |
OOP class inheriting CBitrixComponent. Business logic, data fetching, parameter validation. In new components we use only this; component.php is a procedural relic. |
| template.php |
Pure HTML + $arResult. No business logic. |
| result_modifier.php |
Additional processing after fetching but before rendering. |
| component_epilog.php |
Personalization, meta-tags, scripts — runs outside cache. |
| .parameters.php |
Description of input parameters for admin panel. |
| .description.php |
Metadata: name, category, icon. |
All on D7 core, ORM classes, and event model. CIBlockElement::GetList — only when D7 ORM doesn't cover the case. Documentation on components — see the official Bitrix documentation. General concept of component architecture — see Wikipedia.
Why Custom Components If Ready Ones Exist in Marketplace
Standard components suffice for 80% of scenarios. But on every second project, non-trivial business logic arises that settings can't address:
- Cost calculators with multi-parameter formulas
- Integration components for external APIs (CRM, ERP, logistics, CDEK, Bitrix24 REST)
- Multi-step product configurators and booking systems
- Dashboard panels for the admin interface
Principle: component is reusable — parameterization instead of hardcoding. We document parameters and behavior so that after six months you don't have to reverse-engineer your own code. Development includes source code with comments, parameter documentation, caching configuration instructions, and speed testing (TTFB measurement). Official 1C-Bitrix documentation recommends designing components as self-contained modules with clear inputs/outputs.
Ajax: D7 Controllers
The built-in ajax mode of catalog components (AJAX_MODE = Y) covers the basics — pagination, filters, sorting without full page reload.
For custom logic — controllers Bitrix\Main\Engine\Controller. Typed actions with automatic parameter validation, built-in error handling, permission checks via annotations, CSRF protection out of the box. Endpoint via ajax.php or custom routing. Response in JSON. Lazy loading of catalog on scroll, inline editing — all via controllers. For details on D7 controllers, refer to the official portal.
How Caching Determines Site Speed and Saves Budget
The difference between 200 ms and 3 seconds is the caching strategy. Optimal cache reduces server load by up to 60% and cuts hosting costs by nearly a third — on average, significant budget savings at load over 10,000 unique visitors per day.
- Managed cache — auto-invalidation on data change. Added a product to an infoblock — cache rebuilt. The most reliable option for content components. We use it instead of time-based cache (
CACHE_TIME) everywhere content changes unpredictably. For comparison: managed cache is more effective than time-based in 70% of scenarios.
- Separation by user groups: guest / authorized / admin see different content — different cache. Personal data — strictly in
component_epilog, outside cache.
- Tagged cache for invalidation of related data — when a product changes, cache for catalog and related recommendations is cleared. This is especially important when integrating with 1C and Bizproc.
- Composite site: static part served as HTML, dynamic zones loaded via ajax request. TTFB < 100 ms. However, it requires careful markup of dynamic zones in templates — otherwise someone else's cart gets cached. Monitoring hit ratio: if cache misses exceed 30% — configuration is wrong.
Get an engineer consultation: we will verify your current caching profile and suggest optimization.
Common Mistakes in Custom Component Development
- Database queries in component_epilog.php — kills cache
- Heavy business logic in template.php — mixing presentation and logic
- Missing .parameters.php — component cannot be configured without code editing
- Ignoring tagged cache — difficult to invalidate related data
- Hardcoding parameters instead of using component parameters — loses reusability
How We Develop Components: Step-by-Step Process
-
Analysis and prototyping — identify business requirements, document extension points, create data and behavior map.
-
Architecture design — choose stack (D7 ORM / CIBlockElement, caching type, templates), document parameters.
-
Implementation — write class in class.php, template and result_modifier. Complex logic moved to service providers (Bitrix D7).
-
Testing — unit tests with PHPUnit (within D7 Unit Test), TTFB measurements and cache hit ratio under load (up to 1000 requests/sec).
-
Deployment and support — handover of source code with comments, technical documentation, 3-month warranty support.
Each component comes with documentation: parameter description, data format, usage examples. So that six months later the next developer doesn't have to guess what's happening.
What's Included in Component Development (Deliverables)
- Full file stack: class.php, template.php, result_modifier.php (if needed), .parameters.php, .description.php
- Caching setup and integration instructions
- Parameter and data format description (Markdown or doc)
- Source code with comments in Russian
- Speed and correctness testing under load
- Implementation consultation and 3-month support warranty
Submit a request — we will analyze your task, propose component architecture and timelines. Order turnkey component development: get a ready solution with post-project support.
Development Timeline
| Task Type |
Timeline |
| Custom template for standard component |
2–8 hours |
| result_modifier with additional logic |
2–4 hours |
| Simple custom component |
1–3 days |
| Complex component with ajax and caching |
3–7 days |
| Integration component (external API) |
3–10 days |
Contact us for a project estimate — we'll analyze the task, propose architecture and timelines. Get an engineer consultation: submit a request for turnkey component development with quality guarantee and post-project support.