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

推荐订阅源

Martin Fowler
Martin Fowler
L
LINUX DO - 最新话题
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
Know Your Adversary
Know Your Adversary
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
Lohrmann on Cybersecurity
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Security Latest
Security Latest
T
The Exploit Database - CXSecurity.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Privacy & Cybersecurity Law Blog
K
Kaspersky official blog
The Last Watchdog
The Last Watchdog
Webroot Blog
Webroot Blog
Scott Helme
Scott Helme
T
Threat Research - Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
WordPress大学
WordPress大学
L
LINUX DO - 热门话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - Franky
V
Visual Studio Blog
O
OpenAI News
AI
AI
Hacker News: Ask HN
Hacker News: Ask HN
V2EX - 技术
V2EX - 技术
GbyAI
GbyAI
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Simon Willison's Weblog
Simon Willison's Weblog
S
Schneier on Security
Spread Privacy
Spread Privacy
Y
Y Combinator Blog
I
InfoQ
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
F
Fortinet All Blogs
C
CERT Recently Published Vulnerability Notes
T
The Blog of Author Tim Ferriss
C
Check Point Blog
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
N
News and Events Feed by Topic
Project Zero
Project Zero
小众软件
小众软件
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
B
Blog
G
Google Developers Blog

hayato

Chromium's DOM Deep Dive: Understanding Shadow DOM and Tree Structures - hayato 出版のお知らせ 「普通の人が資産運用で99点をとる方法とその考え方」 - hayato Resource loading with Content Addressable Bundles - hayato 普通の人が資産運用で99点をとる方法とその考え方 - hayato Imperative Shadow DOM Distribution API - hayato Google にソフトウェアエンジニアとして入社して 10 年と 10 日がたちました - hayato Web のつくりかた: ソフトウェアエンジニアリングと雰囲気で理解する Web 標準とブラウザのつくりかた - hayato ブラウザのしくみ: データ構造とアルゴリズムと雰囲気で理解する DOM と Shadow DOM - hayato Rust が最強のプログラミング言語である証明 - hayato 六本木ではたらくソフトウェアエンジニアへのよくある質問とその答え (FAQ) (2015 - 2017) - hayato What's New in Shadow DOM v1 (by examples) - hayato Simple timer application for the pomodoro technique - hayato Google の面接試験で出る (はずがない)「海賊と金貨」問題を空気を読まないでプログラムで解いてみる - hayato hayato.io (4topcoder) - hayato SRM432 - hayato SRM405 - hayato SRM386 - hayato SRM385 - hayato SRM384 - ゲーム - hayato SRM369 - hayato SRM368 - hayato SRM366 - typo 2 連発 - hayato Python - generator で素数生成 - hayato New Launguage - 新言語追加の予定? - hayato lxml で HTML スクレーピング - hayato SRM358 - Today is a Bad Day (-50). - hayato SRM349 FizzBuzz 問題が簡単すぎるそんなあなたへ。「赤いマーブル問題」。 - hayato Suffix Array - hayato google-code-prettify を導入してみる - hayato Subset の生成 - hayato 2006 年のまとめ - SRM332 - hayato Google Code Jam 2006 - Championship Round - hayato Blogger Beta に移行 - hayato Google Code Jam 2006 - Round1 に挑戦 - Generics と AutoBoxing - hayato Google Code Jam 2006 - Qualification Round 通過 - hayato Google Code Jam 2006 - Qualification Round に挑戦 - hayato Google Code Jam 2006 - Practice1 - hayato Google Code Jam 2006 - 開催決定 - hayato Stay tuned... Global Google Code Jam 2006 - 秋に開催? - hayato SRM308 - Hard DP - hayato SRM304 - 条件付確率 - hayato JavaWorld に寄稿しました - hayato 2006 TopCoder Open Final Round - hayato IBM Rational Software Development Forum Tokyo で講演します - hayato SRM298 - ひとふで書き - hayato SRM293 - ビンゴ - hayato 2006 TopCoder Open - Round1 撃墜 - hayato 2006 TopCoder Open - Odds 発表 - hayato 2006 TopCoder Open Qualification Round - hayato SRM291 - OutOfMemory - hayato デブサミ 2006 で講演します - hayato SRM287 - 気分は中学生?連立2元方程式 - hayato SRM281 - 2006 年はポイントゼロスタート - hayato SRM280 - Challenge 祭り - hayato SRM277 - 初賞金げっと - hayato マラソン・マッチ - hayato reStructuredText で blogger - hayato 2006 TopCoder Open - NSA がスポンサーに - hayato SRM276 - お買い物は楽しく DP で - hayato SRM273 - bit 演算は int で行われるのね - hayato SRM272 - Division1 - 4 度目の正直 - hayato JavaOne Tokyo で講演します - hayato SRM270 - Integer == Integer - hayato SRM268 - Division2 脱出 - hayato SRM266 - NASA, we have a problem... - hayato SRM265 - Division2 落ち... - hayato SRM262 - 初 Division1 は Typo に終わる - hayato SRM260 - TopCoder への挑戦のはじまり - hayato
Introducing the Task Scheduler in Chromium's Network Stack: A 0.3% Improvement in Loading Speed - hayato
2025-12-17 · via hayato

