GeezerVison is showing github.com — [Bug]: webagg backend uses non-existent unload event · Issue #32393 · matplotlib/matplotlib
[Bug]: webagg backend uses non-existent unload event #32393
Description
Bug summary
The webagg backend uses the onunload attribute of the image to close the websocket:
|
this.imageObj.onunload = function () { |
|
fig.ws.close(); |
|
}; |
I cannot find any such event for Images, for its parent HTMLElement interface, or for its parent Element class, or even the Node ABC.
The docs for the unload event say that it is only on the global Window interface, with onunload on the body, frameset, and svg elements. It is also not recommended for use.
Code for reproduction
In the browser console:
var img = new Image();
img.on<TAB>
Actual outcome
There is no onunload in the autocomplete in the browser console.
Expected outcome
We should remove the onunload entirely, but I am uncertain as to whether we should be closing the websocket explicitly somewhere else.
Matplotlib Version
main
Matplotlib Backend
WebAgg
Installation
git checkout
Activity
kokhlo commented on Sep 26, 2026
Confirmed — onunload doesn't exist anywhere on the Image prototype chain (HTMLImageElement → HTMLElement → Element → Node), so the assignment at mpl.js:83-85 is a plain expando property that no browser has ever invoked. It's been dead code since it was introduced.
Re: your uncertainty about closing the websocket explicitly — I don't think it's needed:
- On page teardown the browser is required to close all open WebSocket connections, and the tornado side already handles that path:
WebSocketHandler.on_close → FigureManagerWebAgg.remove_web_socket cleans up the server-side set.
- For nbagg, the comm is closed by Jupyter's own comm lifecycle (
comm.on_close in backend_nbagg.py), independent of this handler.
So removing the handler outright is behavior-neutral (it never fired) and leaves the real cleanup paths untouched. I'll push a PR removing it shortly.
Metadata
Metadata
Development
No branches or pull requestsIssue actions