从Manifest V2到V3:Chrome扩展后台脚本不完全指南,background.js的运行机制

背景

最近我在接触Chrome插件开发,发现后台脚本(background script)非常有趣。在开发过程中,我思考了关于这个脚本的三个问题,希望大家也能分享一下见解:

  • background.js 在什么时候运行?
  • background.js 只运行一次吗?
  • background.js 会一直在后台运行吗?

background.js 在什么时候运行?

background.js 是 Chrome 扩展程序的后台脚本,在Chrome插件被加载时运行的,它负责处理插件的生命周期事件和全局状态。具体来说,可以分为以下几种情况:

  1. 浏览器启动:每次打开Chrome浏览器,都会触发background.js运行,这是最基本的启动场景。
  2. 扩展安装/更新:扩展程序首次安装或更新后,background.js将执行,以完成初始化设置或迁移数据。
  3. 扩展激活:用户与扩展交互,比如点击扩展图标,会启动background.js
  4. 事件触发:编码定义的事件,如浏览器启动、标签页更新或消息收到,可以启动background.js执行相应响应。

background.js 会一直在后台运行吗?

这个问题就涉及到 Manifest V2 和 Manifest V3 中的不同背景脚本机制。让我们详细区分和解释一下这两种版本中的背景脚本机制。

Manifest V2 - 持久背景脚本(Persistent Background Script)

在 Manifest V2 中,默认情况下,背景脚本是持久的,会一直在后台运行,直到插件被禁用、浏览器关闭或者扩展程序被卸载。这种背景脚本被称为持久背景脚本。以下是一个示例:

{"manifest_version": 2,"name": "My Extension","version": "1.0","background": {"scripts": ["background.js"],"persistent": true}
}

特点

  • 持久运行。
  • 能够始终响应事件和执行任务。
  • 可能会消耗更多的系统资源。

Manifest V2 - 事件驱动背景脚本(Event Page)

为了节省资源,Chrome 引入了事件驱动的背景脚本,即事件页面。在这种模式下,背景脚本在空闲时会自动卸载,只有在需要处理事件时才会加载。可以通过将 persistent 属性设置为 false 来启用事件驱动模式:

{"manifest_version": 2,"name": "My Extension","version": "1.0","background": {"scripts": ["background.js"],"persistent": false}
}

特点

  • 自动卸载空闲的背景脚本。
  • 在需要处理事件时重新加载背景脚本。
  • 更节省资源,推荐使用这种方式。

Manifest V3 - 服务工作线程(Service Worker)

在 Manifest V3 中,Chrome 使用服务工作线程(Service Workers)代替传统的背景脚本,服务工作线程本身就是事件驱动的设计,所以也是非持久性的。而且在V3中不再支持 persistent 属性。你不能在 Manifest V3 中将服务工作线程设置为持久运行。Chrome 强制使用服务工作线程来实现更好的资源管理和性能优化。

当浏览器处于打开状态时,扩展程序的后台脚本不会一直执行。后台脚本以服务工作线程的形式运行,在空闲时会自动停止,以节省资源。但即使当前没有活动的标签页,后台脚本仍然可以监听和响应各种事件。当有事件需要处理时,服务工作线程会重新启动,并处理该事件。但当浏览器关闭或者用户手动停用扩展程序时,后台脚本会完全停止运行。

{"manifest_version": 3,"name": "My Extension","version": "1.0","background": {"service_worker": "background.js"}
}
  • 特点
    • 非持久性,在空闲时自动停止。
    • 需要处理事件时自动启动。
    • 更加节省资源,符合现代 Web 应用的设计。

这时候我们可以通过消息传递机制与内容脚本或其他页面进行通信,确保在需要时唤醒服务工作线程。或者利用事件驱动以在特定事件发生时启动服务工作线程。

// background.js
// 监听标签页更新事件
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {if (changeInfo.status === 'complete' && tab.url.includes('https://example.com')) {console.log('Tab updated:', tab.url);// 执行所需的操作}
});// 监听消息传递
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {if (message.type === 'some_event') {console.log('Message received:', message);// 执行所需的操作}
});

还有什么歪路子可以让脚本一直在后台运行吗