In the quest for a faster, smoother web browsing experience, every millisecond counts. At the heart of Chrome's ability to fetch web content is the network stack, a complex piece of engineering responsible for handling all network requests. As a software engineer on the Google Chrome networking team, I'm excited to share a significant improvement I've made to the core of Chromium's networking: a new Task Scheduler for the Network Service thread, which has demonstrated an improvement of up to 0.3% in loading speed on global key metrics.

Historical Context: From I/O-Bound to CPU-Bound

Historically, Chromium's Network Service thread was designed as a classic event-driven, I/O-bound system. Its main job was to wait for network events (like data arriving on a socket) from the kernel and react to them. Tasks were generally lightweight and processed in a simple First-In, First-Out (FIFO) queue. This model was efficient when the primary bottleneck was the network itself.

However, as the web has grown more complex, the network stack's responsibilities have also expanded. It's no longer just about waiting for data; it now handles more CPU-intensive tasks like parsing complex proxy rules, managing security policies, and handling intricate caching logic. This shift meant that a long-running, CPU-bound task could occupy the thread and prevent it from processing critical, time-sensitive network I/O, creating a bottleneck right where we least wanted one.

The Challenge: A Digital Traffic Jam

The existing FIFO model was a bit like a single-lane road. A CPU-intensive but low-priority background task could get in front and delay a high-priority navigation task. This contention could negatively impact key performance metrics like First Contentful Paint (FCP) and Largest Contentful Paint (LCP), ultimately leading to a slower page load for the user.

Here is a simplified illustration of the "before" state:

Figure 1: The previous single-queue approach, where all tasks were processed in FIFO order.

Figure1

This diagram illustrates this "single-lane highway." Both high-priority and low-priority tasks are funneled into the same Single FIFO Queue. The MessagePump, which is Chromium's core event loop, simply pulls tasks from this queue in the order they were added. This means a critical navigation task could get stuck waiting for a less important background task to finish.

The Solution: A Multi-Lane Highway for Network Tasks

To address this, I introduced an application-level task scheduler in the Network Service. It's important to note that this scheduler operates on top of the existing event loop. It doesn't change how the kernel notifies us of I/O events, but it gives us fine-grained control over the order in which our application's C++ tasks are executed.

The new scheduler replaces the single-lane road with a multi-lane highway, complete with express lanes for high-priority traffic.

Here is a simplified illustration of the "after" state:

Figure 2: The new scheduler with prioritized queues, allowing critical tasks to be processed first.

Figure2

This diagram shows the new, improved workflow. High-priority tasks are now sent to a dedicated High-Priority Queue, while other tasks go to a separate Default-Priority Queue. The key addition is the SequenceManager, which acts as an intelligent traffic controller. It actively pulls tasks from the available queues, always selecting the next available task from the highest-priority queue. This ensures that critical work can jump to the front of the line and is no longer delayed by less important tasks.

From a Single Queue to Prioritized Lanes

At a technical level, SequenceManager manages task execution on the Network Service thread. My first iteration (v1) of the scheduler introduced two task queues: a HighPriorityTaskQueue for critical tasks and a DefaultTaskQueue for everything else. Tasks are categorized based on their existing net::RequestPriority. For example, tasks associated with a user-initiated navigation are considered HIGHEST priority and are routed to our new express lane.

