惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
Y
Y Combinator Blog
Cisco Talos Blog
Cisco Talos Blog
T
Threatpost
T
Tor Project blog
I
Intezer
T
Threat Research - Cisco Blogs
L
LINUX DO - 热门话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
Lohrmann on Cybersecurity
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Last Watchdog
The Last Watchdog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Privacy & Cybersecurity Law Blog
N
News | PayPal Newsroom
N
News and Events Feed by Topic
C
CERT Recently Published Vulnerability Notes
T
Tenable Blog
K
Kaspersky official blog
V
Visual Studio Blog
T
Troy Hunt's Blog
Project Zero
Project Zero
博客园_首页
The Register - Security
The Register - Security
O
OpenAI News
G
Google Developers Blog
Simon Willison's Weblog
Simon Willison's Weblog
J
Java Code Geeks
D
DataBreaches.Net
F
Full Disclosure
Latest news
Latest news
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Security Affairs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
腾讯CDC
有赞技术团队
有赞技术团队
Hacker News - Newest:
Hacker News - Newest: "LLM"
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs
Vercel News
Vercel News
V
Vulnerabilities – Threatpost
月光博客
月光博客
Hacker News: Ask HN
Hacker News: Ask HN
B
Blog RSS Feed
P
Palo Alto Networks Blog
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
G
GRAHAM CLULEY

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
I Spent Six Months Chasing Core Web Vitals. Here’s What Actually Moved the Needle.
Shudhanshu R · 2026-04-28 · via DEV Community

I Spent Six Months Chasing Core Web Vitals. Here's What Actually Moved the Needle.

A field guide to LCP, INP, and CLS that skips the theory and gets to what breaks in production.


Our dashboard said green. Our users said otherwise.

For the better part of a year, we shipped features, ran Lighthouse locally, watched scores float between 92 and 98, and patted ourselves on the back. Then one Monday morning, support pinged us: a product manager testing on her own phone swore the listing page felt "stuck" for a second every time she tapped a filter. She wasn't wrong. She just wasn't in our lab.

That was the moment I learned the most important thing about Core Web Vitals: the number in your terminal is not the number Google cares about. Google cares about what happens to real users, on real devices, on real networks — the 75th percentile of them — and it measures that over a rolling 28 days through the Chrome User Experience Report (CrUX). Your Lighthouse run is a simulation. CrUX is the scoreboard.

That distinction — lab versus field — reshaped how our team approached performance. What follows is the short version of six months of work, minus the dead ends, focused on the three metrics that matter in 2026: LCP, INP, and CLS.


The metric most teams are losing on

Let me start with the one that hurts: INP. Interaction to Next Paint replaced First Input Delay in March 2024, and unlike FID — which only measured the delay before the browser started processing your click — INP measures the full round trip. Click to visual update. Every interaction on the page, not just the first one. The reported score is essentially your worst case.

Roughly 43% of sites currently fail the 200 ms "good" threshold, and on most of the apps I've touched, it's the metric that takes the deepest rework to fix. LCP is a logistics problem (ship bytes faster). CLS is a discipline problem (reserve space). INP is an architecture problem.

Here's where it bit us hardest: filters on a product listing page. Each tap triggered a setState that ran through a context provider, re-rendered about 40 components, recomputed a sort, and then — only then — painted the new chip as "selected." On a mid-range Android over 4G, that round trip hit 480 ms. The user felt it. Chrome reported it. No amount of bundle trimming was going to fix a long task.

What actually fixed it:

1. Break the task, then yield. The single highest-impact change was introducing yield points using scheduler.yield() (with a fallback to a setTimeout(0) shim for browsers without it). We split the interaction into "visual feedback first, everything else second."

async function handleFilterTap(filter) {
  // Paint the selected state immediately
  setSelectedFilter(filter);
  await yieldToMain();

  // Then do the expensive work
  const filtered = applyFilters(products, filter);
  await yieldToMain();

  setResults(filtered);
}

function yieldToMain() {
  if ('scheduler' in window && 'yield' in window.scheduler) {
    return window.scheduler.yield();
  }
  return new Promise(resolve => setTimeout(resolve, 0));
}

Enter fullscreen mode Exit fullscreen mode

The perceived responsiveness change was dramatic. The filter chip highlighted instantly. The list updated a tick later. INP at p75 dropped from 480 ms to 170 ms on the same page, with no change to the actual filtering logic.

2. Defer non-critical renders with useDeferredValue. In React, marking the filtered results as a deferred value let the input stay responsive while the heavy list re-rendered in the background. Free win, about a week to roll out safely across the product.

3. Kill the long tasks you don't know you're running. This one is humbling. Open the Performance panel in Chrome DevTools, record an interaction, and look for any task over 50 ms. In our case, a third-party analytics script was running a synchronous JSON serialization on every click. We had no idea. We moved the script to a web worker. INP dropped another 40 ms on pages where that analytics event fired.

