Chrome 확장 프로그램의 영구 서비스 워커
P粉323224129
P粉323224129 2023-08-24 18:56:27
0
2
681
<p>특정 요청에 대한 양식으로 전달되는 일부 데이터를 가로채기 위해 webRequest API를 사용하고 있기 때문에 Chrome 확장 프로그램에서 내 서비스 워커를 영구 정의해야 하는데 어떻게 해야 할지 모르겠습니다. 모든 것을 시도했지만 서비스 워커가 계속 제거됩니다. </p> <p>로드를 계속 유지하고 요청이 차단될 때까지 기다리려면 어떻게 해야 합니까? </p>
P粉323224129
P粉323224129

모든 응답(2)
P粉034571623

chrome.webRequest API와 달리 chrome.webNavigation APIchrome.webNavigation APIService Worker를 깨울 수 있기 때문에 완벽하게 작동합니다. 이제 chrome.webRequest API API를 chrome의 에 넣을 수 있습니다. webNavigation.

으아악
P粉386318086

목차

  • 문제 설명

  • 해결책:

    • 악용
    离屏API
    nativeMessagingAPI
    WebSocketAPI
    chrome 메시징 API
    • 전용 탭

  • 주의

정의에 따라 서비스 워커(SW)는 지속될 수 없으며 브라우저는 특정 시간(Chrome에서는 5분)이 지나면 모든 활동/요청을 강제로 종료해야 합니다. 비활성 타이머(즉, 그러한 활동이 진행되지 않는 경우)는 30초로 훨씬 더 짧습니다.

Chromium 팀 은 현재 이 동작을 좋은 것으로 간주합니다(팀에서는 때때로 일부 측면을 완화했습니다. 예를 들어 Chrome 114는 각 메시지 후에 chrome.runtime 포트를 확장했습니다). 그러나 이는 자주 발생하지 않는 이벤트를 관찰하는 확장 프로그램에만 적용됩니다. 하루에 몇 번만 실행하므로 실행 사이의 브라우저 메모리 공간이 줄어듭니다(예: URL이 포함된 webRequest/webNavigation 이벤트 > 거의 방문하지 않는 사이트에 대한 필터링). 이러한 확장은 상태를 유지하도록 재설계될 수 있습니다(). 불행히도 그러한 짧은 서사시는 많은 경우에 지속 가능하지 않습니다.

알려진 문제

  • 문제 1: Chrome 106 이하에서는 webRequest 이벤트에 대해 소프트웨어 를 깨우지 않습니다. p>

    다른 답변에서 볼 수 있듯이 chrome.webNavigation와 같은 API를 구독해 볼 수도 있지만 작업자 스레드가 시작된 후에 발생하는 이벤트에만 도움이 됩니다.

  • 문제 2: 행사로 인해 직원이 무작위로 잠에서 깨어나지 않습니다.

    해결책은 chrome.runtime.reload()를 호출하는 것일 수 있습니다.

  • 문제 3: Chrome 109 이하에서는 이미 실행 중인 백그라운드 스크립트에서 새로운 chrome API 이벤트 의 소프트웨어 수명 주기를 연장할 수 없습니다. 즉, 30초 비활성 제한 시간의 마지막 몇 밀리초 내에 이벤트가 발생하면 코드가 비동기적으로 어떤 것도 안정적으로 실행할 수 없음을 의미합니다. 이는 사용자가 귀하의 확장 프로그램이 신뢰할 수 없다고 생각할 것임을 의미합니다.

  • 질문 4: 확장 프로그램이 원격 연결을 유지하거나 상태(변수)를 다시 빌드하는 데 오랜 시간이 걸리거나 다음과 같은 이벤트가 자주 발생하는 경우 MV2보다 성능이 저하됩니다.

    • chrome.tabs.on업데이트/활성화됨,
    • chrome.webNavigation 범위가 희귀 URL로 제한되지 않는 경우,
    • chrome.webRequest 범위가 희귀한 URL이나 유형으로 제한되지 않는 경우,
    • 모든 탭의 콘텐츠 스크립트에 대한 chrome.runtime.onMessage/onConnect 메시지.

    새 이벤트를 위한 SW를 실행하는 것은 본질적으로 새 탭을 여는 것과 같습니다. 환경을 생성하는 데 약 50ms가 걸리고, 전체 SW 스크립트를 실행하는 데 100ms(또는 코드 양에 따라 1000ms)가 걸릴 수도 있고, SW 스크립트를 읽는 데 1ms(또는 데이터에 따라 1000ms)가 걸릴 수도 있습니다. 저장 및 재구축/수화 상태). 거의 빈 스크립트라도 최소 50밀리초가 소요되는데, 이는 고작 1밀리초밖에 걸리지 않는 이벤트 리스너를 호출하는데 상당한 오버헤드입니다.

    SW는 탭을 클릭한 후 무언가를 쓰는 등 자연스러운 간격이 있는 사용자 작업에 대한 응답으로 이러한 이벤트가 생성되어 소프트웨어가 종료되고 새 이벤트가 다시 시작되어 CPU, 디스크를 소비하기 때문에 하루에 수백 번 다시 시작될 수 있습니다. , 배터리 및 일반적으로 스케일링 응답에서 눈에 띄는 지연이 자주 발생합니다.

오류를 통해 "지속적인" 서비스 워커 악용

Chrome 110에서는 버그가 발생했습니다. 비동기식 chrome API를 호출하면 작업자 스레드가 추가로 30초 동안 실행됩니다. 이 버그는 아직 수정되지 않았습니다.

