Total Blocking Time (TBT) is a key Lighthouse metric that measures the total time the main thread is blocked by tasks exceeding 50ms after First Contentful Paint (FCP) and before Time to Interactive (TTI), contributing 30% to the overall Performance score.[1][2][7] Fluctuations in TBT scores often stem from variable long tasks caused by JavaScript execution, third-party scripts, network conditions, or device differences, leading to inconsistent Lighthouse results across runs.[1][9]
Understanding TBT and Its Impact on Scores
TBT aggregates the "blocking portion" of long tasks—any execution over 50ms on the main thread that delays input responsiveness, such as clicks or taps.[1][2][7] For instance, a 400ms task adds 350ms to TBT, while tasks under 50ms contribute nothing.[1][3] Lighthouse thresholds for TBT subscores vary by device:
| TBT Subscore | Max TBT (Mobile) | Max TBT (Desktop) |
|---|---|---|
| 100 | 0.1s | 0.05s |
| 90 | 0.3s | 0.1s |
| 50 | 0.6s | 0.3s |
| 10 | 1.2s | 0.8s |
High TBT directly lowers Performance scores, with mobile often more sensitive due to slower hardware.[1][9] Fluctuations occur because Lighthouse simulates real-world variability, including CPU throttling and network latency, making identical pages score differently (e.g., PageSpeed Insights at 78 with 540ms TBT vs. local Lighthouse).[9]
Core Causes of TBT Fluctuations
- Variable Long Tasks: Main-thread JavaScript like DOM queries (e.g.,
document.querySelectorAll('a')on 2000 nodes) or rendering loops create inconsistent blocking based on content size or load order.[1][7] - Third-Party Scripts: Widgets, A/B tools, or analytics execute variably, often dominating TBT; Lighthouse audits flag their exact contributions.[1]
- Network and Hosting Variability: Slower asset delivery amplifies JS parsing/execution time, worsening on shared hosting.[5]
- Prefetching Pitfalls:
<link rel="prefetch">can unexpectedly increase TBT by front-loading work, even withrequestIdleCallback.[8] - Lab vs. Field Differences: TBT is a lab proxy for Interaction to Next Paint (INP); real-user variability (e.g., device CPU) causes score swings not captured in single audits.[2]
Strategies to Stabilize and Minimize TBT
To prevent fluctuations, eliminate long tasks entirely (ideal TBT=0) and ensure consistent execution across environments.[6][7] Prioritize these steps, validated via repeated Lighthouse runs or Lighthouse CI for budgeting/assertions.[4]
1. Eliminate or Split Long Tasks
Break JS into chunks under 50ms using timeouts or requestIdleCallback:
- Render components sequentially (e.g., chart first, then map after 50ms gap).[1]
- Refactor inefficient code: Replace broad selectors with targeted ones (e.g., limit to 10 nodes vs. 2000).[7]
- Delay non-essential work: Move global-scope code to functions executed post-load.[6]
2. Optimize JavaScript Delivery
- Reduce Payloads: Use code splitting, tree shaking, and remove unused JS; defer non-critical scripts.[7]
- Avoid Blocking Execution: Parse audits for "Reduce JavaScript execution time" and prioritize high-impact scripts.[1][4]
- Monitor with Performance Panel: Profile Chrome DevTools to identify and refactor blocking portions.[7]
3. Manage Third-Party Code
- Audit and remove unnecessary scripts; lazy-load only on interaction (e.g., chat widgets).[1]
- Replace heavy libraries with lighter alternatives or self-host.[1][7]
4. Infrastructure and Resource Optimizations
- Upgrade Hosting/CDN: Switch to VPS/dedicated servers for consistent low-latency JS delivery.[5]
- Avoid TBT-Degrading Features: Disable aggressive prefetching; test impacts explicitly.[8]
- Preserve Layouts: Reserve space for dynamic content to prevent reflows that trigger long tasks.[3]
5. Testing and Monitoring for Consistency
- Run Multiple Audits: Average 5+ Lighthouse/PageSpeed Insights runs; use Lighthouse CI in CI/CD to catch regressions and enforce TBT budgets (e.g., <300ms mobile).[4][9]
- Field Metrics Correlation: Track real-user INP (TBT proxy) via CrUX; optimize lab TBT to stabilize both.[2]
- Device-Specific Tuning: Test mobile/desktop separately, as thresholds differ.[1]
Implementing these reduces TBT variability by minimizing main-thread dependencies, yielding stable 90-100 Lighthouse scores. For example, disabling prefetch alone improved TBT in controlled tests.[8] Re-audit after changes, focusing on Lighthouse's "Long Tasks" and "Third-Party Summary" diagnostics.[1][4] Note: While TBT remains influential, Google prioritizes INP for field responsiveness—align optimizations accordingly.[2]
No comments:
Post a Comment