{"id":13694497,"url":"https://github.com/Ryan-Shz/FastWebView","last_synced_at":"2025-05-03T04:30:27.110Z","repository":{"id":37335461,"uuid":"139606481","full_name":"Ryan-Shz/FastWebView","owner":"Ryan-Shz","description":"自定义本地缓存策略和资源加载策略，突破原生WebView缓存限制，实现多种缓存模式，支持离线加载和预加载，可大幅提升加载速度。","archived":false,"fork":false,"pushed_at":"2021-01-12T03:36:04.000Z","size":636,"stargazers_count":247,"open_issues_count":8,"forks_count":39,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-12T21:38:44.149Z","etag":null,"topics":["android","cache","cachewebview","offline","webview","webviewcache"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ryan-Shz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-03T15:53:41.000Z","updated_at":"2024-10-09T07:02:53.000Z","dependencies_parsed_at":"2022-08-19T11:33:13.365Z","dependency_job_id":null,"html_url":"https://github.com/Ryan-Shz/FastWebView","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ryan-Shz%2FFastWebView","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ryan-Shz%2FFastWebView/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ryan-Shz%2FFastWebView/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ryan-Shz%2FFastWebView/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ryan-Shz","download_url":"https://codeload.github.com/Ryan-Shz/FastWebView/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252144247,"owners_count":21701371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","cache","cachewebview","offline","webview","webviewcache"],"created_at":"2024-08-02T17:01:33.665Z","updated_at":"2025-05-03T04:30:26.488Z","avatar_url":"https://github.com/Ryan-Shz.png","language":"Java","funding_links":[],"categories":["Java"],"sub_categories":[],"readme":"# FastWebView\n\n[ ![Download](https://api.bintray.com/packages/ryan-shz/Ryan/fastwebview/images/download.svg) ](https://bintray.com/ryan-shz/Ryan/fastwebview/_latestVersion)![](https://img.shields.io/badge/license-MIT-green)\n\n## 背景\nAndroid原生WebView有磁盘缓存最大上限，在4.4之前只有10M，在4.4及其之后虽然提升至20M，但对频繁的H5业务场景来说，还是太小了。HTTP的缓存部分采用LRU缓存算法实现，我们在使用HTTP缓存协议对资源缓存时，太小的缓存空间很容易导致页面缓存被清除，从而重新加载。不仅浪费用户的流量，也会造成不好的用户体验。\n\n如果服务器或者客户端的开发同学对HTTP缓存协议不熟悉，就很容易导致无法高效的利用缓存。况且，就算使用了HTTP协议缓存，在使用本地缓存之前，默认需要经过一次请求来校验缓存是否过期，如果在弱网环境下就会极大的拖慢H5加载速度。\n\nFastWebView通过自定义本地缓存的方式，突破原生WebView缓存限制，提供多种缓存模式，支持预加载和离线加载，并友好的支持离线预推，可以大幅提升H5加载速度。经过千万级用户的项目实践数据证明，二次加载时长缩短100%以上，平均加载时长缩短80%以上。\n\n## 实战数据\n\n千万级日活项目的线上真实数据，屏蔽了项目隐私信息，表中的纵坐标为网页加载整体时长，单位ms。\n\n* 绿线为使用android原生webview加载网页的平均时长\n\n* 蓝线为使用FastWebView加载网页的平均时长\n\n![实战数据](data.png)\n\n## 特性\n1. 自定义本地缓存，提供多种缓存模式，突破原生webview缓存限制\n2. 提供资源拦截器支持自定义读取静态资源（比如读取assets/sdcard中的资源替换在线资源）\n3. 更方便的cookie管理（自动缓存和发布，且Cookie拦截器让Cookie添加或删除变得更简单）\n4. 支持离线加载和预加载\n5. 接入成本和侵入性低，很容易集成到现有项目\n6. 经过大型项目实战验证，功能稳定，且不断完善中\n\n## Quick Start\n\n### 导入\n\n```\nimplementation \"com.ryan.github:fastwebview:1.1.5\"\n```\n\n### 使用\n\n将原生的WebView替换为FastWebView，并选择相应的缓存模式即可。\n\n示例代码如下：\n\n```\nFastWebView fastWebView = new FastWebView(this);\n// 使用强制缓存模式\nfastWebView.setCacheMode(FastCacheMode.FORCE);\n```\n\n到这里FastWebView已经成功接入，就可以正常使用了。\n\n\u003e Tips：如果现有项目中有自定义的WebView，可将原本继承于原生WebView改为继承FastWebView。\n\u003e FastWebView在未开启缓存模式的情况下对现有代码是0侵入的。\n\n## 高级用法\n\n### 1. 缓存模式说明\n\nFast提供了以下3种缓存模式：\n\n| 缓存模式              | 描述                                                         |\n| --------------------- | ------------------------------------------------------------ |\n| FastCacheMode.DEFAULT | 默认缓存模式，和原生webview无任何差异，无任何侵入                                                 |\n| FastCacheMode.NORMAL  | 普通缓存模式，切换为OkHttp加载资源，磁盘缓存上限提升为100MB        |\n| FastCacheMode.FORCE   | 强制缓存模式，切换为OkHttp加载资源，强制缓存不被过滤器过滤的资源 |\n\n#### 1.1. 默认缓存模式\n\n使用默认缓存模式时，FastWebView和原生webview无任何差异, 不会有任何的代码侵入。\n\n```\nFastWebView fastWebView = new FastWebView(this);\n// 下面这行可以不调用，效果是一样的\nfastWebView.setCacheMode(FastCacheMode.DEFAULT);\n```\n\n#### 1.2. 普通缓存模式\n\n使用普通缓存模式时，默认的网络请求方式由HttpUrlConnection切换为OkHttp，磁盘缓存上限提升为100MB。\n\n```\nFastWebView fastWebView = new FastWebView(this);\nfastWebView.setCacheMode(FastCacheMode.NORMAL);\n```\n\n#### 1.3. 强制缓存模式\n\n使用强制缓存模式时，默认的网络请求方式由HttpUrlConnection切换为OkHttp，并且FastWebView会无视HTTP缓存协议，强制缓存所加载H5中所有不被过滤器过滤的静态资源。\n\n```\nFastWebView fastWebView = new FastWebView(this);\nfastWebView.setCacheMode(FastCacheMode.FORCE, cacheConfig);\n```\n\n默认的过滤器会过滤**除了JS/CSS/图片/文本文件外**的其他所有静态资源类型，包括**html**。下面列出了默认情况下可被强制缓存的类型：\n```\n// JavaScript\naddMimeType(\"application/javascript\");\naddMimeType(\"application/ecmascript\");\naddMimeType(\"application/x-ecmascript\");\naddMimeType(\"application/x-javascript\");\naddMimeType(\"text/ecmascript\");\naddMimeType(\"text/javascript\");\naddMimeType(\"text/javascript1.0\");\naddMimeType(\"text/javascript1.1\");\naddMimeType(\"text/javascript1.2\");\naddMimeType(\"text/javascript1.3\");\naddMimeType(\"text/javascript1.4\");\naddMimeType(\"text/javascript1.5\");\naddMimeType(\"text/jscript\");\naddMimeType(\"text/livescript\");\naddMimeType(\"text/x-ecmascript\");\naddMimeType(\"text/x-javascript\");\n// image\naddMimeType(\"image/gif\");\naddMimeType(\"image/jpeg\");\naddMimeType(\"image/png\");\naddMimeType(\"image/svg+xml\");\naddMimeType(\"image/bmp\");\naddMimeType(\"image/webp\");\naddMimeType(\"image/tiff\");\naddMimeType(\"image/vnd.microsoft.icon\");\naddMimeType(\"image/x-icon\");\n// css\naddMimeType(\"text/css\");\n// stream\naddMimeType(\"application/octet-stream\");\n```\n\u003e 注意：在此白名单外的资源类型将不会被强制缓存，**但仍支持HTTP缓存协议**。你也可以通过自定义过滤器，以实现任何你想要自动缓存的文件类型。\n##### 强制缓存模式的配置选项\n\n```\nfastWebView.setCacheConfig(new CacheConfig.Builder()\n        .setCacheDir(String fileDir)\n        .setExtensionFilter(ExtensionFilter filter)\n        .setVersion(int version)\n        .setMemorySize(int size)\n        .setDiskCacheSize(long diskCacheSize)\n        .build());\n```\n\n1. setCacheDir(String fileDir) 设置强制缓存目录\n2. setExtensionFilter(ExtensionFilter filter) 设置资源类型过滤器\n3. setVersion(int version) 设置缓存版本，默认为1\n4. setDiskCacheSize(long diskCacheSize) 设置磁盘缓存上限\n5. setMemorySize(int size) 设置内存缓存上限\n\n##### 强制缓存模式下如何更新静态资源？\n\n由于FastWebView的强制缓存模式会强制缓存静态资源文件到本地，并且优先使用本地资源。\n\n所以如果需要更新静态资源文件，需要和前端达成约定一致，当静态资源更新时，保证静态资源url地址发生改变。url变化后，FastWebView会重新从网络下载。\n\n\u003e 实际上，目前的工程实践中，前端项目一般使用webpack构建。webpack在构建成功后会自动对文件加上hash，在文件变更后hash也会自动变化。这种特性让FastWebView可以轻松的识别静态文件变化，从而实现自动更新。\n#### 资源加载拦截器\n\n\u003e 注意：ResourceInterceptor只对NORMAL和FORCE两种缓存模式生效。\n\n拦截器功能可以让你从任何自定义的文件位置加载静态资源，比如assets目录。\n\n添加拦截器方式如下：\n\n```\nFastWebView fastWebView = new FastWebView(this);\nfastWebView.addResourceInterceptor(new ResourceInterceptor() {\n    @Override\n    public WebResourceResponse load(Chain chain) {\n    \tCacheRequest request = chain.getRequest();\n    \t// 1.process request\t\n    \tWebResourceResponse response = processRequest(request);\n    \tif (response != null) {\n    \t\treturn response;\n    \t}\n    \t// 2.pass request to next interceptor\n        return chain.process(request);\n    }\n});\n```\n#### 3. Cookie选项\nFastWebView实现了Cookie数据的自动缓存和上传，并遵循HTTP中Cookie协议，无需任何开关控制。\n\n##### Cookie拦截器\n\nCookie拦截器用来拦截请求和响应获取到的Cookie列表，从而实现添加自定义Cookie的功能：\n```\nFastCookieManager cookieManager = fastView.getFastCookieManager();\ncookieManager.addRequestCookieInterceptor(CookieInterceptor interceptor);\ncookieManager.addResponseCookieInterceptor(CookieInterceptor interceptor);\n```\n\u003e 注意: FastWebView会使用原生WebView的Cookie数据源，并在内部做好数据同步。\n\u003e\n\u003e 所以完全不必担心 **CookieInterceptor** 会和 **原生的CookieManager** 之间存在数据不同步的问题。\n\n#### 4. 执行JS脚本\n\n```\nfastWebView.runJs(String function, Object... args);\n```\n\n#### 5. 预加载\n\n由于首次加载资源时，需要完整加载整个H5页面，加载速度跟原生webview无异。但我们可以使用preload来预加载页面。\n```\nFastWebView.preload(Context context, String url)\n```\n\n## 原理设计图\n\n![设计图](design.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRyan-Shz%2FFastWebView","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRyan-Shz%2FFastWebView","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRyan-Shz%2FFastWebView/lists"}