1. #1
    Ext User
    Join Date
    Oct 2010
    Posts
    3
    Vote Rating
    0
    bestform is on a distinguished road

      0  

    Default Circumvent Memory Limitation on Mobile Safari

    Circumvent Memory Limitation on Mobile Safari


    Hello,

    I am implementing a document viewer for use on the ipad. I am using a Carousel component for the single pages. If I load the whole document (one image/card per page), I quickly run into the memory limitation of mobile safari (5MB for scripts, if I am not mistaken).

    I tried to add and remove cards from the carousel manually while browsing (typical pre-caching behavior), but mobile safari doesn't deallocate the memory of the previous loaded images.

    I then tried to load empty images using the html property of the cards and manipulating the sources dynamically as it is suggested here. Now I have the problem that my carousel component refuses to update the manipulated items after the first doLayout() call.

    Is there a way to force the update? Am i doing it wrong? Can you think of any other way of circumventing this memory limitation of mobile safari?

    Any help would be highly appreciated.


    Greetings,
    Matthias

  2. #2
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    17,164
    Vote Rating
    674
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    Am i doing it wrong?
    Possibly. It would be useful to show the relevant parts of the code.
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  3. #3
    Ext User
    Join Date
    Aug 2010
    Location
    Sweden, Västerås
    Posts
    85
    Vote Rating
    0
    Kask is on a distinguished road

      0  

    Default


    What I've done is use one global IMG -tag for loading the images and using the onload event to draw the images as canvases. That way I will only have one image in memory at the time, since canvases doesnt "apply" to the limitations.

    This is just an example code; havent tested it, wrote it out of my head. But it gives you an idea of what im talking about...

    This doesnt help with your problem with the carousel, but it will help you with the memory trouble you will run it to with using img-tags.

    Code:
    var img = new Image();
    var imgArr = ['img1.jpg', 'img2.jpg', 'img3.jpg'];
    
    img.onload = function() {
      var canvas = document.createElement('canvas');
      canvas.setAttribute(this.width);
      canvas.setAttribute(this.height);
    
      var context = canvas.getContext('2d');
      context.drawImage(image, 0, 0, this.width, this.height);
    
      var nextImg = imgArr.shift();
      if(nextImg)
        img.src = nextImg;
      else
        img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D';
    };
    img.onerror = function() {
      var nextImg = imgArr.shift();
      if(nextImg)
        img.src = nextImg;
      else
        img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D';
    };
    img.src = imgArr.shift();
    Last edited by Kask; 11 Oct 2010 at 5:25 AM. Reason: Added clarification to the post.

  4. #4
    Ext User
    Join Date
    Oct 2010
    Posts
    3
    Vote Rating
    0
    bestform is on a distinguished road

      0  

    Default


    Thanks for the replies.

    @evant:

    The relevant part ist this snippet, which is being called on every 'beforecardswitch' event. It 'empties' all backgrounds except the ones around the current card, depending on the cache amount:

    Code:
      loadPage : function(n, magView) {
        
        var start = Math.max(0, magView.currentPage - magController.cacheAmount);
        var end = Math.min(magController.pages.length -1, magView.currentPage + magController.cacheAmount);
        
        for (var i=0; i < magController.pages.length; i++) {
          var page = magView.car.items.itemAt(i);
          if(i < start || i > end){
            page.html = '<div style="background-image:url('+magController.strNullImage+'); width:0px;height:0px"></div>';
          } else {
            page.html = '<div style="background-image:url('+page.url+'); width:'+page.imgwidth+'px;height:'+page.imgheight+'px"></div>';
          }
        };
        magView.car.doLayout();
      },

    @Kask:

    Good idea with the canvas. I won't be able to use "one global image tag", but I'll do some experiments with this idea.

    Edit: Turns out, I might actually be able to use this image tag. I'll report back.

  5. #5
    Ext User
    Join Date
    Aug 2010
    Location
    Sweden, Västerås
    Posts
    85
    Vote Rating
    0
    Kask is on a distinguished road

      0  

    Default


    The idea im using is to use div-tags instead of img-tags before rendering each card.
    Code:
    {
      html: '<div class="CardImg" img-data:"image1.jpg"> </div>'
    }
    and on afterrender event i will fetch all divs ...

    Code:
    this.el.select("div.CardImg");
    from there i can create my canvas (using img-data) and add the this div so it acts as a container for the canvas ...

    Code:
    var img = new Image();
    var containers = this.el.select("div.CardImg");
    
    img.onload = function() {
      var canvas = document.createElement('canvas');   
      canvas.setAttribute(this.width);
      canvas.setAttribute(this.height);    
      
      var context = canvas.getContext('2d');   
      context.drawImage(image, 0, 0, this.width, this.height);    
      
      nextContainer.appendChild(canvas);
    
      nextContainer = containers.shift();
      if(nextContainer)
         img.src = nextContainer.getAttribute("img-data");
      else
         img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D';
    }; 
    
    img.onerror = function() {   
      nextContainer= imgArr.shift();   
      if(nextContainer)     
        img.src = nextContainer.getAttribute("img-data");   
      else     
        img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D'; 
    }; 
    
    nextContainer = containers.shift();
    img.src = nextContainer.getAttribute("img-data");

  6. #6
    Ext User
    Join Date
    Oct 2010
    Posts
    3
    Vote Rating
    0
    bestform is on a distinguished road

      0  

    Default


    I tried the suggested canvas solution but I still manage to crash mobile safari. Besides, now I see a strange behavior of the carousel component: when I swipe from one card to the next I see another card passing by in the opposite direction (not as slow as my swipe but very fast, as if the carousel puts the next card into place by translating it without hiding it).

    Kask: are you sure that the memory limitation doesn't affect the canvas object? Here it seems to make no difference.


    .bestform

  7. #7
    Ext User
    Join Date
    Aug 2010
    Location
    Sweden, Västerås
    Posts
    85
    Vote Rating
    0
    Kask is on a distinguished road

      0  

    Default


    Well, I had that problem before, having maybe 20Mb of images loaded. But since I started to use global img loading object, with only one Image-object, and canvases it all works fine. Above is just a suggestion, I've created a larger singleton that holds one Image-object and uses the onload to call a callback function to draw canvases.

Similar Threads

  1. [2.2.0] GXT crashes mobile Safari (iPad)
    By SopGreg in forum Ext GWT: Discussion
    Replies: 6
    Last Post: 12 Oct 2011, 11:09 AM
  2. Hide safari mobile address bar
    By __mme__ in forum Sencha Touch 1.x: Discussion
    Replies: 9
    Last Post: 19 Aug 2010, 3:40 AM
  3. memory limitation on combos? ajax? firefox?
    By Ldom in forum Ext 2.x: Help & Discussion
    Replies: 1
    Last Post: 10 Jun 2008, 12:57 AM

Thread Participants: 2

Tags for this Thread