戴老师的博客 - 浏览器
type: channel
link: https://www.tushu.info/tag/%E6%B5%8F%E8%A7%88%E5%99%A8/
items: chrome插件开发入门指南
items: chrome插件开发入门教程
items: chrome插件调试
items: 从零开始实现一个玩具版浏览器渲染引擎
items: 前端必读：浏览器内部工作原理

chrome插件开发入门指南
type: item
date: 2026-07-07T08:34:12+00:00
description: 什么是扩展插件？扩展插件是可以定制浏览体验的小型软件程序。它们使用户可以根据个人需要或偏好来定制 Chrome 功能和行为。扩展基于 Web 技术构建，例如 HTML、JavaScript 和 CSS。扩展必须满足定义狭义且易于理解的 单一目的 原则。一个扩展可以包含多个组件和一系列功能，只要所有内容都有助于实现共同的目标。用户界面应保持简洁且意图明确。其形式范围从简单的工具栏图标到 覆盖 整个页面的内容。扩展文件会被压缩成单个 .crx 程序包，供用户下载和安装。这意味着扩展与普通的 Web 应用程序不同，它不依赖于 Web 上的远程内容。扩展程序通过 Chrome 开发人员信息中心 分发，并发布到 Chrome 网上应用店。有关更多信息，请参阅 商店开发人员文档。你好插件通过这个快速的 Hello World 示例，迈出扩展开发的第一步。首先创建一个新目录来存储扩展的文件，或者从 示例页面 下载它们。接下来，添加一个名为 manifest.json 的文件，并包含以下代码：{ "name": "Hello Extensions", "description" : "Base Level Extension", "version": "1.0", "manifest_version": 2 }每个扩展都需要一个清单（Manifest），尽管大多数扩展仅对清单没有多大作用。为了快速入门，扩展程序在该 browser_action 字段下声明了一个弹出文件和图标：{ "name": "Hello Extensions", "description" : "Base Level Extension", "version": "1.0", "manifest_version": 2, "browser_action": { "default_popup": "hello.html", "default_icon": "hello_extensions.png" } }请 在此处 下载图标文件，并将其保存为 hello_extensions.png。然后创建一个名为 hello.html 的文件： Hello Extensions 现在，hello.html 将在单击该图标时显示为扩展的弹出页面。下一步是在 manifest.json 中包含启用键盘快捷键的命令。此步骤很有趣，但不是必需的：{ "name": "Hello Extensions", "description" : "Base Level Extension", "version": "1.0", "manifest_version": 2, "browser_action": { "default_popup": "hello.html", "default_icon": "hello_extensions.png" }, "commands": { "_execute_browser_action": { "suggested_key": { "default": "Ctrl+Shift+F", "mac": "MacCtrl+Shift+F" }, "description": "Opens hello.html" } } }最后一步是在您的本地计算机上安装扩展。在浏览器中导航到 chrome://extensions 页面。您还可以通过点击浏览器右上角的 Chrome 菜单，将鼠标悬停在 更多工具 上，然后选择 扩展程序 来访问此页面。勾选 开发者模式 开关。点击 加载已解压的扩展程序 按钮，然后为 "Hello 扩展名" 扩展名选择目录。恭喜你！现在，您可以通过点击 hello_extensions.png 图标或按 Ctrl+Shift+F 键盘快捷键来使用基于弹出窗口的扩展名。接下来是什么？遵循 入门教程阅读 概述阅读 Chromium 博客 以了解最新信息 订阅 铬扩展组精选视频技术视频开发人员快照根据 CC-By 3.0 许可提供的内容说明版本时效：本文档示例基于 Manifest V2 规范编写。目前 Chrome 扩展已逐步转向 Manifest V3，部分 API 和安全策略可能有所不同。链接有效性：文中部分外部链接（如 Google Code 相关页面）可能因服务关闭而无法访问，请以 Chrome 官方开发者文档为准。

