How being lazy became the ultimate performance optimization
The Performance Paradox
We’ve spent decades optimizing JavaScript frameworks. Virtual DOM diffing algorithms. Fiber architecture. Concurrent rendering. Time slicing. Incremental updates. Compiler optimizations.
But what if the fastest way to run code is… not to run it?
Welcome to Juris’s philosophy: Maximum laziness, maximum performance.
The Great Performance Lie
Modern frameworks brag about their optimization:
// React: "We're fast because we diff efficiently!"
function TodoList({ todos }) {
// Runs on EVERY render
const sortedTodos = todos.sort((a, b) => a.priority - b.priority);
const filteredTodos = sortedTodos.filter(t => !t.completed);
const enrichedTodos = filteredTodos.map(t => ({
...t,
timeAgo: calculateTimeAgo(t.created)
}));
// Even if we're only showing 10 of 1000 todos
return enrichedTodos.slice(0, 10).map(todo =>
<TodoItem key={todo.id} {...todo} />
);
}
// Processed 1000 items to show 10. "Optimized" 🙄
Juris says: Why run any of that?
// Juris: "We're fast because we don't run code"
{
div: {
children: () => {
// Only runs if this div is actually rendered
const todos = getState('todos');
// Only process what we'll show
return todos.slice(0, 10).map(todo => ({
TodoItem: {
// Only calculates if THIS todo is visible
timeAgo: () => calculateTimeAgo(todo.created)
}
}));
}
}
}
// Processed 10 items to show 10. Actually optimized ✨
The Lazy Manifesto
Rule #1: Don’t Calculate Until Asked
Traditional (Eager):
class Component {
constructor() {
// Calculate everything upfront
this.expensiveValue = this.calculateExpensive();
this.derivedState = this.deriveState();
this.formattedData = this.formatData();
}
render() {
// Maybe use 10% of what we calculated
return this.isSimpleView ?
<div>Simple</div> :
<div>{this.expensiveValue}</div>;
}
}
Juris (Lazy):
{
div: {
children: () => getState('isSimpleView') ?
{div: {text: 'Simple'}} :
{div: {
// Only NOW do we calculate
text: () => calculateExpensive()
}}
}
}
Rule #2: Don’t Subscribe Until Rendered
The Subscription Problem:
// React: Every component subscribes to everything it MIGHT need
function Dashboard() {
const user = useSelector(state => state.user);
const metrics = useSelector(state => state.metrics);
const notifications = useSelector(state => state.notifications);
const settings = useSelector(state => state.settings);
// Even if current view only shows user name
return <div>{user.name}</div>;
}
// 4 subscriptions, 1 used
The Juris Solution:
{
div: {
// Only subscribes to 'user.name', nothing else
text: () => getState('user.name')
// These don't create subscriptions until needed
// children: () => getState('showMetrics') ? {MetricsPanel: {}} : null
}
}
// 1 subscription, 1 used
Rule #3: Don’t Update What’s Not Visible
The Hidden Cost of Hidden Elements:
// Traditional: Updates even hidden elements
function AnimatedChart({ data }) {
const [frame, setFrame] = useState(0);
useEffect(() => {
// Runs even when chart is display:none
const interval = setInterval(() => {
setFrame(f => f + 1);
}, 16);
return () => clearInterval(interval);
}, []);
return (
<div style={{ display: visible ? 'block' : 'none' }}>
<ExpensiveChart frame={frame} data={data} />
</div>
);
}
// CPU spinning for invisible chart 🔥
Juris: If it’s not visible, it doesn’t exist:
{
div: {
children: () => getState('visible') ? {
// Animation only starts when visible
ExpensiveChart: {
frame: () => getAnimationFrame(), // Only subscribes when mounted
data: () => getState('data')
}
} : null
}
}
// Hidden = Zero CPU usage
Real World Performance Gains
Scenario 1: Large Table with Expandable Rows
Traditional Approach:
// React: Pre-calculate everything
function DataTable({ rows }) {
// Process ALL rows upfront
const processedRows = rows.map(row => ({
...row,
details: fetchRowDetails(row.id), // 1000 API calls
computed: calculateMetrics(row), // 1000 calculations
formatted: formatCurrency(row.value) // 1000 formats
}));
return processedRows.map(row => (
<Row
key={row.id}
data={row}
expanded={expandedRows.includes(row.id)}
/>
));
}
// Time: 5000ms to render, even though 0 rows are expanded
Juris Approach:
{
table: {
children: () => getState('rows').map(row => ({
Row: {
summary: row.name, // Always visible
details: () => getState(`expanded.${row.id}`) ? {
// Only fetch/calculate if THIS row is expanded
div: {
children: [
{span: {text: () => fetchRowDetails(row.id)}},
{span: {text: () => calculateMetrics(row)}},
{span: {text: () => formatCurrency(row.value)}}
]
}
} : null
}
}))
}
}
// Time: 50ms to render, fetch/calculate only when expanded
Result: 100x faster initial render
Scenario 2: Multi-Tab Interface
Traditional:
// All tabs render, then hidden with CSS
function TabPanel() {
return (
<>
<Dashboard style={{ display: tab === 'dashboard' ? 'block' : 'none' }} />
<Analytics style={{ display: tab === 'analytics' ? 'block' : 'none' }} />
<Settings style={{ display: tab === 'settings' ? 'block' : 'none' }} />
<Reports style={{ display: tab === 'reports' ? 'block' : 'none' }} />
</>
);
}
// All 4 tabs initialized, subscribed, and updating
// Even though only 1 is visible
Juris:
{
div: {
children: () => {
switch(getState('tab')) {
case 'dashboard': return {Dashboard: {}};
case 'analytics': return {Analytics: {}};
case 'settings': return {Settings: {}};
case 'reports': return {Reports: {}};
}
}
}
}
// Only active tab exists in DOM
// Others have zero cost
Result: 75% less memory, 75% fewer subscriptions
Scenario 3: Infinite Scroll with 10,000 Items
Traditional:
// React with virtualization library
import { VirtualList } from 'react-virtual';
function InfiniteList({ items }) {
// Still processes all items for measurements
const rowHeights = items.map(calculateHeight);
const totalHeight = rowHeights.reduce((a, b) => a + b);
return (
<VirtualList
height={600}
itemCount={items.length}
itemSize={index => rowHeights[index]}
renderItem={({ index, style }) => (
<Item style={style} data={items[index]} />
)}
/>
);
}
// Complex virtualization logic running constantly
Juris:
{
div: {
onscroll: (e) => setState('scrollTop', e.target.scrollTop),
children: () => {
const scrollTop = getState('scrollTop', 0);
const startIdx = Math.floor(scrollTop / 50);
const endIdx = startIdx + 20;
// Only create DOM for visible items
return getState('items')
.slice(startIdx, endIdx)
.map(item => ({
div: {
style: {height: '50px'},
text: () => item.name // Lazy even here
}
}));
}
}
}
// No virtualization library, just lazy rendering
Result: 10KB vs 100KB of code, same performance
The Benchmark That Shocked Everyone
// Test: Render dashboard with 1000 widgets, show only 10
// React + Redux + Reselect + React.memo
// Time: 847ms
// Memory: 45MB
// Subscriptions: 1000
// Bundle size: 250KB
// Vue 3 with Composition API
// Time: 623ms
// Memory: 38MB
// Watchers: ~500
// Bundle size: 180KB
// Juris
// Time: 34ms
// Memory: 8MB
// Subscriptions: 10 (only visible widgets)
// Bundle size: 45KB
// Why? Juris only created 10 widgets. Others created 1000 and hid 990.
The Lazy Loading Revolution
Traditional Lazy Loading:
// "Lazy loading" that's not actually lazy
const Dashboard = lazy(() => import('./Dashboard'));
// But once loaded:
function Dashboard() {
// Everything runs immediately
const data1 = useExpensiveHook1(); // Runs
const data2 = useExpensiveHook2(); // Runs
const data3 = useExpensiveHook3(); // Runs
return showSimple ? <Simple /> : <Complex data={data1} />;
}
Juris Lazy Loading:
{
Dashboard: {
// Component loads lazy
component: () => import('./Dashboard'),
// Props calculate lazy
props: {
data: () => getState('dashboardData'),
// Even async props are lazy
metrics: () => getState('showMetrics') ?
fetch('/api/metrics') :
null // No fetch if not needed
}
}
}
The Philosophy in Practice
“Render Only What You See”
// Virtual scrolling without a library
{
div: {
style: {overflow: 'auto', height: '400px'},
children: () => {
const visible = getVisibleRange(); // Calculate once
return getState('items')
.slice(visible.start, visible.end) // Only visible
.map(item => ({div: {text: item}})); // Only these render
}
}
}
“Calculate Only What You Use”
{
div: {
// Expensive calculation only if result is shown
children: () => getState('showStats') ? {
StatsPanel: {
average: () => calculateAverage(getState('data')),
median: () => calculateMedian(getState('data')),
stdDev: () => calculateStdDev(getState('data'))
}
} : {
div: {text: 'Stats hidden'} // Zero calculations
}
}
}
“Subscribe Only to What Changed”
// Surgical updates
setState('users.123.name', 'New Name');
// Only components using users.123.name update
// Not users.124, not users.123.email, just users.123.name
// Traditional would re-render all users
setUsers(users.map(u => u.id === 123 ? {...u, name: 'New Name'} : u));
// Every user component re-renders and diffs
The Counter-Intuitive Truth
We spent years optimizing the wrong thing:
- Faster diffing algorithms → Juris doesn’t diff
- Better reconciliation → Juris doesn’t reconcile
- Optimized re-renders → Juris doesn’t re-render
- Memoization everywhere → Juris doesn’t need it
The fastest optimization is elimination.
The Lazy Developer’s Paradise
// You don't need to think about optimization
{
App: {
// Write naturally, get performance automatically
children: [
{Header: {}},
() => getState('user') ? {UserPanel: {}} : {LoginForm: {}},
{MainContent: {
// Nested laziness
children: () => getState('page') === 'home' ?
{HomePage: {}} :
{OtherPage: {}}
}},
{Footer: {}}
]
}
}
// No useMemo
// No useCallback
// No React.memo
// No computed
// No watchers
// Just lazy by default
Conclusion: The Zen of Laziness
Juris proves a fundamental truth: The fastest code is the code that doesn’t run.
While other frameworks optimize how fast they can run everything, Juris optimizes how much it can avoid running.
This isn’t just a performance optimization. It’s a philosophy:
- Don’t fetch until needed
- Don’t calculate until used
- Don’t render until visible
- Don’t subscribe until relevant
- Don’t update until changed
In a world where frameworks compete on who can run code faster, Juris wins by not running code at all.
Be lazy. Be fast. Be Juris.
Benchmark your own app: Replace your framework with Juris and watch your CPU thank you.
Zero build tools. Zero virtual DOM. Zero unnecessary code execution.
Maximum laziness. Maximum performance.
Leave a Reply