美文网首页
性能优化一

性能优化一

作者: 前年的邂逅_Jerry | 来源:发表于2018-03-13 21:36 被阅读19次

    一、图像性能优化

    1、减少view个数 ,例如聊天的图文混排,使用富文本代替labels,imageviews。
    2、减少使用半透明效果,或者不要把半透明加在一个经常变化的view之上,因为,不仅底层view要更新,半透明的也要更新。
    3、 shouldRasterize(栅格化) == true,将当前view绘制成image缓存,这个绘制过程本身比较耗时耗内存,但是如果界面很少变化,这种缓存能提升性能。栅格化就是将内容转化成图片。

    二、图像性能检测,Core Animation工具

    1 Blended像素混合

    1.1 当图层有半透明时,如:view.backgroundcolor。

    GPU需要进行像素混合,需要先绘制透明层下层的内容,再叠加透明层以达到透明的效果,而不影响帧率的情况下,GPU可绘制的像素是有限制的。

    1.2 通常优化方式

    • backgroundColor设置为不透明色
    • Opaque设置为YES
    • 图片能不用透明的切图成不透明
      例1:运行结果见图一。
    - (void)testBlendedLayer
    {
        __block CGFloat width = 200;
        __block CGFloat leftOffset = (SCREEN_WIDTH - 200)/2.0;
        __block CGFloat topOffset = 70;
        [self testBlendedLayer:^(UILabel *label) {
            label.frame = CGRectMake(leftOffset, topOffset, width, 30);
            topOffset += 50;
            label.text = @"背景颜色:默认";
        }];
    
        [self testBlendedLayer:^(UILabel *label) {
            label.frame = CGRectMake(leftOffset, topOffset, width, 30);
            topOffset += 50;
            
            label.text = @"背景颜色:半透明";
            label.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
        }];
        
        [self testBlendedLayer:^(UILabel *label) {
            label.frame = CGRectMake(leftOffset, topOffset, width, 30);
            topOffset += 50;
            
            label.text = @"背景颜色:不透明";
            label.backgroundColor = [UIColor lightGrayColor];
        }];
    
        [self testBlendedLayer:^(UILabel *label) {
            label.frame = CGRectMake(leftOffset, topOffset, width, 30);
            topOffset += 50;
            
            label.text = @"背景颜色:无混合情况";
            label.backgroundColor = [UIColor lightGrayColor];
            label.layer.masksToBounds = YES;
        }];
    }
    
    - (void)testBlendedLayer:(void (^) (UILabel *label))construct
    {
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 30)];
        label.textColor = [UIColor blackColor];
        if (construct) {
            construct(label);
        }
        [self.view addSubview:label];
    }
    
    图一 像素混合.jpeg

    1:55:47

    2、Color Copied images 图片能否需CPU要转码,需要的显示蓝色,如图二所示。

    - (void)viewDidLoad {
        UIImageView *imageView = [[UIImageView alloc]  initWithFrame:self.view.bounds];
        UIImage *origin = [UIImage imageNamed:@"16.png"];
        UIImage *image = [Util decodeImage:origin toSize:imageView.layer.bounds.size];
        imageView.image = origin;
        imageView.opaque = YES;
    
        [self.view addSubview:imageView];
        [super viewDidLoad];
    }
    
    + (UIImage *)decodeImage:(UIImage *)image toSize:(CGSize)size
    {
        if (image == nil) { // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
            return nil;
        }
        
        @autoreleasepool{
            // do not decode animated images
            if (image.images != nil) {
                return image;
            }
            
            CGImageRef imageRef = image.CGImage;
            
            CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef);
            BOOL anyAlpha = (alpha == kCGImageAlphaFirst ||
                             alpha == kCGImageAlphaLast ||
                             alpha == kCGImageAlphaPremultipliedFirst ||
                             alpha == kCGImageAlphaPremultipliedLast);
            if (anyAlpha) {
                NSLog(@"图片解压失败,存在alpha通道");
                return image;
            }
            
            // current
            CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(CGImageGetColorSpace(imageRef));
            CGColorSpaceRef colorspaceRef = CGImageGetColorSpace(imageRef);
            
            BOOL unsupportedColorSpace = (imageColorSpaceModel == kCGColorSpaceModelUnknown ||
                                          imageColorSpaceModel == kCGColorSpaceModelMonochrome ||
                                          imageColorSpaceModel == kCGColorSpaceModelCMYK ||
                                          imageColorSpaceModel == kCGColorSpaceModelIndexed);
            if (unsupportedColorSpace) {
                colorspaceRef = CGColorSpaceCreateDeviceRGB();
            }
            CGFloat scale = [UIScreen mainScreen].scale;
            size_t width = size.width;
            size_t height = size.height;
            NSUInteger bytesPerPixel = 4;
            NSUInteger bytesPerRow = bytesPerPixel * width;
            NSUInteger bitsPerComponent = 8;
            
            
            // kCGImageAlphaNone is not supported in CGBitmapContextCreate.
            // Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
            // to create bitmap graphics contexts without alpha info.
            CGContextRef context = CGBitmapContextCreate(NULL,
                                                         width,
                                                         height,
                                                         bitsPerComponent,
                                                         bytesPerRow,
                                                         colorspaceRef,
                                                         kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
            
            // Draw the image into the context and retrieve the new bitmap image without alpha
            CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
            CGImageRef imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
            UIImage *imageWithoutAlpha = [UIImage imageWithCGImage:imageRefWithoutAlpha
                                                             scale:scale
                                                       orientation:image.imageOrientation];
            
            if (unsupportedColorSpace) {
                CGColorSpaceRelease(colorspaceRef);
            }
            
            CGContextRelease(context);
            CGImageRelease(imageRefWithoutAlpha);
            NSLog(@"图片解压成功");
            return imageWithoutAlpha;
        }
    
    }
    
    
    图二.png

    3、Offscreen-Rendered工具

    • 离屏渲染
      在使用圆角、阴影和遮罩等视图功能的时候,图层属性的混合体被指定为在未预合成之前不能直接在屏幕中绘制,所有就需要在屏幕外的上下文中渲染,即离屏渲染。
      产生离屏渲染原因:
      shouldRasterize(光栅化)、masks(遮罩)、shadows(阴影)、edge antialiasing(抗锯齿)、group opacity(不透明)、复杂形状设置圆角、渐变
      见链接:https://www.cnblogs.com/fishbay/p/7576176.html

    4、Color Hits Green and Misses Red 检测栅格化的效果,绿色最佳

    栅格化命中显示绿色,没有命中显示红色。见图三cell.rasterizeLbl.layer.shouldRasterize = YES;

    图三 栅格化截图.jpeg
    当 shouldRasterize 设成 true 时,layer 被渲染成一个 bitmap,并缓存起来,等下次使用时不会再重新去渲染了。实现圆角本身就是在做颜色混合(blending),如果每次页面出来时都blending,消耗太大,这时shouldRasterize = yes,下次就只是简单的从渲染引擎的 cache 里读取那张 bitmap,节约系统资源。
    额外收获:如果在滚动 tableView 时,每次都执行圆角设置,肯定会阻塞 UI,设置这个将会使滑动更加流畅。

    相关文章

      网友评论

          本文标题:性能优化一

          本文链接:https://www.haomeiwen.com/subject/hpuofftx.html