{"result":{"depiction_url":null,"edges":{"subject":{"objects":[{"created":"2026-09-30T09:11:23Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2563,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_frontend_developer","title":"Frontend developer","uri":"https:\/\/zotonic.com\/id\/2563"},"seq":2},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2625,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_model","title":"Model","uri":"https:\/\/zotonic.com\/id\/2625"},"seq":3},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2673,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_javascript","title":"JavaScript","uri":"https:\/\/zotonic.com\/id\/2673"},"seq":4},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2715,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_page_lifecycle","title":"Page lifecycle","uri":"https:\/\/zotonic.com\/id\/2715"},"seq":5},{"created":"2026-09-30T09:11:23Z","object_id":{"id":2718,"is_a":["categorization","keyword","keyword_technology"],"name":"zotonic_topic_cotonic","title":"Cotonic","uri":"https:\/\/zotonic.com\/id\/2718"},"seq":6}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":2738,"is_a":["text","documentation","reference","cotonic_reference","cotonic_model"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2738"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_cotonic_model_lifecycle","page_url":{"en":"https:\/\/zotonic.com\/cotonic\/models\/lifecycle","x-default":"https:\/\/zotonic.com\/cotonic\/models\/lifecycle"},"preview_url":null,"resource":{"version":16,"pivot_location_lat":null,"title":"model\/lifecycle","is_authoritative":true,"body":"<a name=\"model.lifecycle\"><\/a>\n\n            <p>\n            Application lifecycle is a key way that modern operating systems manage resources.\n            On Android, iOS, and recent Windows versions, apps can be started and stopped at\n            any time by the OS. This allows these platforms to streamline and reallocate resources\n            where they best benefit the user.\n            <\/p>\n\n            <p>\n            Modern browsers will also suspend and discard pages. Browsers do not provide this\n            information in an orderly fashion. There are individual events like: <tt>load<\/tt>,\n            <tt>unload<\/tt>, and <tt>visibilitychange<\/tt>. The lifecycle model publishes the\n            different states a page can be in.\n            <\/p>\n            <dl>\n                <dt><tt>active<\/tt><\/dt>\n                <dd>\n                    The page has focus, and is visible in the foreground. It is important that\n                    the page is responsive to user input. It may be needed to move non-important\n                    work from the main thread to a worker.\n                <\/dd>\n\n                <dt><tt>passive<\/tt><\/dt>\n                <dd>\n                    The page has lost focus, but is still visible. It is important that ui updates\n                    and animations still run smoothly. It may be a good time to store unsaved\n                    application state.\n                <\/dd>\n\n                <dt><tt>hidden<\/tt><\/dt>\n                <dd>\n                    The page has lost focus, and is no longer visible, but it still exists. It is\n                    likely that this is the end of user interaction with the page. Unsaved state\n                    should be saved. It is also a good time to stop making UI updates, since they\n                    won&#39;t be seen by user.\n                <\/dd>\n\n                <dt><tt>frozen<\/tt><\/dt>\n                <dd>\n                    The page has been cached to memory by the browser. It can resume in a\n                    later stage. Javascript&#39;s timers and fetch callbacks no longer work.\n                    Browsers can freeze pages to prevent full page reloads. This is a good time\n                    to close any open Web Socket connections, close WebRTC channels because\n                    the browser want&#39;s to conserve energy.\n                <\/dd>\n\n                <dt><tt>terminated<\/tt><\/dt>\n                <dd>\n                    The page will be terminated shortly.\n                <\/dd>\n            <\/dl>\n\n            <p>\n            The lifecycle model publishes the state the page is at on the\n            <tt>model\/lifecycle\/event\/state<\/tt> topic as a retained message. This makes\n            it possible to get the current state at any moment, and be notified of changes\n            so the application can scale its resource usage at any moment.\n            <\/p>\n\n            <p>\n            State changes are always done in an orderly way. When a page goes from state\n            <tt>active<\/tt> to state <tt>hidden<\/tt> it is made sure that the <tt>passive<\/tt>\n            state is also published.\n            <\/p>\n\n            <p>\n            State transition diagram: <br \/><br \/>\n\n            <img width=\"250\" alt=\"Lifecycle State Changes\" src=\"https:\/\/user-images.githubusercontent.com\/1024972\/123400323-edbf7600-d5a5-11eb-94fd-0bd42aff2ac2.png\" \/>\n\n            <\/p>\n\n            <a name=\"model.lifecycle.event.state\"><\/a><h2>event\/state<\/h2><p>\n            When the lifecycle model sees a state change in the page lifecycle state, its\n            state is published on this topic. The message is published as a retained message,\n            and is available when the model is active. Possible states are: <tt>active<\/tt>,\n            <tt>passive<\/tt>, <tt>hidden<\/tt>, <tt>frozen<\/tt>, and <tt>terminated<\/tt>.\n            <\/p>\n            <pre>\n\/\/ Subscribe in a worker\nself.subscribe(&quot;model\/lifecycle\/event\/state&quot;,\n    function(m) {\n        switch(m.payload) {\n            case &quot;active&quot;:\n            case &quot;passive&quot;:\n                \/\/ Speed up network usage again.\n            case &quot;hidden&quot;:\n                \/\/ Slow down network usage.\n                break;\n        }\n   });<\/pre>\n\n            <a name=\"model.lifecycle.event.online\"><\/a><h2>event\/online<\/h2><p>\n            When the lifecycle model detects a change in the online state of the browser,\n            the state will be published on this topic. When the browser is online, <tt>true<\/tt>\n            will be published <tt>false<\/tt> otherwise.\n            <\/p>\n            <pre>\nself.subscribe(&quot;model\/lifecycle\/event\/online&quot;,\n    function(m) {\n        if(m.payload) {\n            console.log(&quot;We are online&quot;);\n        } else {\n            console.log(&quot;We are offline&quot;);\n        }\n    }\n);\n<\/pre>\n\n            <a name=\"model.lifecycle.event.ping\"><\/a><h2>event\/ping<\/h2><p>\n            When the lifecycle model is enabled it publishes a retained <tt>pong<\/tt>\n            message on this topic. This makes it possible to check if the model is enabled.\n            <\/p>\n            <pre>\n\/\/ Subscribe in a worker\nself.subscribe(&quot;model\/lifecycle\/event\/ping&quot;,\n    function() {\n        console.log(&quot;the lifecycle model is enabled&quot;)\n   });<\/pre>\n\n\n            <!-- autofocus model -->\n            ","slug":"model-lifecycle","is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"13f72946262f15c752910aed4402a3f83d52295e3f340246e1fb0190a2657111","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"category_id":{"id":2723,"is_a":["meta","category"],"name":"cotonic_model","title":"Cotonic models","uri":"https:\/\/zotonic.com\/id\/cotonic_model"},"doc_source_path":"index.html","publication_start":"2026-09-30T09:11:23Z","page_path":"\/cotonic\/models\/lifecycle","github_url":"https:\/\/github.com\/cotonic\/cotonic\/blob\/master\/index.html","pivot_location_lng":null,"doc_source_kind":"cotonic","name":"doc_cotonic_model_lifecycle","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2026-09-30T09:11:23Z","uri":null,"doc_source_anchor":"model.lifecycle","doc_status":"current","is_dependent":false,"publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"f88cc928b997d10f7f19e6bd0ede80e1c8c619bc","creator_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"modified":"2026-09-30T10:06:59Z","title_slug":"model-lifecycle"},"uri":"https:\/\/zotonic.com\/id\/2738","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/2738"}},"status":"ok"}