chrome插件开发入门教程
type: item
date: 2026-07-07T08:34:05+00:00
description: Chrome 插件开发入门教程目录创建清单添加后台脚本用户界面添加逻辑选项页面后续步骤扩展由不同但相互联系的组件组成。这些组件可以包括 后台脚本、内容脚本、选项页、UI 元素 以及各种逻辑文件。扩展组件是使用 Web 开发技术创建的：HTML、CSS 和 JavaScript。扩展的具体组件取决于其功能需求，并非所有扩展都需要包含上述所有选项。本教程将构建一个扩展，允许用户更改 developer.chrome.com 上任何页面的背景颜色。它将使用许多核心组件来介绍它们之间的关系。首先，创建一个新目录来保存扩展的文件。完整的扩展程序可以在 此处 下载。创建清单扩展从 清单 文件开始。创建一个名为 manifest.json 的文件并包含以下代码，或在 此处 下载该文件。{ "name": "Getting Started Example", "version": "1.0", "description": "Build an Extension!", "manifest_version": 2 }可以在当前状态下以开发者模式将包含清单文件的目录添加为扩展。通过导航到 chrome://extensions 打开“扩展管理”页面。也可以通过点击 Chrome 菜单，将鼠标悬停在 “更多工具” 上，然后选择 “扩展程序” 来打开该页面。通过单击 “开发者模式” 旁边的切换开关启用该模式。单击 “加载已解压的扩展程序” (LOAD UNPACKED.html) 按钮，然后选择扩展目录。该扩展程序已成功安装。由于清单中未包含任何图标，因此将为扩展创建通用工具栏图标。添加后台脚本尽管已安装扩展，但目前它没有任何指令。通过创建名为 background.js 的文件或 在此处 下载，然后将其放置在扩展目录中，来引入 后台脚本。后台脚本和许多其他重要组件必须在清单中注册。在清单中注册后台脚本会告诉扩展要引用的文件以及该文件的行为。{ "name": "Getting Started Example", "version": "1.0", "description": "Build an Extension!", "background": { "scripts": [ "background.js" ], "persistent": false }, "manifest_version": 2 }现在，该扩展程序知道它包含一个非持久性后台脚本，并将扫描注册文件中需要侦听的重要事件。此扩展在安装后将需要来自持久变量的信息。首先在后台脚本中包含一个 runtime.onInstalled 监听事件。在 onInstalled 侦听器内部，扩展将使用 存储 API 设置一个值。这将允许多个扩展组件访问该值并进行更新。chrome.runtime.onInstalled.addListener(function(.html) { chrome.storage.sync.set({color: '#3aa757'}, function (.html) { console.log('The color is green.'.html); }); });大多数 API（包括 存储 API）都必须在清单中的 "permissions" 字段下注册，以便扩展程序使用它们。{ "name": "Getting Started Example", "version": "1.0", "description": "Build an Extension!", "permissions": ["storage"], "background": { "scripts": ["background.js"], "persistent": false }, "manifest_version": 2 }浏览回到扩展管理页面，然后单击 “重新加载” 链接。带有蓝色链接 “背景页面” 的新字段 “检查视图” (Inspect Views.html) 将变为可用。点击链接以查看后台脚本的控制台日志 "The color is green."。用户界面扩展可以具有多种形式的 用户界面，本教程将使用 弹出窗口。创建并添加名为 popup.html 的文件到目录，或 在此处 下载。此扩展程序使用按钮来更改背景颜色。 与后台脚本一样，该文件需要在清单下的 page_action 字段中指定为弹出窗口。{ "name": "Getting Started Example", "version": "1.0", "description": "Build an Extension!", "permissions": ["storage"], "background": { "script…

