Participants
Yoav Weiss, Dave Pifke, Nic Jansma, Noam Helfman, Noam Rosenthal, Sean Feng, Benjamin De Kosnik, Michal Mocny, Michelle Vu, Thomas Kelly, Steven Bougon, Nicolás Peña Moreno, Peter Perlepes
Next Call
December 3rd at 10am PST / 1pm PST
Agenda
Case study: Wikipedia preview popup extension - Noam Rosenthal
- Presentation: Optimizing MediaWiki Preview Popups
- (https://www.mediawiki.org/wiki/Extension:Popups)
- Performance challenges of developing real-world popups, and how/which improvements in the web platform could help
- Noam: Freelance web developer, in this case working with Wikipedia
- ... Idea was to look at existing popular web feature (Wikipedia preview popups), see what’s missing in web platform to make this easier in the future
- … Everytime there’s new concepts like popovers, there are performance problems and solutions that are non-standard
- … Research into what the web platform could provide
- … When you hover or focus on a link, you see a balloon with content from the next page, snippet of text and thumbnail
- … UI requirements such as clipping the image, cursor appears to mouse, place based on viewport, and stacks on top of the navigation elements
- … Stacking vs. Placement dilemma: Does it go in tree or out of tree
- … Out of the tree requires measurement
- … Layout thrashing is difficult to make go away if there’s any measurement
- … Due to JavaScript execution delays, by the time you get client rects, you could be off
- … Contributes to layout thrashing and jank
- … Top layer research (https://github.com/whatwg/html/issues/4633) separates ???
- … popper.js find a way to position a popup relative to another element, can cause layout thrash, part of Bootstrap (3% web usage)
- … “relative-to” proposal as well
- … Tried to use MouseEvent.offsetX to find position of cursor, they have bugs, FF is different from Chromium and Safari
- … TIL: Only way to totally remove thrashing is to totally remove synchronous measurements
- … Batching them together reduces them but does not remove them
- Yoav: Would an async measurement API have helped here? Or would the response return too late?
- Noam: It would help but not be optimal. If you had something like ResizeObserver but for position, it would be one solution, if it worked on coordinates but not sizes
- Yoav: And IntersectionObserver does not help here
- Noam: IO does not tell where an element is
- … Might want to have a PositionObserver as an intermediate solution ,but I was trying to solve popups at a high level.
- … Clipping: SVG used by Wikipedia, requires a lot of code
- … Tried to replace with modern clip-path, but polygons don’t have rounded corners, and paths only have absolute coordinates, so you can’t make a responsive balloon
- … I was able to mimic the behavior with polygon here since it only needed a 2px radius, so I just switched to a straight line
- … Working with CSS WG on a new shape
- … Overriding default behavior, i.e. Title attribute has a default behavior for a tooltip
- … On wikipedia, JS removes the title attribute and reinstated it when the popup is hidden
- … Code appears in profiler, new style calculation in case something relies on the title attribute for styling
- … Looked at web usage, Bootstrap tooltips do this, on hover it removes the title attribute
- … What I would expect to happen is preventDefault could be used
- … preventDefault behavior is not standard and does nothing on mouseover
- Yoav: Is any browser doing what you think is the right thing in preventDefault on mouseover?
- Noam: No
- Yoav: Could be an implementation bug on all three
- Noam: Websites are built with the preventDefault behavior in mind, like in the example link to bootstrap-tooltip
- Noam Helfman: From what I remember, tooltips are implemented using title or JavaScript, are not considered accessible
- Noam R: Preview popups are accessible, you can reach them with focus but they’re aria-hidden
- Thomas: They’re pulling from content that the link is referencing -- it’s a navigation away
- Noam: Titles in general are sometimes discouraged. For Wikipedia, when Popup Preview is not available the tooltip (via title) works
- … Looked for suboptimal but viable solutions
- … First thing was to do all sync measurements at the event handler, reduces some thrashing but not 100%
- … Still needs to use getClientRects() which does too many things, needs to calculate transforms, etc. All I care about is the hit rect from my mouse event, but I still have to call getClientRects()
- … Next, I’m using a polygon with semi-rounded corners, OK for this UI but if a designer wanted different rounding that wouldn’t be available
- … Finally I’m removing all title attributes which works for MediaWiki, but might not be OK for libraries like bootstrap
- … Feature requests: Solution for popovers (stacking vs. placement)
- … Fix MouseEvent.offset[X|Y]
- … Flexible shape clip-path
- … preventDefault for mouseover should disable native tooltip
- … Main takeaway for this group is not just about monitoring, but sometimes performance is about fixing bugs and allowing forms of expression
- Yoav: One more question about offsetXY issues, currently we have different behavior in Firefox vs. Chrome/Safari, do we have breakage in Firefox about that different behavior?
- Noam: There are bugs reported, and many people just recommend to not use it. StackOverflow answers often suggest getBoundingClientRect() -- which is a frequent answer, they don’t have a solution so they recommend it, causing performance problems
- Noam Helfman: Would using MutationObserver(?) work here
- Noam R: You still need to measure it somehow, you need ResizeObserver. Just doing one sync measurement would help.
- … Mutations don’t consider scrolling, images loading, fonts loading
- Noam H: Correlated with IntersectionObserver and events, it becomes a heuristic
- Gilles: My main comment for this particular is how difficult it is to do the good thing and how easy it is to do the bad thing. We frequently have performance reviews and say “please don’t use that API”, but in some cases this is the only thing available to use
- … Very advanced CSS and JS knowledge required to do this properly
- … Maybe we should warn people more about expensive JS functions that are used frequently
- Yoav: What I can imagine us (as web platform) is assuming we fix those things, people won’t necessarily adopt the fix, but PR those fixes to the libraries to help make them more performant
- Noam: I think library developers want to do the right thing, e.g. jquery using offsetX, there was already a fix. I think people want to do the right thing.
- Yoav: Most of the issues you mentioned are not things this working group can solve, beyond that what other low-hanging fruit is out there?
- Noam: I think going back to the performance WG, besides being advocates, having wider knowledge and conversations with other groups, I would say measuring and alerting about layout thrashing and sync measurement would help. Maybe even a performance entry for that.
- … Any time there was a style calculation/layout that didn’t come from painting, this should be a yellow flag.
- Yoav: Flagged in dev tools in some modes, but not in the wild. And this kind of measurement is highly dependent on user interaction, and may not be seen in the lab
- Noam: One thing I found if you have a perf review of a website about jankiness, look for usage of getBoundingClientRect, smoking gun
- Yoav: Part I’m having trouble with is if there’s another different async API that could be a replacement, or there will still be cases where get getBoundingClientRect() would still be needed
- Noam: It’s an API that might get called a lot. Trying to synchronize position with JS, would still be hard. The real solution is to figure out a way to add popups that get stacked with the whole page. Several solutions to that that would let the browser lay out that element. Any other solution would require JS on scroll.
- Benjamin: Was curious about what Gilles said is JS libraries doing the wrong things, are there examples?
- Noam: My examples about popper and bootstrap-tooltip, they’re doing the wrong thing but that’s just because there’s not another solution
- Yoav: Right order would be creating a reasonable alternative, then ask/PR them to move to it.
Issue Triage
- Yoav: Currently, they’re all returning 0, probably not what we want them to
- … Discussion one what we should be returning
- … Issue coalesced on returning values as close as possible to the transferred sizes
- … responseBody in Fetch has equivalence to encoded and decoded body sizes
- … Does not have equivalence to transferSize
- … Then when a SW is putting together various response objects, we could take those values and report them
- … Question to the group, does this make sense?
- … From my perspective the proposal makes general sense, the thing that scares me are the Fetch integration pieces
- … We’ll need ResourceTiming to operate on a response object in order to make use of those parameters
- Nicolás: Do we know what other browsers do?
- Yoav: Safari doesn’t implement sizes, Firefox returns 0
- Nicolás: We want to fix this in the spec first
- Yoav: Fixing it may require full Fetch integration
- Nic: Could we align with Fetch spec’s concepts without fully aligning the whole spec with Fetch?
- Yoav: Maybe there’s a path forward with integrating the Response object in the processing model and reporting those values
- Yoav: Sam Weiler pointed out that the document claims to be normative, but it’s just documentation. Xiaoxian recommended to obsolete the document. Haven’t looked lately.
- … Might be worthwhile for someone to go over it and determine that. Anyone feels like they want to take on that task?
- Nic: Do we want to maintain that document?
- Yoav: If it’s indeed out-of-date, we should probably obsolete it. Maybe the right place for it is in MDN or another developer-facing venue
- Nicolás: Has anyone used this document?
- Nic: Analytics?
- Yoav: Has anyone looked at this document?
- <crickets>
- Yoav: Might be the right call to obsolete it.
- Nic: From GH traffic analytics - 3 unique visitors, the people that filed the issue
- Yoav: Can ask around Chrome folks to see if they think it’s useful and want to maintain it.
- … Benjamin, I believe the original motivation for this was from Mozilla. Can you ask around on the Mozilla side?
- Benjamin: Will do. You have my support to deprecate this.
- Nic: Marcos proposed moving it to MDN in 2018.
- Yoav: We can settle on obsoleting this unless something says it’s required