在颤振网络上缓存图像,是否需要?

Ora*_*nge 8 flutter flutter-web

由于CachedNetworkImage不在 flutter web 上工作,在移植时,我尝试使用它,但我的问题是我们真的需要它吗?或者我们只使用 Image。网络和浏览器和服务工作者将处理缓存部分(然后由服务器的响应头设置,例如 cache-control="max-age=43200, public"

这用于我正在从事的食品配送项目,https://www.santaiyamcha.com

下面是我用来替换 CachedNetworkImage 的类,它似乎不能很好地工作。

import 'package:flutter/material.dart';
import 'package:http/http.dart';

import 'package:http_extensions_cache/http_extensions_cache.dart';
import 'package:http_extensions/http_extensions.dart';

/// Builds a widget when the connectionState is none and waiting
typedef LoadingBuilder = Widget Function(BuildContext context);

/// Builds a if some error occurs
typedef ErrorBuilder = Widget Function(BuildContext context, Object error);

class MeetNetworkImage extends StatelessWidget {
  /// Image url that you want to show in your app.
  final String imageUrl;

  /// When image data loading from the [imageUrl],
  /// you can build specific widgets with [loadingBuilder]
  final LoadingBuilder loadingBuilder;

  /// When some error occurs,
  /// you can build specific error widget with [errorBuilder]
  final ErrorBuilder errorBuilder;

  final double scale;

  final double width;
  final double height;
  final Color color;

  final FilterQuality filterQuality;

  final BlendMode colorBlendMode;

  final BoxFit fit;
  final AlignmentGeometry alignment;

  final ImageRepeat repeat;

  final Rect centerSlice;
  final bool matchTextDirection;

  /// Whether to continue showing the old image (true), or briefly show nothing
  /// (false), when the image provider changes.
  final bool gaplessPlayback;

  final String semanticLabel;
  final bool excludeFromSemantics;

  MeetNetworkImage({
    @required this.imageUrl,
    this.loadingBuilder = null,
    this.errorBuilder = null,
    this.scale = 1.0,
    this.height,
    this.width,
    this.color = const Color(0xFDFFFF),
    this.fit = BoxFit.fill,
    this.alignment = Alignment.center,
    this.repeat = ImageRepeat.noRepeat,
    this.semanticLabel,
    this.centerSlice,
    this.colorBlendMode,
    this.excludeFromSemantics = false,
    this.filterQuality = FilterQuality.low,
    this.matchTextDirection = false,
    this.gaplessPlayback = false,
  })  : assert(imageUrl != null),
        assert(alignment != null),
        assert(repeat != null),
        assert(matchTextDirection != null);

  Future<Response> getUrlResponse() {
    /*
    //The caching part  I tried, does not seems working
    final client = ExtendedClient(
      inner: Client(),
      extensions: [
        CacheExtension(
          //logger: Logger("Cache"),
          defaultOptions: CacheOptions(
            expiry: const Duration(hours: 168),
            // The duration after the cached result of the request will be expired.
            //forceUpdate: false, // Forces to request a new value, even if an valid cache is available
            //forceCache: false, // Forces to return the cached value if available (even if expired).
            //ignoreCache: true, //Indicates whether the request should bypass all caching logic
            //returnCacheOnError: true, //If [true], on error, if a value is available in the  store if is returned as a successful response (even if expired).
            keyBuilder: (request) => "${request.method}_${imageUrl.toString()}",
            // Builds the unqie key used for indexing a request in cache.
            store: MemoryCacheStore(),
            // The store used for caching data.
            shouldBeSaved: (response) =>
                response.statusCode >= 200 && response.statusCode < 300,
          ),
        )
      ],
    );

    return client.get(imageUrl);
     */
    return get(imageUrl);
  }

  Widget getLoadingWidget(BuildContext context) {
    if (loadingBuilder != null) {
      return loadingBuilder(context);
    } else
      return Container(
          height: height, width: width,
          child: Center(
            child: CircularProgressIndicator()
          )
          /*Image.asset(
          'assets/img/loading4.gif',
          height: height,
          width: width,
          fit: BoxFit.contain,
        ),*/
          );
  }

  Widget getErrorWidget(BuildContext context, String error) {
    if (errorBuilder != null) {
      return errorBuilder(context, error);
    } else
      return Center(child: Icon(Icons.error));
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: getUrlResponse(),
      builder: (BuildContext context, AsyncSnapshot<Response> snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
            return getLoadingWidget(context);
          case ConnectionState.active:
          case ConnectionState.done:
            if (snapshot.hasError)
              return getErrorWidget(context, snapshot.error);
            if (!snapshot.hasData)
              return getErrorWidget(context, snapshot.error);
            //return getLoadingWidget(context);
            return Image.memory(
              snapshot.data.bodyBytes,
              scale: scale,
              height: height,
              width: width,
              color: color,
              fit: fit,
              alignment: alignment,
              repeat: repeat,
              centerSlice: centerSlice,
              colorBlendMode: colorBlendMode,
              excludeFromSemantics: excludeFromSemantics,
              filterQuality: filterQuality,
              gaplessPlayback: gaplessPlayback,
              matchTextDirection: matchTextDirection,
              semanticLabel: semanticLabel,
            );
        }
        return Container();
      },
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

你有什么建议?

Xih*_*uny 8

我在用FadeInImage.memoryNetwork。它运行良好。浏览器处理缓存部分。


小智 4

不。这是 Google Chrome 的问题,它更喜欢“缓存控制”而不是电子标签或上次修改标头。就我而言,我使用的是基于电子标签进行缓存的 Firefox。所以事情就是这样。

如果您使用 setState((){}) 或 flutter 引擎由于某种原因调用 setState,则会重建图像,如果图像未缓存,则会再次获取。为了防止这种情况,请使用标头cache-control: max-age=<any value greater than 0>,它在 Chrome 中可以正常工作。

或者只是使用 Web 渲染器 canvaskit - 构建应用程序flutter build web --web-renderer canvaskit

我根据我的经验得出这个结论,但我在任何地方都找不到它,希望它有帮助:)