svg动画导致持续占用CPU
1、在一次性能优化中突然发现一个svg矢量图动画导致CPU持续占用的问题,该svg在web中使用,
即使webview释放之后,CPU依然占用达到10%,6s+上测试结果
svg如下所示:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none" x="0px" y="0px" width="25px" height="25px" viewBox="0 0 25 25"> <path stroke="#777777" stroke-width="1" stroke-linejoin="round" stroke-linecap="round" fill="none" stroke-dasharray="64,6" stroke-dashoffset="0" d="
M 3.4 5.65
Q 9.5 2.2 11.2 1.15 12.6 0.4 14 1.3
L 21.65 5.75
Q 22.9 6.65 22.85 8.2
L 22.85 17.4
Q 22.8 18.6 21.5 19.25 14.85 23.25 13.6 23.9 12.3 24.55 10.8 23.7 4.3 19.9 3.1 19.1 2.35 18.6 2.15 17.75
L 2.1 7.95
Q 2.1 7.25 2.75 6.35
L 3.4 5.65 Z">
<animate attributeName="stroke-dashoffset" begin="0s" dur="1.5s" from="0" to="70" repeatCount="indefinite"/>
</path> <path stroke="#777777" stroke-width="1" stroke-linejoin="round" stroke-linecap="round" fill="none" stroke-dasharray="37,4" stroke-dashoffset="41" d="
M 7.15 8.35
L 11.7 5.7
Q 12.55 5.25 13.35 5.8
L 17.85 8.4
Q 18.6 8.95 18.55 9.85
L 18.55 15.25
Q 18.5 15.95 17.75 16.35 13.85 18.7 13.1 19.05 12.35 19.45 11.45 18.95
L 6.95 16.25
Q 6.55 16 6.4 15.45
L 6.35 9.7
Q 6.35 9.25 6.75 8.75
L 7.15 8.35 Z">
<animate attributeName="stroke-dashoffset" begin="0s" dur="1.5s" from="41" to="0" repeatCount="indefinite"/>
</path> </svg>
注意该动画的时间是无限长,指定时间结束之后,CPU将不再占用,因此这可能是webkit中的bug。
svg是HTML5中的标准,每个webview都应该支持。未测试WKWebView兼容情况
2、问题解决
可以看到该svg是由web中的css文件引用,真正的请求是:https://egame.gtimg.cn/club/pgg/v2.5/v2/img/global/loading-fecf2b8eea.svg
为了可以将这个问题解决掉,在前端暂无法修复的情况下,我选择使用NSURLProtocol中的方法,hook该请求,并返回404
具体操作使用了一个OHHTTPStubs的框架,代码如下:
+ (void)addLoadingSVG_Patch
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { NSString *url = [request.URL description];
if([url hasSuffix:@"svg"] && [[url lastPathComponent] hasPrefix:@"loading"])
{
QG_Event(MODULE_LIVE_ASS, @"patch fuck loading animated svg request!!! = %@", request);
return YES;
}
return NO;
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) { return [OHHTTPStubsResponse responseWithFileAtPath:@""
statusCode:404 headers:@{@"Content-Type":@"image/jpeg"}];
}];
}
问题解决
3、NSURLProtocol是苹果的一个协议,其中通过 + (BOOL)canInitWithRequest:(NSURLRequest *)request; 这个方法返回是否要手动接管这个请求
通常web的离线缓存基于此实现,接管请求之后,需要自己实现请求的代码,并将返回结果通过NSURLProtocol的client对象回调给上层,例如:
在startLoading方法中,实现请求,并返回结果。
- (void)startLoading
{
self.clientRunLoop = CFRunLoopGetCurrent();
NSURLRequest* request = self.request;
id<NSURLProtocolClient> client = self.client; if (!self.stub)
{
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"It seems like the stub has been removed BEFORE the response had time to be sent.",
NSLocalizedFailureReasonErrorKey,
@"For more info, see https://github.com/AliSoftware/OHHTTPStubs/wiki/OHHTTPStubs-and-asynchronous-tests",
NSLocalizedRecoverySuggestionErrorKey,
request.URL, // Stop right here if request.URL is nil
NSURLErrorFailingURLErrorKey,
nil];
NSError* error = [NSError errorWithDomain:@"OHHTTPStubs" code:500 userInfo:userInfo];
[client URLProtocol:self didFailWithError:error];
if (OHHTTPStubs.sharedInstance.afterStubFinishBlock)
{
OHHTTPStubs.sharedInstance.afterStubFinishBlock(request, self.stub, nil, error);
}
return;
} OHHTTPStubsResponse* responseStub = self.stub.responseBlock(request); if (OHHTTPStubs.sharedInstance.onStubActivationBlock)
{
OHHTTPStubs.sharedInstance.onStubActivationBlock(request, self.stub, responseStub);
} if (responseStub.error == nil)
{
NSHTTPURLResponse* urlResponse = [[NSHTTPURLResponse alloc] initWithURL:request.URL
statusCode:responseStub.statusCode
HTTPVersion:@"HTTP/1.1"
headerFields:responseStub.httpHeaders]; // Cookies handling
if (request.HTTPShouldHandleCookies && request.URL)
{
NSArray* cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:responseStub.httpHeaders forURL:request.URL];
if (cookies)
{
[NSHTTPCookieStorage.sharedHTTPCookieStorage setCookies:cookies forURL:request.URL mainDocumentURL:request.mainDocumentURL];
}
} NSString* redirectLocation = (responseStub.httpHeaders)[@"Location"];
NSURL* redirectLocationURL;
if (redirectLocation)
{
redirectLocationURL = [NSURL URLWithString:redirectLocation];
}
else
{
redirectLocationURL = nil;
}
[self executeOnClientRunLoopAfterDelay:responseStub.requestTime block:^{
if (!self.stopped)
{
// Notify if a redirection occurred
if (((responseStub.statusCode > 300) && (responseStub.statusCode < 400)) && redirectLocationURL)
{
NSURLRequest* redirectRequest = [NSURLRequest requestWithURL:redirectLocationURL];
[client URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:urlResponse];
if (OHHTTPStubs.sharedInstance.onStubRedirectBlock)
{
OHHTTPStubs.sharedInstance.onStubRedirectBlock(request, redirectRequest, self.stub, responseStub);
}
} // Send the response (even for redirections)
[client URLProtocol:self didReceiveResponse:urlResponse cacheStoragePolicy:NSURLCacheStorageNotAllowed];
if(responseStub.inputStream.streamStatus == NSStreamStatusNotOpen)
{
[responseStub.inputStream open];
}
[self streamDataForClient:client
withStubResponse:responseStub
completion:^(NSError * error)
{
[responseStub.inputStream close];
NSError *blockError = nil;
if (error==nil)
{
[client URLProtocolDidFinishLoading:self];
}
else
{
[client URLProtocol:self didFailWithError:responseStub.error];
blockError = responseStub.error;
}
if (OHHTTPStubs.sharedInstance.afterStubFinishBlock)
{
OHHTTPStubs.sharedInstance.afterStubFinishBlock(request, self.stub, responseStub, blockError);
}
}];
}
}];
} else {
// Send the canned error
[self executeOnClientRunLoopAfterDelay:responseStub.responseTime block:^{
if (!self.stopped)
{
[client URLProtocol:self didFailWithError:responseStub.error];
if (OHHTTPStubs.sharedInstance.afterStubFinishBlock)
{
OHHTTPStubs.sharedInstance.afterStubFinishBlock(request, self.stub, responseStub, responseStub.error);
}
}
}];
}
} - (void)stopLoading
{
self.stopped = YES;
}
svg动画导致持续占用CPU的更多相关文章
- shopex-百度爬虫抓取过于频繁导致php-cgi占用CPU过高的解决办法
步骤 1.开启slowlog:php-fpm里修改配置 观察slowlog里的超时文件,然后修改相应超时文件 2.1修改完后,仍然无效,查看access.log,发现大量如下的请求 220.181.1 ...
- JAVA进程占用CPU分析
在一次生产环境中,服务器负载报警,SSH登录上看到CPU占用很高. 1.执行top命令,看到进程号为9737的进程持续占用CPU 2.怀疑是否是进程配置的内存不够了,引发了fullGC导致CPU占用高 ...
- tomcat+java的web程序持续占cpu问题调试
原文出处:http://www.blogjava.net/hankchen 现象: 在tomcat中部署java的web应用程序,过一段时间后出现tomcat的java进程持续占用cpu高达100%, ...
- tomcat+java的web程序持续占cpu高问题调试【转】
转自 tomcat+java的web程序持续占cpu问题调试 - 像风一样的自由 - CSDN博客http://blog.csdn.net/five3/article/details/28416771 ...
- PHP CGI 进程占用CPU过高导致CPU使用达到100%的另类原因
由于使用的华为云的CDN加速,结果发现我的阿里云服务器突然卡顿,网页打开极慢.登陆华为云CDN管理后台发现最高带宽占用30M,流量短时间内达到10GB以上,这么大的流量我的服务器肯定扛不住啊.于是还跟 ...
- 记一次JAVA进程导致Kubernetes节点CPU飙高的排查与解决
一.发现问题 在一次系统上线后,我们发现某几个节点在长时间运行后会出现CPU持续飙升的问题,导致的结果就是Kubernetes集群的这个节点会把所在的Pod进行驱逐(调度):如果调度到同样问题的节点上 ...
- 服务器CPU又爆了?Linux快速排查Java程序占用CPU很高的方法
这个问题可以说是 Java 面试的高频面试题了,有很多面试官都喜欢问这个问题,问题可能是下面这样的. 线上一台服务器 CPU 使用率100% 了,如果你碰到这样的情况,如何排查并找到问题原因? 1.场 ...
- memcache占用CPU过高的解决办法
Simon最近为公司服务器操碎了心 , 先是mysqld进程占用CPU过高 , 导致服务器性能变低 ,网站打开太慢.通过增加max_connections及table_cache解决了问题 ,随后发现 ...
- 关于linux系统CPU篇--->不容易发现的占用CPU较高进程
1.系统的CPU使用率,不仅包括进程用户态和内核态的运行,还包括中断处理,等待IO以及内核线程等等.所以,当你发现系统的CPU使用率很高的时候,不一定能找到相对应的高CPU使用率的进程 2.案例分析, ...
- 转 JVM找出占用CPU最高的线程
这两天客户这边有一台服务器一到下午3点左右就开始卡住,页面无法访问,服务器CPU占用达到300%多开始以为只是可能只是意外事件,重启一下就好,但是发现重启之后没几分钟服务器马上又反应无法访问,我就开始 ...
随机推荐
- 局部区块多个报表 TAB 页切换及局部区块的参数查询
在企业的业务系统中,如何从纷繁复杂的数据中抽丝剥茧看到关键数据信息呢?一个重要的途径就是将企业和各部门运营中关键的 KPI 集中在一起显示,同时尽量省去在企业的各个业务系统中分别查找数据. 下面是我近 ...
- 并发系列64章(TPL 数据流(二))第八章
前言 续第七章. 正文 数据流块的并行处理 数据流块在网格上本身就是并行的,为什么这么说呢? 加入有两个数据库,他们链接在一起,然后给他们post数据. 当数据流块一在运行的时候,数据流块二也在执行, ...
- js中“??“和“?.“怎么用?
??:空值合并操作符 逻辑操作符,左侧为null和undefined时,才返回右侧的数const sum = null ?? 12console.log(sum);//输出12const sum1 = ...
- 妙用 drop-shadow 实现线条光影效果
本文将介绍一种利用 CSS 滤镜 filter 的 drop-shadow(),实现对 HTML 元素及 SVG 元素的部分添加阴影效果,以实现一种酷炫的光影效果,用于各种不同的场景之中.通过本文,你 ...
- idea引用lombok一直不成功
idea引用lombok一直不成功 比如想使用lombok的@data注解一直报错,尽管已经声明了import lombok.Data,且在pom里面也增加了lombok依赖,但是就是不成功的时候 建 ...
- 力扣682(java)-棒球比赛(简单)
题目: 你现在是一场采用特殊赛制棒球比赛的记录员.这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分. 比赛开始时,记录是空白的.你会得到一个记录操作的字符串列表 ops,其中 ops ...
- 力扣670(java)-最大交换(中等)
题目: 给定一个非负整数,你至多可以交换一次数字中的任意两位.返回你能得到的最大值. 示例 1 : 输入: 2736输出: 7236解释: 交换数字2和数字7.示例 2 : 输入: 9973输出: 9 ...
- 甘肃政法大学AI协会
甘肃政法大学AI协会成员博客 甘肃政法大学AI协会 简介:甘肃政法大学AI协会正式成立于2022年6月30日,是在院团委领导下,人工智能与大数据发展环境为前提的实践性学生社团,是面向全校同学科技创新类 ...
- InnoDB之UNDO LOG介绍
简介: undo log是InnoDB事务特性的重要组成部分.当对记录做增删改操作就会产生undo记录,undo记录会记录到单独的表空间中. 本文将从代码层面对undo log进行一个简单的介绍:主要 ...
- Apsara Stack 技术百科 | 可运营的行业云,让云上资源跑起来
简介:企业级云管理平台,如何打造千人千面的个性化体验,从应用.云资源.硬件等进行全局智能优化,实现资源配置的最佳配比,构建精细化运营能力? 距离第一例新冠疫情病例的发现,不知不觉中已经过去两年, ...