chrome插件调试
type: item
date: 2026-07-07T08:27:04+00:00
description: [TOC]重要提示： Chrome 将在所有平台上移除对 Chrome 应用（Chrome Apps）的支持。Chrome 浏览器和 Chrome 网上应用店将继续支持扩展程序（Extensions）。请 阅读公告，并了解有关 迁移应用程序 的更多信息。调试扩展扩展程序可以利用 Chrome DevTools 为网页提供的相同调试 优势，但它们具有独特的行为属性。成为专业的扩展调试器需要了解以下行为：扩展组件如何相互配合，以及在哪里处理错误。本教程旨在帮助开发人员建立对调试扩展的基本了解。查找日志扩展由许多不同的组件组成，这些组件各有其职责。在此处下载损坏的扩展程序，以开始查找不同扩展组件的错误日志。后台脚本导航至 Chrome 扩展管理页面 chrome://extensions，并确保已启用开发者模式。单击加载已解压的扩展程序按钮，然后选择损坏的扩展目录。扩展加载后，应显示三个按钮：详情、移除以及红色文字的错误。单击错误按钮以查看错误日志。扩展程序系统在后台脚本中发现了一个问题：Uncaught TypeError: Cannot read property 'addListener' of undefined此外，通过选择检查视图旁边的蓝色链接，可以打开 Chrome DevTools 面板以显示后台脚本。返回代码编辑器查看 background.js：chrome.runtime.oninstalled.addListener(function(.html) { chrome.storage.sync.set({color: '#3aa757'}, function(.html) { console.log('The color is green.'.html); }); chrome.declarativeContent.onPageChanged.removeRules(undefined, function(.html) { chrome.declarativeContent.onPageChanged.addRules([{ conditions: [new chrome.declarativeContent.PageStateMatcher({ pageUrl: {hostEquals: 'developer.chrome.com'}, })], actions: [new chrome.declarativeContent.ShowPageAction()] }]); }); });后台脚本正在尝试侦听 onInstalled 事件，但是属性名称要求使用大写字母 "I"（即 onInstalled 而非 oninstalled）。更新代码以反映正确的调用，单击右上角的清除全部按钮，然后重新加载该扩展。弹出页面现在，该扩展已正确初始化，可以测试其他组件了。刷新此页面，或打开一个新标签页并导航到 developer.chrome.com 上的任何页面，打开弹出窗口并单击绿色方块。然而……什么都没发生。导航回到扩展管理页面，错误按钮重新出现。单击它以查看新日志：Uncaught ReferenceError: tabs is not defined弹出错误也可以通过检查弹出窗口来查看。错误 tabs is undefined 表示扩展不知道将内容脚本注入哪里。可以通过调用 tabs.query() 方法，然后选择活动标签页来更正此问题。let changeColor = document.getElementById('changeColor'.html); chrome.storage.sync.get('color', function(data.html) { changeColor.style.backgroundColor = data.color; changeColor.setAttribute('value', data.color); }); changeColor.onclick = function(element.html) { let color = element.target.value; chrome.tabs.query({active: true, currentWindow: true}, function(tabs.html) { chrome.tabs.executeScript( tabs[0].id, {code: 'document.body.style.backgroundColor = color;'}); }); };更新代码，单击右上角的清除全部按钮，然后重新加载扩展。内容脚本刷新页面，打开弹出窗口，然后单击绿色方块。然而……不，背景仍然没有变色！浏览回扩展…