//Background.js

으아아아

오프스크린 API를 사용하는 "지속적인" 서비스 워커

기고자: Kevin Augusto.

Chrome 109 이상에서는 오프스크린 API를 사용하여 오프스크린 문서를 만들고 30초 이내에 메시지를 보내 서비스 워커를 계속 실행할 수 있습니다. 현재 문서의 수명은 제한이 없지만(오디오 재생만 제한되며 우리가 사용하지 않음) 이는 향후 변경될 수 있습니다.

  • manifest.json

    으아아아
  • offscreen.html

    으아아아
  • offscreen.js

    으아아아
  • 배경.js

    으아아아

Connect nativeMessaging 호스트 시간 "영구" 서비스 워커 스레드

Chrome 105 이상에서는 chrome.runtime.connectNative를 전달하세요. 충돌이나 사용자 작업으로 인해 호스트 프로세스가 종료되면 포트가 닫히고 소프트웨어가 평소대로 종료됩니다. 포트의 onDisconnect 이벤트를 수신하여 chrome.runtime.connectNative를 다시 호출하는 것을 방지할 수 있습니다.

WebSocket이 활성화된 동안 "영구" 서비스 작업자 스레드

Chrome 116 이상: WebSocket 메시지를 30초마다 교환하여 활성 상태를 유지합니다(예: 25초마다 한 번씩).

연결 가능한 탭이 존재하는 동안 "지속적인" 서비스 워커

단점:

  • 열린 웹 탭이 필요합니다
  • 웹 스토어의 느린 검토 대기열에 대부분의 확장 프로그램을 배치하는 콘텐츠 스크립트(예: *://*/*)에 대한 광범위한 호스트 권한.
경고! 연결된 포트가 있는 경우 이 해결 방법을 사용하지 말고 아래 포트에 대해 다른 해결 방법을 사용하십시오.

경고! sendMessage를 사용하는 경우 sendMessage에 대한 해결 방법(아래)을 구현할 수도 있습니다.

  • manifest.json, 관련 부분:

    으아악

  • 백그라운드 서비스 워커 bg.js:

    으아악

  • 팝업이나 옵션과 같은 기타 모든 확장 페이지:

    으아악

sendMessage도 사용한다면

Chrome 99-101에서는 응답이 필요하지 않더라도 항상 chrome.runtime.onMessage 리스너에서 sendResponse()를 호출해야 합니다. MV3의 버그입니다. 또한 5분 이내에 이 작업을 수행해야 합니다. 그렇지 않으면 즉시 sendResponse를 호출하고 작업이 완료되면 chrome.tabs.sendMessage(탭으로) 또는 chrome.runtime.sendMessage(팝업으로)를 통해 새 메시지를 보냅니다.

이미 chrome.runtime.connect와 같은 포트를 사용하고 있는 경우

경고! 또한 서비스 워커에 더 많은 포트를 연결하는 경우 5분이 경과하기 전에(예: 295초 이내) 각 포트를 다시 연결해야 합니다. 이는 104 이전의 Chrome 버전에서 매우 중요했으며, 추가 연결 포트가 아무리 많아도 SW를 종료했습니다. Chrome 104 이상에서는 이 버그가 수정되었지만 5분 수명 주기가 변경되지 않았기 때문에 여전히 다시 연결해야 합니다. 따라서 가장 쉬운 해결 방법은 모든 버전의 Chrome 연결에서 동일한 방식으로 다시 연결하는 것입니다(예: 295초마다). .

  • 백엔드 스크립트 예:

    으아악

  • 콘텐츠 스크립트와 같은 클라이언트 스크립트의 예:

    으아악

탭이 열려 있을 때 전용 탭을 통해 "항상"

소프트웨어를 사용하는 대신 확장 페이지가 포함된 새 탭을 열어서 이 페이지가 "표시되는 배경 페이지" 역할을 하도록 하세요. 즉, 소프트웨어가 해야 할 유일한 작업은 이 탭을 여는 것뿐입니다. 작업 팝업에서 열 수도 있습니다.

으아악

ManifestV2의 영구 배경 페이지와 동일한 기능을 가지지만 a) 표시되고 b)

를 통해 액세스할 수 없습니다(chrome.extension.getBackgroundPagechrome.extension.getViews로 대체 가능).

단점:

  • 더 많은 메모리를 소비합니다.
  • 탭바 공간 낭비,
  • 사용자의 주의를 산만하게 하고,
  • 여러 확장 프로그램이 이렇게 탭을 열면 단점이 눈덩이처럼 불어나 진짜 PITA가 됩니다.

페이지에 정보/로그/차트/대시보드를 추가하면 사용자가 더 쉽게 사용할 수 있으며 탭이 실수로 닫히는 것을 방지하기 위해 beforeunload 리스너도 추가할 수 있습니다. p>

지속성에 대한 경고

영구 서비스 워커와 같은 것이 없기 때문에 상태(변수)를 저장/복원해야 하며 이러한 해결 방법에는 위에서 언급한 대로 작업자가 종료될 수 있는 제한 사항이 있습니다. 에서 상태를 유지할 수 있습니다.

단지 상태/변수 관리를 단순화하기 위해 작업자 스레드를 영구화해서는 안 됩니다. 이는 상태를 재구축하는 데 비용이 많이 들거나 이 답변의 시작 부분에 나열된 빈번한 이벤트에 빠진 경우 작업자 스레드를 다시 시작하여 악화된 성능을 복원하기 위해서만 수행됩니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