如何有效提升WebView的加载速度
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何有效提升WebView的加载速度相关的知识,希望对你有一定的参考价值。
在做混合应用的时候,有几个痛点,一个是无网络无法使用,还有一个是受网络环境影响的网页加载速度。今天就这两个问题,和大家交流一下自己的经验。离线缓存
这个比较容易,开启webView的缓存功能就可以了。
WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(true);
settings.setDatabaseEnabled(true);
settings.setDomStorageEnabled(true);//开启DOM缓存,关闭的话H5自身的一些操作是无效的settings.setCacheMode(WebSettings.LOAD_DEFAULT);
这边我们通过setCacheMode方法来设置WebView的缓存策略,WebSettings.LOAD_DEFAULT是默认的缓存策略,它在缓存可获取并且没有过期的情况下加载缓存,否则通过网络获取资源。这样的话可以减少页面的网络请求次数,那我们如何在离线的情况下也能打开页面呢,这里我们在加载页面的时候可以通过判断网络状态,在无网络的情况下更改webview的缓存策略。
ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();if(info.isAvailable())
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
else
settings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);//不使用网络,只加载缓存
这样我们就可以使我们的混合应用在没有网络的情况下也能使用一部分的功能,不至于什么都显示不了了,当然如果我们将缓存做的更好一些,在网络好的时候,比如说在WIFI状态下,去后台加载一些网页缓存起来,这样处理的话,即使在无网络情况下第一次打开某些页面的时候,也能将该页面显示出来。
当然缓存资源后随之会带来一个问题,那就是资源无法及时更新,WebSettings.LOAD_DEFAULT中的页面中的缓存版本好像不是很起作用,所以我们这边可能需要自己做一个缓存版本控制。这个缓存版本控制可以放在APP版本更新中。
if (upgrade.cacheControl > cacheControl)
webView.clearCache(true);//删除DOM缓存
VersionUtils.clearCache(mContext.getCacheDir());//删除APP缓存
try
mContext.deleteDatabase("webview.db");//删除数据库缓存
mContext.deleteDatabase("webviewCache.db");
catch (Exception e)
预加载
有时候一个页面资源比较多,图片,CSS,js比较多,还引用了JQuery这种庞然巨兽,从加载到页面渲染完成需要比较长的时间,有一个解决方案是将这些资源打包进APK里面,然后当页面加载这些资源的时候让它从本地获取,这样可以提升加载速度也能减少服务器压力。重写WebClient类中的shouldInterceptRequest方法,再将这个类设置给WebView。
webView.setWebViewClient(new WebViewClient()
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url)
if (url.contains("[tag]"))
String localPath = url.replaceFirst("^http.*[tag]\\\\]", ""); try
InputStream is = getApplicationContext().getAssets().open(localPath);
Log.d(TAG, "shouldInterceptRequest: localPath " + localPath);
String mimeType = "text/javascript"; if (localPath.endsWith("css"))
mimeType = "text/css";
return new WebResourceResponse(mimeType, "UTF-8", is);
catch (Exception e)
e.printStackTrace(); return null;
else
return null;
);
这里我们队页面中带有特殊标记的请求进行过滤替换,也就是上面代码中的[tag],这个可以跟做后台开发的同事约定好来就行了。对图片资源或者其他资源进行替换也是可以的。补充一个小点可以通过settings.setLoadsImagesAutomatically(true);来设置在页面装载完成之后再去加载图片。
H5优化
android的OnPageFinished事件会在Javascript脚本执行完成之后才会触发。如果在页面中使 用JQuery,会在处理完DOM对象,执行完$(document).ready(function() );事件自会后才会渲染并显示页面。而同样的页面在iPhone上却是载入相当的快,因为iPhone是显示完页面才会触发脚本的执行。所以我们这边的解决方案延迟JS脚本的载入,这个方面的问题是需要Web前端工程师帮忙优化的,网上应该有比较多LazyLoad插件,这里放一个比较老的链接Painless JavaScript lazy loading with LazyLoad,同样也放上一小段前端代码,仅供参考。
<script src="/css/j/lazyload-min.js" type="text/javascript"></script><script type="text/javascript" charset="utf-8">
loadComplete() //instead of document.read();
function loadscript()
LazyLoad.loadOnce([ \'/css/j/jquery-1.6.2.min.js\', \'/css/j/flow/jquery.flow.1.1.min.js\', \'/css/j/min.js?v=2011100852\'
], loadComplete);
setTimeout(loadscript,10);</script> 参考技术A 浏览器的作用就是将得到的数据显示出来,跟你得到文本流再在textview中显示一样,你说的渲染太耗时除非是你过去网络资源时没有开辟子线程,或者要显示的图形或者js太复杂。
另外webview相当于你使用了一个系统内置的简单浏览器,也就是说只具备基础的显示功能,没法排版或者加速的,如果需要显示复杂网页还是通过intent调用其他浏览器比较好。
如何提升页面加载速度,并简述原理
页面的加载过程主要分为下载、解析、渲染三个步骤,下面从这三个方面阐述提升加载速度的方法:
1、加快文件下载速度,减小资源文件下载对页面解析的阻塞。页面加载过程首先会下载 HTML 文件,然后自上而下开始解析,解析过程中如果遇到外部资源则会开始下载,直至下载完成才会继续解析。所以,加快文件下载速度方式是有效的提升页面加载速度的方法。具体可以是
1)通过设置 CDN、HTTP 缓存等方式,减少 HTTP 传输时间;
2)对文件进行压缩,减小文件体积;
3)对 script、CSS 文件引用标签设置异步下载属性,避免对 HTML 文件解析产生阻塞
2、将样式写在 head 中,将 JS 代码或文件引用写在 body 的最后。
在 HTML 文件下载的过程中,会同步的对文件流进行解析成 DOM 结构,当遇到 CSS 代码时,会将其解析成 CSSOM 树;当遇到 JS 脚本时,会将其同步执行,并且阻塞继续解析,执行之后方才继续解析。最后,将 DOM 和 CSSOM 渲染至页面上。所以,将样式写在 head 中,可以尽早地构建 CSSOM 树;将 JS 代码写在 body 最后,不会对 DOM 解析造成阻塞,可以最快地完成页面地构建
3、尽可能地提升浏览器渲染速度。包括
1)避免出现冗余 HTML 标签,提升 DOM 结构地构建速度;
2)精简 CSS 样式及选择器,提升 CSSOM 构建及匹配速度;
3)如果是单页面应用,则页面结构依赖 JS 的执行。可以优化 JS 代码,尽早输出首屏结构;或采用服务端渲染的方式,直接传输 HTML 结构,减少首屏时间
以上是关于如何有效提升WebView的加载速度的主要内容,如果未能解决你的问题,请参考以下文章
如果url有效,如何检查iphone应用程序然后加载WebVIew else show alert