从零开始实现一个玩具版浏览器渲染引擎
type: item
date: 2026-07-07T08:26:13+00:00
description: 引言浏览器渲染原理是前端开发者必须掌握的核心知识点之一，在技术面试中经常被问及。许多前端书籍或培训课程也会提及此主题，例如 MDN 文档中就有关于渲染原理 [1] 的相关描述。作为一名工作多年的前端工程师，我虽然了解渲染原理的理论知识，但缺乏实践层面的深入理解。因此，我决定动手实现一个玩具版（Toy Version）的渲染引擎。渲染引擎是浏览器的核心组件，负责将网页内容（HTML、CSS、JavaScript 等）转化为用户可阅读、观看和听到的形式。独自实现一个完整的渲染引擎工作量巨大且难度极高，所以我决定退一步，实现一个简化版的玩具引擎。GitHub 上有一个开源的 Rust 语言玩具版渲染引擎 robinson [2]，我决定模仿其源码，使用 JavaScript 重新实现一遍，并将项目开源在 GitHub 上：从零开始实现一个玩具版浏览器渲染引擎 [3]。整体架构这个玩具版渲染引擎的实现一共分为五个阶段：具体流程分别是：解析 HTML：生成 DOM 树。解析 CSS：生成 CSS 规则集合。生成 Style 树：将样式与 DOM 节点关联。生成布局树：计算节点在页面中的位置和尺寸。绘制：将布局树渲染到屏幕上。每个阶段的代码在仓库中都用独立的分支来表示。由于直接查看整个渲染引擎的代码可能比较困难，建议大家从第一个分支开始学习，由易到难，以获得更好的学习效果。接下来，我们先看一下如何编写一个 HTML 解析器。第一阶段：HTML 解析器HTML 解析器的作用是将一连串的 HTML 文本解析为 DOM 树。例如，将以下 HTML 文本： test! 解析为一个 DOM 树结构：{ "tagName": "div", "attributes": { "class": "lightblue test", "id": "div", "data-index": "1" }, "children": [ { "nodeValue": "test!", "nodeType": 3 } ], "nodeType": 1 }编写解析器通常需要掌握编译原理知识，如词法分析、语法分析等。但我们的玩具版解析器非常简单，即使不懂相关理论，通过阅读源码也能理解。回到上面的 HTML 文本，其整个解析过程可以用下图表示，每一段 HTML 文本都有对应的方法去解析：为了让解析器实现起来更简单，我们需要对 HTML 的功能进行约束：标签必须要成对出现： ... 。HTML 属性值必须要有引号包起来： ... 。不支持注释。尽量不做错误处理。只支持两种类型节点：Element 和 Text。对解析器的功能进行约束后，代码实现就变得简单多了。节点类型首先，为这两种节点 Element 和 Text 定义适当的数据结构：export enum NodeType { Element = 1, Text = 3, } export interface Element { tagName: string attributes: Record<string, string> children: Node[] nodeType: NodeType.Element } interface Text { nodeValue: string nodeType: NodeType.Text } export type Node = Element | Text然后为这两种节点各写一个生成函数：export function element(tagName: string.html) { return { tagName, attributes: {}, children: [], nodeType: NodeType.Element, } as Element } export function text(data: string.html) { return { nodeValue: data, nodeType: NodeType.Text, } as Text }这两个函数在解析到元素节点或者文本节点时调用，调用后会返回对应的 DOM 节点。解析流程下图展示了整个 HTML 解析器的执行过程：HTML 解析器的入口方法为 parse()，从这开始执行直到遍历完所有 HTML 文本为止：判断当前字符是否为 <，如果是，则当作元素节点来解析，调用 parseElement()，否则调用 parseText()。parseText() 比较简单，一直往前遍历字符串，直至遇到 < 字符为止。然后将之前遍历过的所有字符当作 Text 节点的值。parseElement() 则相对复杂一点，它首先要解析出当前的元素标签名称，这段文本用 parseTag() 来解析。然后再进入 parse…