Building on the success of v1, I've since rolled out v2 of the scheduler, which is even more granular. It features six task queues, one for each net::RequestPriority level (from THROTTLED to HIGHEST). This allows for a much finer-grained control over task prioritization.

A Real-World Example in Action

To make this more concrete, let's look at a real-world trace of the scheduler in action. In this scenario (Perfetto trace), a simple navigation to https://httpbin.org/ occurred.

When the navigation task (an HttpStreamFactoryJob posting an OnStreamReadyCallback) was posted with HIGHEST priority (Figure 3), the default queue already had 13 pending tasks (Figure 4). In a traditional First-In, First-Out (FIFO) system, this critical navigation task would normally have to wait for those 13 tasks to complete.

Figure 3: [00:00:03.501415836] HttpStreamFactoryJob posts a task for OnStreamReadyCallback with the highest priority using a high-priority task runner.

Figure3

Figure 4: The number of tasks in the default queue.

Figure4

However, with the new Task Scheduler, the SequenceManager immediately recognized the high-priority task. It processed this newly posted task without delay, taking precedence over the tasks in the default-priority queue (as depicted in Figure 5). This bypassing demonstrates how the scheduler ensures critical user-facing work is not blocked by less important background operations, leading to a more responsive browsing experience.

Figure 5: [00:00:03.501727836] The high-priority task is processed immediately, taking precedence over the tasks in the default-priority queue.

Figure5

The Journey: Timeline, Challenges, and Triumphs

Introducing such a fundamental change to a mature and complex codebase like Chromium's network stack was a significant undertaking.

The Challenges

One of the biggest risks was the potential for task reordering to break subtle assumptions in the existing code, leading to stability issues like race conditions or use-after-free bugs. To mitigate this, I took a phased and data-driven approach. I started with a conservative implementation, focusing on a small, well-understood set of critical tasks. I then carefully expanded the scope of the scheduler, continuously monitoring for any regressions. This meticulous approach, which I documented as "No Mechanical Rewrites" in the design doc, allowed me to reap the performance benefits without compromising Chrome's stability.

Another interesting challenge was handling the different ways the Network Service is run on different platforms. On most desktop platforms, the Network Service runs in its own dedicated process (out-of-process). However, on some Android devices, particularly low-end ones, it runs within the main browser process (in-process) to save memory. This required careful handling to ensure the scheduler worked flawlessly in both scenarios: its dedicated out-of-process configuration (standard on desktop) and the in-process, memory-saving configuration for some Android devices.

The Timeline

  • Weeks 1-3: Design and Prototyping. I started by creating a detailed design document, outlining the problem, proposed solution, and potential risks. This was followed by a proof-of-concept to validate the approach.
  • Weeks 4-9: Integration and Testing. The next phase involved carefully integrating the new scheduler with the existing network stack. This was the most extensive part of the work, requiring me to modify numerous task posting sites in //net and //services/network. During this phase, I also added comprehensive unit tests and diagnostic metrics to monitor the scheduler's behavior.
  • Week 10 onwards: Finch Experiments and Rollout. With the implementation in place, I began a series of Finch experiments on Chrome's Canary, Dev, Beta, and Stable channels to measure the real-world impact of the new scheduler.

The Impact: Measurable Performance Gains

I rigorously tested the new task scheduler through a series of Finch experiments. The results have been very promising. With the v1 scheduler, I observed:

  • Up to 0.3% improvement in Global First Contentful Paint (FCP) and Largest Contentful Paint (LCP) on Android. (FCP measures the time it takes for the first piece of content to appear on screen, and LCP measures when the main content of a page has loaded.)

These seemingly small percentages translate to a noticeably faster and smoother browsing experience for millions of users, especially on devices with limited resources or on congested networks.

What's Next?

The rollout of our v2 per-priority task queues is ongoing, and I'm continuing to monitor its impact. I'm also exploring other opportunities to improve task scheduling in the network service, such as dynamically changing task priorities and allowing tasks to yield to higher-priority ones.

I'm excited about the improvements the new task scheduler brings to Chrome's performance, and I'll continue to work on making the web a faster place for everyone.