dart-lang / web

Lightweight browser API bindings built around JS static interop.
https://pub.dev/packages/web
BSD 3-Clause "New" or "Revised" License
134 stars 23 forks source link

Add support for `performance.measureUserAgentSpecificMemory()` #208

Open kenzieschmoll opened 8 months ago

kenzieschmoll commented 8 months ago

In the DevTools flutter web app, we'd like to periodically check our memory usage to take action and release resources before OOMing (https://github.com/flutter/devtools/issues/7002). To do this, I was looking at using the browser memory API: https://developer.mozilla.org/en-US/docs/Web/API/Performance/measureUserAgentSpecificMemory

This doesn't appear to be available from the Performance API in package:web: https://github.com/dart-lang/web/blob/2f13cd55f938f71bcd16c831110e3a196967337f/lib/src/dom/hr_time.dart#L39

Are there plans to support this? Is there a better way we should be checking the total memory usage for the web app?

navaronbracke commented 8 months ago

Since that API is experimental, it is not exposed by package:web, per the note in https://github.com/dart-lang/web?tab=readme-ov-file#compatibility

You might get away with using an extension / extension type?

import 'dart:js_interop';

import 'package:web/web.dart';

extension PerformanceMemory on Performance {
  @JS('measureUserAgentSpecificMemory')
  external JSFunction? get _measureUserAgentSpecificMemory;

  Future<UserAgentSpecificMemory?> measureUserAgentSpecificMemory() {
    if (_measureUserAgentSpecificMemory == null) {
      return Future<UserAgentSpecificMemory?>.value();
    }

    return (_measureUserAgentSpecificMemory!.callAsFunction() as JSPromise<UserAgentSpecificMemory>).toDart;
  }
}

@JS()
extension type UserAgentSpecificMemory._(JSObject _) implements JSObject {
  external int get bytes;

  external JSArray<UserAgentSpecificMemoryBreakdownElement> get breakdown;
}

@JS()
extension type UserAgentSpecificMemoryBreakdownElement._(JSObject _) implements JSObject {
  external JSArray<UserAgentSpecificMemoryBreakdownAttributionElement> get attribution;

  external int get bytes;

  external JSArray<JSString> get types;
}

@JS()
extension type UserAgentSpecificMemoryBreakdownAttributionElement._(JSObject _) implements JSObject {
  external UserAgentSpecificMemoryBreakdownAttributionContainerElement? get container;

  external String get scope;

  external String get url;
}

@JS()
extension type UserAgentSpecificMemoryBreakdownAttributionContainerElement._(JSObject _) implements JSObject {
  external String get id;

  external String get url;
}

Although, when I inspect if the method is defined, on my Chrome 122.0.6261.128 instance , typeof performance.measureUserAgentSpecificMemory results in undefined?

I don't think there is a different API for it though.

srujzs commented 8 months ago

This may get added back as part of #209. It's on track to be a standard, but it's marked experimental, so it depends on which way we lean. If experimental APIs lead to too many breakages, we may exclude them. @navaronbracke is correct here - you can expose your own types/APIs to workaround this.