Optimization of iOS image loading speed limit-FastImageCache resolution

Source: Internet
Author: User

Optimization of iOS image loading speed limit-FastImageCache resolution

 

FastImageCache is an open-source library developed by the Path team to accelerate image loading and rendering, so that the image-based list slides more smoothly to see how it works.

Optimization points

IOS loads an image from the disk and uses UIImageVIew to display it on the screen. follow these steps:

  1. Copy data from disk to kernel buffer
  2. Copy data from kernel buffer to user space
  3. Generate UIImageView and assign image data to UIImageView
  4. If the image data is undecoded PNG/JPG, It is decoded as bitmap data.
  5. CATransaction captures changes to the UIImageView layer tree
  6. The main thread Runloop submits CATransaction and starts image rendering.
    • 6.1 if the data does not have the byte alignment, Core Animation will copy another copy of the data for the byte alignment.
    • 6.2 GPU processes bitmap data for rendering.

      FastImageCache optimizes steps 2, 4 and 6.1 respectively:

      1. Mmap memory ing eliminates the need to copy data from the kernel space to the user space.
      2. The decoded bitmap data is cached to the disk. The next time you read the data from the disk, you do not need to perform Step 1 decoding.
      3. Generates byte-aligned data to prevent the preceding step 6.1 CoreAnimation from copying a copy of data during rendering.

        Next, we will introduce these three optimization points and their implementation.

        Memory ing

        Normally, we read a file on the disk. after calling the upper-layer API, we will use the system method read () to read the data, and the kernel will read the disk data into the kernel buffer, the user then reads data from the kernel buffer and copies the data to the user's memory space. There is a memory copy time consumption, and the entire file data is stored in the user's memory after reading the data, occupies the memory space of the process.

        FastImageCache uses another method to read and write files. It uses mmap to map files to the virtual memory in the user space. The file location has a corresponding address in the virtual memory, this file can be operated like the memory operation. It is equivalent to placing the entire file into the memory, but it does not consume physical memory or read or write data to the disk before it is actually used, only when the data is actually used, that is, when the image is ready to be rendered on the screen, the Virtual Memory Management System (VMS) can load the corresponding data block from the disk to the physical memory based on the page missing loading mechanism, then perform rendering. This method reduces the efficiency of data copying from the kernel cache to the user space.

        Decoded image

        Generally, we use JPG/PNG images. These images are not bitmap data, but encoded and compressed data. Before rendering them to the screen, we need to decode them into bitmap data, this decoding operation is time-consuming and does not involve GPU hard decoding. It can only be performed through the CPU. By default, iOS will decode the image in the main thread. Many databases solve the problem of image decoding. However, because the decoded image is too large, it is generally not cached to the disk. The SDWebImage method is to move the decoding operation from the main thread to the subthread, so that time-consuming decoding operations do not occupy the Time of the main thread.

        FastImageCache also decodes the image in the sub-thread. The difference is that it caches the decoded image to the disk. Because the size of the decoded image is very large, FastImageCache caches and manages the image data. For details, see the implementation section below. In addition, the size of cached images is also the reason for using memory ing to read files. Memory ing is advantageous for small files, and the amount of memory copy is small. After copying, the user memory usage is not high, the larger the file size, the larger the memory ing advantage.

        Byte alignment

        Core Animation copies an image before rendering the image data in non-byte alignment. The official document does not describe the copy behavior, the simulator and Instrument have the function of highlighting "copied images", but it seems that it has a bug that even if an image is not highlighted and rendered, it is copied, we can still see from the call stack that the CA: Render: copy_image method is called:

        So what is byte alignment? In my understanding, for the sake of performance, the underlying rendering of an image is not a pixel-to-pixel rendering, but a rendering, and the data is retrieved in blocks, it is possible that the ending data in this continuous memory data is not the image content, it is other data in the memory, it may be out-of-bounds reading, leading to some strange mixed-in, therefore, before rendering, CoreAnimation must copy the data for processing to ensure that each part is image data and leave the remaining part empty. General illustration: (pixel is image pixel data, and data is other data in memory)

        The block size should be related to the CPU cache line, ARMv7 is 32 bytes, A9 is 64 bytes, and CoreAnimation in A9 should be read and rendered based on 64 bytes as a piece of data, by aligning the image data with 64 bytes, CoreAnimation can be prevented from copying a copy of the data for repair. FastImageCache performs byte alignment.

        Implementation

        FastImageCache stores images of the same type and size in a single file, and obtains a Single Image Based on the file offset, similar to the css sprite of the web, which is called ImageTable. In this way, the whole FastImageCache is used to manage ImageTable data to facilitate unified image Cache Management and Control the cache size. Overall Data Structure

        Some notes:

        ImageTable
        1. An ImageFormat corresponds to an ImageTable. ImageFormat specifies the image rendering format/size and other information in ImageTable. The image data in ImageTable specifies the uniform size by ImageFormat, and the size of each image is the same.
        2. One ImageTable is an object file, and another file stores the meta information of this ImageTable.
        3. The image uses entityUUID as the unique identifier, which is defined by the user, usually the hash value of the image url. The indexMap of ImageTable Meta records the entiing of entityUUID-> entryIndex. Through indexMap, you can use the entityUUID of the image to find the location of the cached data in ImageTable. ImageTableEntry
          1. The real data of ImageTable is ImageTableEntry. Each entry has two parts: the aligned image data and the meta information. meta stores the UUID of the image and the original image UUID, used to verify the correctness of image data.
          2. The Entry data is aligned by the memory paging size, and the data size is an integer multiple of the memory paging size. This ensures that an image is loaded with the Minimum Memory Page size when the virtual memory page is missing.
          3. The image data is aligned in bytes, so you do not need to process the copy operation when using CoreAnimation. The specific method is to pass the bytesPerRow parameter to a 64-fold value when CGBitmapContextCreate creates a bitmap canvas. Chunk
            • There are multiple chunks between ImageTable and object data Entry. Chunk is the Logical Data Division, N entries are used as a Chunk, and the memory ing mmap operation is in the unit of Chunk, each chunk executes mmap to map the chunk content to the virtual memory. Why do I need to add another chunk? In my understanding, this is to flexibly control the size of mmap and the number of calls. If mmap is executed for the entire ImageTable, the file loaded into the virtual memory is too large, if mmap is performed on each Entry, too many calls will be made. Cache Management
              • Users can define the maximum number of cached images in the entire ImageTable. When new images need to be cached, if the cache does not exceed the limit, the file size will be expanded in chunk and written in sequence. If the Maximum Cache limit is exceeded, the minimum used cache will be replaced by inserting the UUID into the beginning of the MRUEntries array every time you use the image, MRUEntries arranges the image UUID in the order of recent use, and the last image in the array is used at least. When the replaced image needs to be used again next time, the process of getting the source image, extracting the image, and storing the image is performed again. Use

                FastImageCache is suitable for caching images of the same size on each cell in tableView. It can greatly accelerate the first time these images are loaded from the disk. However, it has two obvious disadvantages: First, it occupies a large space. Because the decoded bitmap is cached to the disk, the bitmap is large, for images with a width of 100*100, 200*200*4 byte/pixel = 156KB is required on a 2x HD screen device. This is why FastImageCache has to pay a lot of weeks to limit the cache size. Second, the interface is unfriendly and the cached image size needs to be predefined. FastImageCache cannot seamlessly access UIImageView like SDWebImage. to use it, you need to configure ImageTable, define the size, and manually provide the source image. Each object image must define a FICEntity model to complicate the logic.

                FastImageCache is already a limit optimization. When performing image loading/rendering optimization, some low-cost and high-return optimization points should be given priority. For example, CALayer replaces UIImageVIew to reduce GPU computing (de-Transparency/pixel alignment ), image sub-thread decoding to avoid Offscreen-Render and so on. While other optimizations are in place, FastImageCache can be used to further improve the performance of the first loading only when the rendering performance of the image is poor, however, the optimization of byte alignment can be directly applied to projects without FastImageCache. You only need to set the bytesPerRow of the bitmap canvas to a multiple of 64 when decoding the image.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.