前端必读：浏览器内部工作原理
type: item
date: 2026-07-07T08:24:59+00:00
description: 前端必读：浏览器内部工作原理英文原文：How Browsers Work: Behind the Scenes of Modern Web Browsers一、介绍浏览器可以被认为是使用最广泛的软件。本文将介绍浏览器的工作原理，我们将看到从你在地址栏输入 google.com 到你看到 Google 主页过程中都发生了什么。将讨论的浏览器今天，有五种主流浏览器——IE、Firefox、Safari、Chrome 及 Opera。本文将基于一些开源浏览器的例子——Firefox、Chrome 及 Safari（Safari 是部分开源的）。根据 W3C（World Wide Web Consortium，万维网联盟）的浏览器统计数据，当前（2011 年 5 月），Firefox、Safari 及 Chrome 的市场占有率综合已接近 60%。（原文数据为 2009 年 10 月，当时数据没有太大变化）。因此，可以说开源浏览器已经占据了浏览器市场的半壁江山。浏览器的主要功能浏览器的主要功能是将用户选择的 Web 资源呈现出来。它需要从服务器请求资源，并将其显示在浏览器窗口中。资源的格式通常是 HTML，也包括 PDF、Image 及其他格式。用户用 URI（Uniform Resource Identifier，统一资源标识符）来指定所请求资源的位置，在“网络”一章有更多讨论。HTML 和 CSS 规范中规定了浏览器解释 HTML 文档的方式，由 W3C 组织对这些规范进行维护。W3C 是负责制定 Web 标准的组织。HTML 规范的最新版本是 HTML4 (http://www.w3.org/TR/html401/)，HTML5 还在制定中（译注：两年前）；最新的 CSS 规范版本是 2 (http://www.w3.org/TR/CSS2)，CSS3 也还正在制定中（译注：同样两年前）。这些年来，浏览器厂商纷纷开发自己的扩展，对规范的遵循并不完善，这为 Web 开发者带来了严重的兼容性问题。但是，浏览器的用户界面则差不多，常见的用户界面元素包括：用来输入 URI 的地址栏前进、后退按钮书签选项用于刷新及暂停当前加载文档的刷新、暂停按钮用于到达主页的主页按钮奇怪的是，并没有哪个正式公布的规范对用户界面做出规定，这些是多年来各浏览器厂商之间相互模仿和不断改进的结果。HTML5 并没有规定浏览器必须具有的 UI 元素，但列出了一些常用元素，包括地址栏、状态栏及工具栏。还有一些浏览器有自己专有的功能，比如 Firefox 的下载管理。更多相关内容将在后面讨论用户界面时介绍。浏览器的主要构成（High Level Structure）浏览器的主要组件包括：用户界面 － 包括地址栏、后退/前进按钮、书签目录等，也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分。浏览器引擎 － 用来查询及操作渲染引擎的接口。渲染引擎 － 用来显示请求的内容。例如，如果请求内容为 HTML，它负责解析 HTML 及 CSS，并将解析后的结果显示出来。网络 － 用来完成网络调用，例如 HTTP 请求。它具有平台无关的接口，可以在不同平台上工作。UI 后端 － 用来绘制类似组合选择框及对话框等基本组件，具有不特定于某个平台的通用接口，底层使用操作系统的用户接口。JS 解释器 － 用来解释执行 JS 代码。数据存储 － 属于持久层，浏览器需要在硬盘中保存类似 Cookie 的各种数据。HTML5 定义了 Web Database 技术，这是一种轻量级完整的客户端存储技术。图 1：浏览器主要组件需要注意的是，不同于大部分浏览器，Chrome 为每个 Tab 分配了各自的渲染引擎实例，每个 Tab 就是一个独立的进程。对于构成浏览器的这些组件，后面会逐一详细讨论。二、渲染引擎（The Rendering Engine）渲染引擎的职责就是渲染，即在浏览器窗口中显示所请求的内容。默认情况下，渲染引擎可以显示 HTML、XML 文档及图片。它也可以借助插件（一种浏览器扩展）显示其他类型数据，例如使用 PDF 阅读器插件可以显示 PDF 格式。将由专门一章讲解插件及扩展，这里只讨论渲染引擎最主要的用途——显示应用了 CSS 之后的 HTML 及图片。渲染引擎简介本文所讨论的浏览器——Firefox、Chrome 和 Safari 是基于两种渲染引擎构建的。Firefox 使用 Gecko——Mozilla 自主研发的渲染引擎；Safari 和 Chrome 都使用 WebKit。WebKit 是一款开源渲染引擎，它本来是为 Linux 平台研发的，后来由 Apple 移植到 Mac 及 Windows 上。相关内容请参考 http://webkit.org。渲染主…