The pattern that emerged: INP rewards event handlers that do almost nothing synchronously. Anything expensive — filtering, sorting, logging, heavy computations — gets yielded, deferred, or offloaded. If you take one thing from this post, take that.


LCP: it's almost always the hero image

Every team I've worked with has the same story with LCP. Someone optimized "the images." LCP was still 3.2 seconds. Because "the images" is not the fix — the LCP element is the fix, and the LCP element is almost always one specific image above the fold.

Before you touch anything, identify what the LCP element actually is. You can read it straight from the web-vitals library in production:

import { onLCP } from 'web-vitals';

onLCP(metric => {
  console.log('LCP element:', metric.entries.at(-1)?.element);
  console.log('LCP value:', metric.value);
});

Enter fullscreen mode Exit fullscreen mode

Ninety percent of the time, it's a hero image. Once you know that, the playbook is short and boring, which is the highest compliment I can give a performance playbook:

  • Preload it. <link rel="preload" as="image" href="..." fetchpriority="high"> in the document head. This one line moved our LCP from 2.8 s to 2.1 s on the homepage. Don't preload everything — just the LCP resource. Preload abuse is its own problem.
  • Set fetchpriority="high" on the image tag itself. Browsers are conservative about image priority by default; you're telling it this one matters.
  • Use modern formats. AVIF first, WebP fallback, JPEG as a last resort. The file size difference between JPEG and AVIF at equivalent quality is routinely 40 to 60 percent.
  • Serve the right size. A responsive srcset is not optional. Shipping a 2000-pixel-wide image to a phone that displays it at 400 is the most common unforced error in frontend performance.
  • Do not lazy-load the LCP image. I've seen this mistake on production sites shipping in 2026. loading="lazy" on the hero image is a guaranteed LCP regression.

The harder part of LCP is when the element isn't an image — when it's a block of text that depends on a custom font, for example. In that case, font-display: swap and preloading the font file are your friends. Accept the brief flash of fallback type. Your users won't notice. Your 75th-percentile LCP will.


CLS: the metric that makes you look unprofessional

CLS is the cheapest to fix and the one that makes your site feel the most amateur when you don't. When buttons jump out from under thumbs and ads push content down after the user has started reading, people lose trust in the interface, even if they can't articulate why.

Three rules. That's all. I have not found a CLS problem in the last three years that wasn't covered by these:

  1. Every image, video, and iframe gets explicit width and height attributes. Even if you're styling them with CSS, the HTML attributes let the browser reserve space before the asset loads. Aspect-ratio boxes work too, but the width/height attributes are simpler and work everywhere.
  2. Reserve space for anything injected late. Ad slots, cookie banners, personalization widgets — any element that arrives after first paint needs a height reserved upfront. A min-height on the container is usually enough. If the slot stays empty, leave it empty. The shift is worse than the blank space.
  3. Use font-display: swap with care. Swap prevents invisible text, but it can cause a layout shift if your fallback font has significantly different metrics. The size-adjust descriptor on @font-face lets you match fallback metrics to your web font and eliminates that shift entirely. This is underused. Most teams haven't heard of it.

That's it. CLS under 0.05 is achievable on nearly any site if you follow those three rules. Ours runs at 0.02.


The monitoring setup that actually helped

You cannot fix what you cannot see, and DevTools on your machine is not "seeing." We installed the web-vitals npm package, shipped real-user metrics to our analytics pipeline, and — this was the unlock — sliced the data by route, device class, and country. A single aggregate INP number hides everything. The same site can have great INP for desktop users in Germany and awful INP for mobile users in Brazil, and the aggregate will look mid. Slicing is how you find the real fire.

We also set alerts at 80% of Google's thresholds — INP at 160 ms, LCP at 2.0 s, CLS at 0.08 — so we'd see regressions before they started eating our CrUX window. A deploy that bumps INP from 150 to 190 still reports "good," but three of those deploys in a month and you're in trouble.


What I'd tell past-me on day one

Three things.

First, stop optimizing for Lighthouse. Use it as a diagnostic tool, not a scoreboard. The scoreboard lives at CrUX, and the gap between the two can be an order of magnitude. We spent weeks chasing a 98 when we needed to spend a day fixing a filter handler.

Second, fix the metric that's actually failing, not the one you have opinions about. I like LCP. I find it tractable and satisfying. For three weeks I optimized LCP while INP silently tanked. Look at your CrUX dashboard, find the worst of the three, and start there. Then the next worst. No hero shots.

Third, performance is a product feature, not a cleanup task. Every team I've seen succeed at Core Web Vitals treated them like any other product metric: someone owned them, they were reviewed weekly, regressions were treated as bugs, and they were part of the definition of done for new features. Every team I've seen fail at Core Web Vitals treated them as something to "get to after the next launch."

You know which team gets to the next launch faster.


If this was useful, a clap helps other engineers find it. I write about frontend architecture, performance, and the unglamorous parts of shipping software.