在 Manifest V3 中,无法让脚本一直在后台运行。不过,有一些方法可以尽可能地保持服务工作线程的活跃状态,但是更建议在设计扩展程序时,应尽量避免依赖持续运行的后台脚本,以节省资源。

我们可以利用 Chrome 的 Alarms API 设置定时器,定期唤醒服务工作线程。这种方法不能让脚本一直运行,但可以让它在需要时定期执行任务。

// background.js
chrome.runtime.onInstalled.addListener(() => {// 创建一个每分钟触发的定时器chrome.alarms.create('periodicAlarm', { periodInMinutes: 1 });
});chrome.alarms.onAlarm.addListener((alarm) => {if (alarm.name === 'periodicAlarm') {console.log('Periodic alarm triggered');// 执行定时任务}
});

background.js 只运行一次吗?

在 Manifest V2 中,background.js 是一个持久的后台脚本,它在扩展程序加载时运行一次,并在整个浏览器会话期间保持运行,除非浏览器关闭或者扩展程序被手动停用。

在 Manifest V3 中,background.js 是以服务工作线程(Service Worker)的形式运行的。服务工作线程的运行机制是非持久性的,这意味着它不会一直保持运行,而是在需要时启动,并在空闲时自动停止因此,它在插件的整个生命周期中可能运行多次,但每次都是在特定事件触发时启动的。

运行多次的情况:

  • 插件首次加载:安装后,background.js 会运行一次。
  • 浏览器重启:每次浏览器启动时,background.js 会重新运行。
  • 插件重新加载:如果扩展程序被手动重新加载(例如开发过程中),background.js 会重新运行。
  • 事件触发:当某个监听的事件触发时(例如 alarms.onAlarmtabs.onUpdated),服务工作线程会被唤醒并运行以处理事件。

不知道大家关于Chrome扩展中background.js文件还有哪些疑问呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/29760.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模块的加载机制

模块的加载机制是编程中一个重要的概念,它涉及到在运行时将模块(可以是独立的源代码文件或预编译的二进制文件)引入到程序中的过程。 模块查找: 加载机制首先会根据程序中引用的模块名称进行查找。在Node.js中,对于自…

win11 之下载安装 allure

1. 下载 https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/2.25.0/allure-commandline-2.25.0.zip 2. 配置系统变量 path 下添加解压后的bin目录 3. 验证是否安装成功 输入 allure

element ui 封装Table组件

1.首先npm i element-ui -S 安装element-ui 2.引入 Element 在 main.js 中写入以下内容: import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue; Vue.use(ElementUI); new Vue({ el…

Mac 安装HomeBrew(亲测成功)

1、终端安装命令: /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"执行后,没有安装git,会先安装,安装后再执行一下命令。 2、根据中文选择源安装 3、相关命令 查看版本号&a…

python flask使用flask_migrate管理数据库迁移

🌈所属专栏:【Flask】✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的点…

ipv4地址划分与地址汇总

一、IPV4地址 32位二进制构成 存在分类:ABCDE 其中ABC为单播地址 D为组播地址 E为保留地址 单播地址是唯一既可以作为源ip,也可以作为目标ip地址;组播地址只能为目标地址; ABC 存在标记广播域的需求--- …

一篇文章了解常用排序算法

排序 文章目录 排序直接(插入)排序InsertSort思想实现方法: 希尔排序ShellSort(可过OJ)思想预排序gap的作用整体代码 选择排序SelectSort思想完整代码 堆排序HeapSort(可过OJ)思想大根堆向下调整 完整代码 冒泡排序BubbleSort快速排序(快排&a…

Unity URP 仿原神角色渲染过程记录

想学一下NPR渲染,话不多说,先搞一只芙再说,边做边学 一、资源整理 终于是把东西全都集齐了 1、纹理设置 首先要把将Diffuse和Lightmap的压缩改成"无"或"高质量"。 法线贴图的纹理类型改成"法线贴图"。 除颜…

【如何在Python中使用turtle库】

在Python中使用turtle库来绘制图形非常简单。下面是一些基本步骤,说明如何使用turtle库进行简单的绘图操作。 步骤 1: 导入turtle模块 首先,你需要在你的Python脚本或交互式环境中导入turtle模块。 import turtle步骤 2: 创建一个Turtle对象 通常&am…

HarmonyOS 角落里的知识 —— 状态管理

一、前言 在探索 HarmonyOS 的过程中,我们发现了许多有趣且实用的功能和特性。有些总是在不经意间或者触类旁通的找到。或者是某些开发痛点。其中,状态管理是ArkUI开发非常核心的一个东西,我们进行了大量的使用和测试遇到了许多奇奇怪怪的问…

Android平台下VR头显如何低延迟播放4K以上超高分辨率RTSP|RTMP流

技术背景 VR头显需要更高的分辨率以提供更清晰的视觉体验、满足沉浸感的要求、适应透镜放大效应以及适应更广泛的可视角度,超高分辨率的优势如下: 提供更清晰的视觉体验:VR头显的分辨率直接决定了用户所看到的图像的清晰度。更高的分辨率意…

spring boot自定义注解校验参数(枚举校验)

引入spring boot的spring-boot-starter-validation实现自定义注解校验参数&#xff0c;实现校验枚举值参数数据是否合规&#xff0c;提高接口的安全性和开发效率。 1.引入validation的starter <dependency><groupId>org.springframework.boot</groupId><…

001.VMware Workstation Pro虚拟平台安装

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

《数字图像处理-OpenCV/Python》第16章:图像的特征描述

《数字图像处理-OpenCV/Python》第16章&#xff1a;图像的特征描述 本书京东 优惠购书链接 https://item.jd.com/14098452.html 本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html 第16章&#xff1a;图像的特征描述 特征通常是针对图像中的目标或…

快排(霍尔排序实现+前后指针实现)(递归+非递归)

前言 快排是很重要的排序&#xff0c;也是一种比较难以理解的排序&#xff0c;这里我们会用递归的方式和非递归的方式来解决&#xff0c;递归来解决是比较简单的&#xff0c;非递归来解决是有点难度的 快排也称之为霍尔排序&#xff0c;因为发明者是霍尔&#xff0c;本来是命名…

基于Spring Boot+VUE旧物置换网站

1前台首页功能模块 旧物置换网站&#xff0c;在系统首页可以查看首页、旧物信息、网站公告、个人中心、后台管理等内容&#xff0c;如图1所示。 图1系统功能界面图 用户注册&#xff0c;在用户注册页面通过填写用户名、密码、姓名、性别、头像、手机、邮箱等内容进行用户注册&…

【linux 常用命令】

以下是一些常用的Linux命令&#xff1a; ls&#xff1a;列出当前目录的文件和文件夹。cd&#xff1a;更改当前目录。pwd&#xff1a;显示当前工作目录的路径。mkdir&#xff1a;创建一个新目录。touch&#xff1a;创建一个新文件或更新现有文件的时间戳。cp&#xff1a;复制文…

FlinkCDC介绍及使用

CDC简介 什么是CDC&#xff1f; cdc是Change Data Capture(变更数据获取)的简称。核心思想是&#xff0c;监测并捕获数据库的 变动(包括数据或数据表的插入&#xff0c;更新以及删除等)&#xff0c;将这些变更按发生的顺序完整记录下来&#xff0c;写入到消息中间件以供其它服…

C++笔记之RegisterCallback和setCallback、以及setCallback(lambda表达式)

C++笔记之RegisterCallback和setCallback、以及setCallback(lambda表达式) —— 2024-06-19 code review! 参考博文: C++笔记之RegisterCallback和setCallback、以及setCallback(lambda表达式) C++笔记之注册回调函数常见的5种情况对比 文章目录 C++笔记之RegisterCallback和…

IPv4的报头详解

1.ipv4的报头&#xff1a; 注意&#xff1a;ipv4的报头长度共有20个字节&#xff0c;数据包通过ipv4协议传输后&#xff0c;会进行封装和解封装&#xff1a; 封装&#xff1a;tcp/ip五层参考模型 应用层网络层传输层数据链路层物理层 网络层&#xff1a;tcp/udp 传输层&#…