Flutter ਵਿੱਚ ਲੋਕਲ ਕੈਸ਼, ਮੁਰਝਾਇਆ ਡੇਟਾ ਅਤੇ ਰੀਫ੍ਰੈਸ਼ ਨਿਯਮ: ਕੀ ਸਟੋਰ ਕਰਨਾ ਹੈ, ਕਦੋਂ ਅਵੈਧ ਕਰਨਾ ਹੈ, ਅਤੇ ਸਕਰੀਨਾਂ ਨੂੰ ਇੱਕਸਾਰ ਕਿਵੇਂ ਰੱਖਣਾ ਹੈ।

ਮੋਬਾਈਲ ਐਪ ਵਿੱਚ ਕੈਸ਼ਿੰਗ ਦਾ ਮਤਲਬ ਡੇਟਾ ਦੀ ਇੱਕ ਨਜ਼ਦੀਕੀ ਨਕਲ ਰੱਖਣਾ ਹੈ (ਮੇਮੋਰੀ ਜਾਂ ਡਿਵਾਈਸ 'ਤੇ) ਤਾਂ ਜੋ ਅਗਲਾ ਸਕਰੀਨ ਤੁਰੰਤ ਰੈਂਡਰ ਕਰ ਸਕੇ ਬਿਨਾਂ ਨੈੱਟਵਰਕ ਦੀ ਉਡੀਕ ਕੀਤੇ। ਇਹ ਡੇਟਾ ਆਈਟਮਾਂ ਦੀ ਲਿਸਟ, ਯੂਜ਼ਰ ਪ੍ਰੋਫਾਈਲ, ਜਾਂ ਖੋਜ ਨਤੀਜੇ ਹੋ ਸਕਦੇ ਹਨ।
ਮੁਸ਼ਕਲ ਗੱਲ ਇਹ ਹੈ ਕਿ ਕੈਸ਼ ਕੀਤਾ ਡੇਟਾ ਅਕਸਰ ਥੋੜ੍ਹਾ ਗਲਤ ਹੁੰਦਾ ਹੈ। ਯੂਜ਼ਰ ਇਸਨੂੰ ਜਲਦੀ ਨੋਟਿਸ ਕਰ ਲੈਂਦੇ ਹਨ: ਇੱਕ ਕੀਮਤ ਜੋ ਅਪਡੇਟ ਨਹੀਂ ਹੁੰਦੀ, ਇੱਕ ਬੈਜ ਕੰਟ ਜੋ ਫਸਿਆ ਲੱਗਦਾ ਹੈ, ਜਾਂ ਇੱਕ ਡੀਟੇਲ ਸਕਰੀਨ ਜੋ ਬਦਲ ਕਰਨ ਦੇ ਬਾਅਦ ਵੀ ਪੁਰਾਣਾ ਡੇਟਾ ਦਿਖਾਉਂਦੀ ਹੈ। ਇਸਨੂੰ ਡਿਬੱਗ ਕਰਨਾ ਮੁਸ਼ਕਿਲ ਬਣਾਉਂਦੀਆਂ ਗੱਲਾਂ ਟਾਈਮਿੰਗ ਹੁੰਦੀਆਂ ਹਨ। ਇਕੋ ਐਂਡਪੌਇੰਟ ਕਈ ਵਾਰ ਠੀਕ ਲੱਗ ਸਕਦਾ ਹੈ (ਜਿਵੇਂ ਪਲ-ਟੂ-ਰੀਫ੍ਰੈਸ਼ ਤੋਂ ਬਾਅਦ), ਪਰ ਬੈਕ ਨੈਵੀਗੇਸ਼ਨ, ਐਪ ਰੀਜ਼ਿਊਮ, ਜਾਂ ਅਕਾਊਂਟ ਬਦਲਣ 'ਤੇ ਗਲਤ ਦਿਖ ਸਕਦਾ ਹੈ।
ਇੱਥੇ ਹਕੀਕਤੀ ਟਰੇਡ-ਆਫ਼ ਹੈ। ਜੇ ਤੁਸੀਂ ਹਮੇਸ਼ਾ ਤਾਜਾ ਡੇਟਾ ਫੈਚ ਕਰੋਗੇ ਤਾਂ ਸਕਰੀਨ ਸਲੋ ਅਤੇ ਅਚਾਨਕ ਮਹਿਸੂਸ ਹੋਣਗੀਆਂ, ਬੈਟਰੀ ਅਤੇ ਡੇਟਾ ਵਰਤੋ ਹੋਵੇਗਾ। ਜੇ ਤੁਸੀਂ ਜ਼ਿਆਦਾ ਕੈਸ਼ ਕਰੋਗੇ ਤਾਂ ਐਪ ਤੇਜ਼ ਲੱਗੇਗੀ ਪਰ ਲੋਕ ਜੋ ਵੇਖਦੇ ਹਨ ਉਸ 'ਤੇ ਭਰੋਸਾ ਘਟ ਜਾਵੇਗਾ।
ਸਧਾਰਨ ਟੀਚਾ ਇਹ ਹੈ: ਤਾਜਗੀ ਨੂੰ ਭਵਿੱਖਬਾਣੀਯੋਗ ਬਣਾਓ। ਫੈਸਲਾ ਕਰੋ ਕਿ ਹਰ ਸਕਰੀਨ ਕੀ ਦਿਖਾ ਸਕਦੀ ਹੈ (ਤਾਜਾ, ਥੋੜ੍ਹਾ ਮੁਰਝਾਇਆ, ਜਾਂ ਆਫਲਾਈਨ), ਡੇਟਾ ਕਿੰਨੀ ਦੇਰ ਰਹਿ ਸਕਦਾ ਹੈ ਇਸ ਤੋਂ ਪਹਿਲਾਂ ਕਿ ਤੁਸੀਂ ਉਨ੍ਹਾਂ ਨੂੰ ਰੀਫ੍ਰੈਸ਼ ਕਰੋ, ਅਤੇ ਕਿਹੜੇ ਇਵੈਂਟ ਉਸਨੂੰ ਅਵੈਧ ਕਰਦੇ ਹਨ।
ਇਕ ਆਮ ਫ਼ਲੋ ਦੀ ਸੋਚੋ: ਯੂਜ਼ਰ ਇੱਕ ਆਰਡਰ ਖੋਲ੍ਹਦਾ ਹੈ, ਫਿਰ ਆਰਡਰ ਸੂਚੀ 'ਤੇ ਵਾਪਸ ਜਾਂਦਾ ਹੈ। ਜੇ ਸੂਚੀ ਕੈਸ਼ ਤੋਂ ਆ ਰਹੀ ਹੈ ਤਾਂ ਉਹ ਪੁਰਾਣੀ ਸਟੇਟ ਦਿੱਸ ਸਕਦੀ ਹੈ। ਜੇ ਤੁਸੀਂ ਹਰ ਵਾਰ ਰੀਫ੍ਰੈਸ਼ ਕਰੋਗੇ ਤਾਂ ਸੂਚੀ ਫੈਲਿਕਰ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਸੁਸਤ ਮਹਿਸੂਸ ਹੋਵੇਗੀ। ਸਾਫ਼ ਨਿਯਮ ਜਿਵੇਂ “ਤੁਰੰਤ ਕੈਸ਼ ਦਿਖਾਓ, ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਰੀਫ੍ਰੈਸ਼ ਕਰੋ, ਅਤੇ ਜਦੋਂ ਨਤੀਜਾ ਆਏ ਤਾਂ ਦੋਨੋ ਸਕਰੀਨਾਂ ਨੂੰ ਅਪਡੇਟ ਕਰੋ” ਤੋਂ ਅਨੁਭਵ ਨੈਵੀਗੇਸ਼ਨ ਦੌਰਾਨ ਇੱਕਸਾਰ ਰਹਿੰਦਾ ਹੈ।
ਕੈਸ਼ ਸਿਰਫ "ਸੰਭਾਲਿਆ ਹੋਇਆ ਡੇਟਾ" ਹੀ ਨਹੀਂ ਹੈ। ਇਹ ਇੱਕ ਨਕਲ ਹੈ ਨਾਲ ਇੱਕ ਨਿਯਮ ਕਿ ਉਹ ਨਕਲ ਕਦ ਤੱਕ ਵੈਧ ਹੈ। ਜੇ ਤੁਸੀਂ ਪੇਲੋਡ ਸਟੋਰ ਕਰਦੇ ਹੋ ਪਰ ਨਿਯਮ ਨਹੀਂ ਰੱਖਦੇ ਤਾਂ ਤੁਹਾਡੇ ਕੋਲ ਦੋ ਹਕੀਕਤਾਂ ਹੋ ਸਕਦੀਆਂ ਹਨ: ਇਕ ਸਕਰੀਨ ਨਵਾਂ ਡੇਟਾ ਦਿਖਾ ਰਹੀ ਹੈ, ਦੂਜੀ ਕੱਲ ਦਾ।
ਇੱਕ ਪ੍ਰਯੋਗਿਕ ਮਾਡਲ ਇਹ ਹੈ ਕਿ ਹਰ ਕੈਸ਼ ਕੀਤੀ ਆਈਟਮ ਨੂੰ ਤਿੰਨ ਸਥਿਤੀਆਂ ਵਿੱਚ ਰੱਖੋ:
ਇਹ ਫਰੇਮਿੰਗ ਤੁਹਾਡੇ UI ਨੂੰ ਭਵਿੱਖਬਾਣੀਯੋਗ ਬਨਾਉਂਦੀ ਕਿਉਂਕਿ ਹਰੇਕ ਸਥਿਤੀ ਵੇਖ ਕੇ UI ਇੱਕੋ ਤਰ੍ਹਾਂ ਪ੍ਰਤੀਕਿਰਿਆ ਕਰ ਸਕਦਾ ਹੈ।
ਤਾਜਗੀ ਦੇ ਨਿਯਮ ਉਸ ਸਿਗਨਲ 'ਤੇ ਆਧਾਰਿਤ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ ਜੋ ਤੁਸੀਂ ਆਪਣੀ ਟੀਮ ਨੂੰ ਸਮਝਾ ਸਕੋ। ਆਮ ਚੋਣਾਂ ਵਿੱਚ ਟਾਈਮ-ਆਧਾਰਿਤ ਮਿਆਦ (ਜਿਵੇਂ 5 ਮਿੰਟ), ਵਰਜ਼ਨ ਬਦਲਣਾ (ਸਕੀਮਾ ਜਾਂ ਐਪ ਵਰਜਨ), ਯੂਜ਼ਰ ਕਿਰਿਆ (ਪੁਲ-ਟੂ-ਰੀਫ੍ਰੈਸ਼, submit, delete), ਜਾਂ ਸਰਵਰ ਦੇ ਸਿਗਨਲ (ETag, last-updated timestamp, ਜਾਂ ਇੱਕ ਸਪਸ਼ਟ “cache invalid” ਜਵਾਬ) ਸ਼ਾਮਲ ਹਨ।
ਉਦਾਹਰਨ: ਇੱਕ ਪ੍ਰੋਫਾਈਲ ਸਕਰੀਨ ਕੈਸ਼ ਕੀਤਾ ਯੂਜ਼ਰ ਡੇਟਾ ਤੁਰੰਤ ਲੋਡ ਕਰਦੀ ਹੈ। ਜੇ ਇਹ ਮੁਰਝਾਇਆ ਪਰ ਵਰਤਣਯੋਗ ਹੈ ਤਾਂ ਇਹ ਨਾਂ ਅਤੇ аваਟਰ ਦਿਖਾਏਗੀ, ਫਿਰ ਚੁੱਪਚਾਪ ਰੀਫ੍ਰੈਸ਼ ਕਰੇਗੀ। ਜੇ ਯੂਜ਼ਰ ਨੇ ਹੁਣੇ ਆਪਣੀ ਪ੍ਰੋਫਾਈਲ ਸੋਧੀ ਹੈ ਤਾਂ ਇਹ ਜ਼ਰੂਰੀ ਰੀਫ੍ਰੈਸ਼ ਦਾ ਮੋੜ ਹੈ। ਐਪ ਤੁਰੰਤ ਕੈਸ਼ ਅਪਡੇਟ ਕਰ ਦੇਵੇ ਤਾਂ ਹਰ ਸਕਰੀਨ ਇੱਕਸਾਰ ਰਹੇ।
ਇਹ ਨਿਯਮ ਕਿਸ ਦਾ ਕਹਿਰ ਹੈ ਇਹ ਵੀ ਫੈਸਲਾ ਕਰੋ। ਜ਼ਿਆਦਾਤਰ ਐਪ ਵਿੱਚ ਸਭ ਤੋਂ ਵਧੀਆ ਡੀਫਾਲਟ ਇਹ ਹੈ: ਡੇਟਾ ਲੇਅਰ ਤਾਜਗੀ ਅਤੇ ਅਵੈਧਤਾ ਦਾ ਮਾਲਕ ਹੋਵੇ, UI ਸਿਰਫ ਪ੍ਰਤੀਕਿਰਿਆ ਕਰੇ (ਤੁਰੰਤ ਕੈਸ਼ ਦਿਖਾਓ, ਲੋਡਿੰਗ ਦਿਖਾਓ, ERROR ਦਿਖਾਓ), ਅਤੇ ਬੈਕਅਏਂਡ ਜੇ ਸਕਦਾ ਤਾਂ ਸਹਾਇਤਾ ਦੇਵੇ। ਇਸ ਨਾਲ ਹਰ ਸਕਰੀਨ ਆਪਣੀਆਂ ਨਿਯਮ ਨਹੀਂ ਬਣਾਉਂਦੀ।
ਵਧੀਆ ਕੈਸ਼ਿੰਗ ਇਕ ਸਵਾਲ ਨਾਲ ਸ਼ੁਰੂ ਹੁੰਦੀ ਹੈ: ਜੇ ਇਹ ਡੇਟਾ ਥੋੜ੍ਹਾ ਪੁਰਾਣਾ ਹੋਵੇ ਤਾਂ ਕੀ ਇਹ ਯੂਜ਼ਰ ਨੂੰ ਨੁਕਸਾਨ ਪਹੁੰਚਾਏਗਾ? ਜੇ ਜਵਾਬ “ਸ਼ਾਇਦ ਠੀਕ” ਹੈ ਤਾਂ ਆਮ ਤੌਰ 'ਤੇ ਇਹ ਲੋਕਲ ਕੈਸ਼ ਲਈ ਵਧੀਆ ਹੈ।
ਜੋ ਡੇਟਾ ਬਹੁਤ ਪੜ੍ਹਿਆ ਜਾਂਦਾ ਅਤੇ ਹੌਲੀ-ਹੌਲੀ ਬਦਲਦਾ ਹੈ ਉਹ ਕੈਸ਼ ਕਰਨਯੋਗ ਹੁੰਦਾ ਹੈ: ਫੀਡਾਂ ਅਤੇ ਲਿਸਟਾਂ, ਕੈਟਾਲੌਗ-ਤਰ੍ਹਾਂ ਦਾ ਸਮੱਗਰੀ (ਉਤਪਾਦ, ਲੇਖ), ਅਤੇ ਰੈਫਰੰਸ ਡੇਟਾ ਜਿਵੇਂ ਕੈਟੇਗਰੀਜ਼ ਜਾਂ ਦੇਸ਼। ਸੈਟਿੰਗਜ਼ ਅਤੇ ਪਸੰਦਾਂ ਇਥੇ ਆਉਂਦੀਆਂ ਹਨ, ਨਾਲ ਹੀ ਮੁਢਲਾ ਪ੍ਰੋਫਾਈਲ ਜਾਣਕਾਰੀ (ਨਾਂ, avatar URL)।
ਖਤਰਨਾਕ ਪੱਖ ਉਹ ਹੈ ਜੋ ਪੈਸੇ ਜਾਂ ਸਮੇਂ ਨਾਲ ਸੰਬੰਧਿਤ ਹੈ। ਬੈਲੈਂਸ, ਭੁਗਤਾਨ ਸਥਿਤੀ, ਸਟਾਕ ਉਪਲਬਧਤਾ, ਨਿਯੁਕਤੀ ਸਲਾਟ, ਡਿਲਿਵਰੀ ETAs, ਅਤੇ "last seen online" ਜਿਹੜੇ ਹਨ ਇਹ ਪੁਰਾਣੇ ਹੋਣ 'ਤੇ ਅਸਲ ਸਮੱਸਿਆ ਪੈਦਾ ਕਰ ਸਕਦੇ ਹਨ। ਤੁਸੀਂ ਇਨ੍ਹਾਂ ਨੂੰ ਤੇਜ਼ੀ ਲਈ ਕੈਸ਼ ਕਰ ਸਕਦੇ ਹੋ, ਪਰ ਫੈਸਲੇ-ਬਿੰਦੂਆਂ (ਜਿਵੇਂ ਆਰਡਰ ਪੁਸ਼ਟੀ) ਤੋਂ ਪਹਿਲਾਂ ਫੋਰਸ ਰੀਫ੍ਰੈਸ਼ ਕਰੋ।
Derived UI state (ਚੁਣਿਆ ਹੋਇਆ ਟੈਬ, ਫਿਲਟਰ, ਖੋਜ ਕੁੈਰੀ, ਸਰਟ ਆਰਡਰ, ਸਕ੍ਰੋਲ ਪੋਜ਼ੀਸ਼ਨ) ਦੀ ਆਪਣੀ ਸ਼੍ਰੇਣੀ ਹੈ। ਇਹ ਨੈਵੀਗੇਸ਼ਨ ਨੂੰ ਮਸਹੂਸ ਲਹਿਰਦਾਰ ਬਣਾਂ ਸਕਦਾ ਹੈ ਪਰ ਲੋਕਾਂ ਨੂੰ ਗੁੰਝਲ ਵਿੱਚ ਵੀ ਪਾ ਸਕਦਾ ਹੈ ਜਦ ਪੁਰਾਣੇ ਚੋਣਾਂ ਅਚਾਨਕ ਵਾਪਸ ਆ ਜਾਂਦੀਆਂ ਹਨ। ਇਕ ਸਧਾਰਨ ਨਿਯਮ: UI state ਨੂੰ ਮੈਮੋਰੀ ਵਿੱਚ ਰੱਖੋ ਜਦ ਤੱਕ ਯੂਜ਼ਰ ਉਸ ਫਲੋ ਵਿੱਚ ਹੈ, ਪਰ ਜਦ ਉਹ ਜ਼ਾਹਿਰ ਤੌਰ 'ਤੇ "ਫਿਰ ਸ਼ੁਰੂ" ਕਰਦਾ ਹੈ (ਜਿਵੇਂ ਹੋਮ ਸਕਰੀਨ) ਤਾਂ ਰੀਸੈਟ ਕਰ ਦਿਓ।
ਜੋ ਕੁਝ ਸਿਕਿਉਰਟੀ ਜਾਂ ਪ੍ਰਾਈਵੇਸੀ ਰਿਸਕ ਪੈਦਾ ਕਰਦਾ ਹੈ ਉਸਨੂੰ ਕੈਸ਼ ਕਰਨ ਤੋਂ ਬਚੋ: ਸੀਕ੍ਰੇਟ (passwords, API keys), ਇੱਕ-ਵਾਰੀ ਟੋਕਨ (OTP, password reset tokens), ਅਤੇ ਸੰਵੇਦਨਸ਼ੀਲ ਨਿੱਜੀ ਡੇਟਾ ਜਦ ਤੱਕ ਤੁਹਾਨੂੰ ਆਫਲਾਈਨ ਪਹੁੰਚ ਦੀ ਸਚਮੁਚ ਲੋੜ ਨਾ ਹੋਵੇ। ਪੂਰੇ ਕਾਰਡ ਡੀਟੇਲ ਕਦੇ ਵੀ ਕੈਸ਼ ਨਾ ਕਰੋ।
ਉਦੇਹਰਨ ਲਈ, ਸ਼ਾਪਿੰਗ ਐਪ ਵਿੱਚ ਉਤਪਾਦ ਸੂਚੀ ਕੈਸ਼ ਕਰਨਾ ਵੱਡਾ ਫਾਇਦਾ ਹੈ। ਚੈੱਕਆਉਟ ਸਕਰੀਨ ਹਮੇਸ਼ਾਂ ਖਰੀਦ ਤੋਂ ਠੀਕ ਪਹਿਲਾਂ ਟੋਟਲ ਅਤੇ ਉਪਲਬਧਤਾ ਰੀਫ੍ਰੈਸ਼ ਕਰੇ।
ਜਿਆਦਾਤਰ Flutter ਐਪਸ ਨੂੰ ਲੋਕਲ ਕੈਸ਼ ਦੀ ਲੋੜ ਪੈਂਦੀ ਹੈ ਤਾਂ ਜੋ ਸਕਰੀਨ ਤੇਜ਼ ਲੋਡ ਹੋਣ ਅਤੇ ਨੈੱਟਵਰਕ ਦੇ ਉੱਠਣ 'ਤੇ ਖਾਲੀ ਨਾ ਫਲੈਸ਼ ਹੋਣ। ਮੈਚ ਕੀਤੇ ਜਾਣ ਵਾਲੇ ਮੁੱਖ ਫੈਸਲੇ ਹਨ ਕਿ ਕੈਸ਼ ਕਿੱਥੇ ਰਹੇਗਾ ਕਿਉਂਕਿ ਹਰ ਲੇਅਰ ਦੀ ਤੇਜ਼ੀ, ਸাইজ ਸੀਮਾ, ਅਤੇ ਕਲੀਨਅਪ ਹਵਾਲਾ ਵੱਖਰਾ ਹੁੰਦਾ ਹੈ।
ਮੈਮੋਰੀ ਕੈਸ਼ ਸਭ ਤੋਂ ਤੇਜ਼ ਹੁੰਦਾ ਹੈ। ਇਹ ਉਹਨਾਂ ਡੇਟਾ ਲਈ ਵਧੀਆ ਹੈ ਜੋ ਤੁਸੀਂ ਹੁਣੇ ਫੈਚ ਕੀਤਾ ਹੈ ਅਤੇ ਐਪ ਖੁੱਲੀ ਰਹਿਣ ਦੌਰਾਨ ਦੁਬਾਰਾ ਵਰਤੋਂਗੇ, ਜਿਵੇਂ ਮੌਜੂਦਾ ਯੂਜ਼ਰ ਪ੍ਰੋਫਾਈਲ, ਆਖਰੀ ਖੋਜ ਨਤੀਜੇ, ਜਾਂ ਹਾਲ ਹੀ ਵਿੱਚ ਦੇਖਿਆ ਉਤਪਾਦ। ਨuksਾਨ ਇਹ ਹੈ ਕਿ ਇਹ ਐਪ ਮਾਰੇ ਜਾਣ 'ਤੇ ਗਾਇਬ ਹੋ ਜਾਂਦਾ ਹੈ, ਇਸ ਲਈ ਇਹ ਕੋਲਡ ਸਟਾਰਟ ਜਾਂ ਆਫਲਾਈਨ ਲਈ ਮਦਦਗਾਰ ਨਹੀਂ।
ਡਿਸਕ key-value ਸਟੋਰੇਜ ਉਹਨਾਂ ਛੋਟੇ ਆਈਟਮਾਂ ਲਈ ਫਿੱਟ ਹੈ ਜੋ ਰੀਸਟਾਰਟਾਂ ਤੋਂ ਬਾਅਦ ਜੀਵਤ ਰਹਿਣੇ ਚਾਹੀਦੇ ਹਨ। ਸੋਚੋ ਪ੍ਰੈਫਰੰਸ, feature flags, "last selected tab", ਅਤੇ ਛੋਟੇ JSON ਜਵਾਬ ਜੋ ਬਦਲਦੇ ਨਹੀਂ। ਇਸਨੂੰ ਇਰਾਦਾ ਰੂਪ ਵਿੱਚ ਛੋਟਾ ਰੱਖੋ—ਵੱਡੀਆਂ ਲਿਸਟਾਂ key-value ਸਟੋਰੇਜ ਵਿੱਚ ਪਾਉਣ ਨਾਲ ਅਪਡੇਟਸ ਗੁੰਝਲਦਾਰ ਹੋ ਜਾਂਦੀਆਂ ਹਨ।
ਲੋਕਲ ਡੇਟਾਬੇਸ ਸਭ ਤੋਂ ਵਧੀਆ ਹੈ ਜਦ ਤੁਹਾਡਾ ਡੇਟਾ ਵੱਡਾ, ਸਟਰੱਕਚਰਡ, ਜਾਂ ਆਫਲਾਈਨ ਵਰਤੀ ਲਈ ਚਾਹੀਦਾ ਹੋਵੇ। ਇਹ ਉਨ੍ਹਾਂ ਸਮੇਂ ਵੀ ਮਦਦ ਕਰਦਾ ਹੈ ਜਦ ਤੁਹਾਨੂੰ ਕੁਇਰੀਆਂ ਚਾਹੀਦੀਆਂ ਹਨ ("ਸਾਰੇ unread messages", "ਕਾਰਟ ਵਿੱਚ ਆਈਟਮ", "ਪਿਛਲੇ ਮਹੀਨੇ ਦੇ ਆਰਡਰ") ਬਜਾਇ ਇੱਕ ਵੱਡੇ ਬਲਬ ਨੂੰ ਲੋਡ ਕਰਕੇ ਮੇਮੋਰੀ ਵਿੱਚ ਫਿਲਟਰ ਕਰਨ ਦੇ।
ਕੈਸ਼ਿੰਗ ਨੂੰ ਭਵਿੱਖਬਾਣੀਯੋਗ ਬਣਾਏ ਰੱਖਣ ਲਈ, ਹਰ ਡੇਟਾ ਕਿਸਮ ਲਈ ਇੱਕ ਪ੍ਰਾਇਮਰੀ ਸਟੋਰ ਚੁਣੋ ਅਤੇ ਇੱਕੋ dataset ਨੂੰ ਤਿੰਨ ਥਾਵਾਂ 'ਤੇ ਰੱਖਣ ਤੋਂ ਬਚੋ।
ਛੋਟਾ ਨਿਯਮ-ਹੱਥ:
ਸਾਈਜ਼ ਦੀ ਯੋਜਨਾ ਵੀ ਬਣਾਓ। ਨਿਰਧਾਰਤ ਕਰੋ ਕਿ "ਬਹੁਤ ਵੱਡਾ" ਦਾ ਕੀ ਮਤਲਬ ਹੈ, ਤੁਸੀਂ ਆਈਟਮ ਕਿੰਨੀ ਦੇਰ ਰੱਖੋਗੇ, ਅਤੇ ਕਿਵੇਂ ਸਾਫ਼ ਕਰੋਂਗੇ। ਉਦਾਹਰਨ ਲਈ: ਕੈਸ਼ ਕੀਤੇ ਖੋਜ ਨਤੀਜਿਆਂ ਨੂੰ ਆਖਰੀ 20 ਕੁਐਰੀਜ਼ ਤੱਕ ਸੀਮਤ ਕਰੋ, ਅਤੇ 30 ਦਿਨ ਤੋਂ ਪੁਰਾਣੇ ਰਿਕਾਰਡ ਨਿਯਮਿਤ ਤੌਰ 'ਤੇ ਹਟਾਓ ਤਾਂ ਕਿ ਕੈਸ਼ ਸ਼ਾਂਤੀ ਨਾਲ ਕਦੇ ਵੱਡਾ ਨਾ ਹੋ ਜਾਵੇ।
ਰੀਫ੍ਰੈਸ਼ ਨਿਯਮ ਸਧੇ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ ਤਾਂ ਕਿ ਤੁਸੀਂ ਹਰ ਸਕਰੀਨ ਲਈ ਇੱਕ ਵਾਕ ਵਿੱਚ ਸਮਝਾ ਸਕੋ। ਇਹੀ ਜਗ੍ਹਾ ਹੈ ਜਿੱਥੇ ਸਮਝਦਾਰ ਕੈਸ਼ਿੰਗ فائدੇਮੰਦ ਹੁੰਦੀ ਹੈ: ਯੂਜ਼ਰ ਨੂੰ ਤੇਜ਼ ਸਕਰੀਨਾਂ ਮਿਲਦੀਆਂ ਹਨ ਅਤੇ ਐਪ ਭਰੋਸੇਯੋਗ ਰਹਿੰਦੀ ਹੈ।
ਸਭ ਤੋਂ ਸਧਾਰਨ ਨਿਯਮ TTL (time to live) ਹੈ। ਡੇਟਾ ਨੂੰ ਇੱਕ ਟਾਈਮਸਟੈਂਪ ਨਾਲ ਸਟੋਰ ਕਰੋ ਅਤੇ, ਮਿਸਾਲ ਵਜੋਂ, 5 ਮਿੰਟ ਲਈ ਤਾਜਾ ਮੰਨੋ। ਉਸ ਤੋਂ ਬਾਅਦ ਇਹ ਮੁਰਝਾਇਆ ਹੋ ਜਾਂਦਾ ਹੈ। TTL ਉਹਨਾਂ ਡੇਟਾ ਲਈ ਚੰਗਾ ਹੈ ਜੋ "ਆਪਸ਼ਨਲ" ਨੇ ਜਿਵੇਂ ਫੀਡ, ਕੈਟੇਗਰੀਜ਼, ਜਾਂ ਰੇਕਮੈਂਡੇਸ਼ਨ।
ਇੱਕ ਲਾਭਦਾਇਕ ਸੁਧਾਰ soft TTL ਤੇ hard TTL ਵਿੱਚ ਵੰਡਣਾ ਹੈ।
soft TTL ਦੇ ਨਾਲ ਤੁਸੀਂ ਤੁਰੰਤ ਕੈਸ਼ ਡੇਟਾ ਦਿਖਾਉਂਦੇ ਹੋ, ਫਿਰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਰੀਫ੍ਰੈਸ਼ ਕਰਦੇ ਹੋ ਅਤੇ UI ਨੂੰ ਅਪਡੇਟ ਕਰਦੇ ਹੋ ਜੇਕਰ ਕੁਝ ਬਦਲਿਆ। hard TTL ਦੇ ਨਾਲ ਤੁਸੀਂ ਪੁਰਾਣੇ ਡੇਟਾ ਨੂੰ ਰੁਕ ਜਾਂਦੇ ਹੋ ਜਦੋਂ ਇਹ ਮਿਆਦ ਪੂਰੀ ਹੋ ਜਾਂਦੀ ਹੈ; ਤੁਸੀਂ ਲੋਡਰ ਨਾਲ ਰੋਕੇ ਹੋ ਜਾਂ "ਆਫਲਾਈਨ/ਫੇਲਟਾਈ" ਸਟੇਟ ਦਿਖਾਉਂਦੇ ਹੋ। hard TTL ਉਹਨਾਂ ਕੇਸਾਂ ਲਈ ਢੁਕਵਾਂ ਹੈ ਜਿਥੇ ਗਲਤ ਹੋਣਾ ਸੁਸਤ ਹੋਣ ਨਾਲੋਂ ਵੱਡਾ ਨੁਕਸਾਨ ਕਰਦਾ ਹੈ, ਜਿਵੇਂ ਬੈਲੈਂਸ, ਆਰਡਰ ਸਥਿਤੀ, ਜਾਂ ਪਰਮਿਸ਼ਨ।
ਜੇ ਤੁਹਾਡਾ ਬੈਕਏਂਡ ਸਹਾਇਤਾ ਕਰਦਾ ਹੈ ਤਾਂ “ਸਿਰਫ ਜਦ ਬਦਲੇ ਤਾਂ ਰੀਫ੍ਰੈਸ਼” ਨੂੰ ਤਰਜੀਹ ਦਿਓ — ETag, updatedAt, ਜਾਂ ਵਰਜ਼ਨ ਫੀਲਡ ਵਰਗੇ ਹੋ ਸਕਦੇ ਹਨ। ਐਪ ਪੁੱਛ ਸਕਦਾ ਹੈ "ਕੀ ਇਹ ਬਦਲਿਆ ਹੈ?" ਅਤੇ ਜਦ ਕੁਝ ਨਵਾਂ ਨਹੀਂ ਹੁੰਦਾ ਤਾਂ ਪੂਰਾ ਪੇਲੋਡ ਡਾਊਨਲੋਡ ਕਰਨ ਤੋਂ ਬਚ ਸਕਦਾ ਹੈ।
ਯੂਜ਼ਰ-ਫ੍ਰੈਂਡਲੀ ਡੀਫਾਲਟ ਬਹੁਤ ਸਕਰੀਨਾਂ ਲਈ stale-while-revalidate ਹੋ ਸਕਦਾ ਹੈ: ਹੁਣੇ ਦਿਖਾਓ, ਚੁੱਪਚਾਪ ਰੀਫ੍ਰੈਸ਼ ਕਰੋ, ਅਤੇ ਸਿਰਫ ਜਦ ਨਤੀਜਾ ਵੱਖਰਾ ਹੋਵੇ UI ਰੀਡ੍ਰੌ ਕਰੋ। ਇਹ ਤੇਜ਼ੀ ਦਿੰਦਾ ਹੈ ਬਿਨਾਂ ਬੇਕਾਰ ਫਲਿਕਰ ਦੇ।
ਪ੍ਰਤੀ-ਸਕਰੀਨ ਤਾਜਗੀ ਆਮ ਤੌਰ 'ਤੇ ਇਨ੍ਹਾਂ ਵਰਗੀ ਹੁੰਦੀ ਹੈ:
ਨਿਯਮਾਂ ਨੂੰ ਫੈਸਲਾ ਕਰੋ ਆਧਾਰ ਤੇ ਉਸ ਲਾਗਤ ਦੀ ਕਿ ਗਲਤ ਹੋਣ ਦੀ—ਸਿਰਫ ਫੈਚ ਕਰਨ ਦੀ ਲਾਗਤ 'ਤੇ ਨਹੀਂ।
ਕੈਸ਼ ਅਵੈਧਤਾ ਇਕ ਸਵਾਲ ਨਾਲ ਸ਼ੁਰੂ ਹੁੰਦੀ ਹੈ: ਕਿਹੜਾ ਇਵੈਂਟ ਕੈਸ਼ ਡੇਟਾ ਨੂੰ ਇਸ ਲਾਇਕ ਘਟਾ ਦਿੰਦਾ ਹੈ ਕਿ ਰੀਫੈਚ ਕਰਨ ਦੀ ਲਾਗਤ ਠੀਕ ਹੋਵੇ? ਜੇ ਤੁਸੀਂ ਇੱਕ ਛੋਟਾ ਸੈੱਟ ਟ੍ਰਿਗਰ ਚੁਣਦੇ ਹੋ ਅਤੇ ਉਸ 'ਤੇ ਟਿਕੇ ਰਹਿੰਦੇ ਹੋ ਤਾਂ ਵਿਹਾਰ ਭਵਿੱਖਬਾਣੀਯੋਗ ਰਹਿੰਦਾ ਹੈ ਅਤੇ UI ਸਥਿਰ ਮਹਿਸੂਸ ਹੁੰਦੀ ਹੈ।
ਅਸਲ ਐਪਸ ਵਿੱਚ ਸਭ ਤੋਂ ਜ਼ਿਆਦਾ ਮਾਇਨੇ ਰੱਖਣ ਵਾਲੇ ਟ੍ਰਿਗਰ:
ਉਦਾਹਰਨ: ਯੂਜ਼ਰ ਨੇ ਆਪਣੀ ਪ੍ਰੋਫਾਈਲ ਫੋਟੋ ਸੋਧੀ, ਫਿਰ ਵਾਪਸ ਜਾਂਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਸਿਰਫ਼ ਸਮੇਂ-ਆਧਾਰਿਤ ਰੀਫ੍ਰੈਸ਼ 'ਤੇ ਨਿਰਭਰ ਰਹੋਗੇ ਤਾਂ ਪਿਛਲਾ ਸਕਰੀਨ ਪੁਰਾਣੀ ਤਸਵੀਰ ਦਿਖਾ ਸਕਦਾ ਹੈ। ਇਸ ਦੀ ਥਾਂ ਸੋਧ ਨੂੰ ਟ੍ਰਿਗਰ ਮੰਨੋ: ਤੁਰੰਤ cached profile object ਨੂੰ ਅਪਡੇਟ ਕਰੋ ਅਤੇ ਨਵਾਂ ਟਾਈਮਸਟੈਂਪ ਦੇ ਕੇ ਇਸਨੂੰ ਤਾਜਾ ਨਿਰਧਾਰਤ ਕਰੋ।
ਅਵੈਧਤਾ ਨਿਯਮਾਂ ਨੂੰ ਛੋਟਾ ਅਤੇ ਸਪਸ਼ਟ ਰੱਖੋ। ਜੇ ਤੁਸੀਂ ਕਿਸੇ ਕੈਸ਼ ਐਟਰੀ ਨੂੰ ਅਵੈਧ ਕਰਨ ਵਾਲਾ ਸਟ੍ਰਿਕਟ ਇਵੈਂਟ ਨਹੀਂ ਦੱਸ ਸਕਦੇ, ਤਾਂ ਤੁਸੀਂ ਬਹੁਤ ਵਾਰੀ ਰੀਫ੍ਰੈਸ਼ ਕਰੋਂਗੇ (ਸਲੋ, ਫਲਿਕਰਿੰਗ UI) ਜਾਂ ਕਦੇ ਨਹੀਂ (ਸਟੇਲ ਸਕਰੀਨਾਂ)।
ਸ਼ੁਰੂਆਤ ਕਰੋ ਆਪਣੇ ਮੁੱਖ ਸਕਰੀਨਾਂ ਦੀ ਸੂਚੀ ਬਣਾਕੇ ਅਤੇ ਹਰ ਇੱਕ ਨੂੰ ਲੋੜੀਂਦਾ ਡੇਟਾ ਨਿਰਧਾਰਤ ਕਰੋ। ਐਂਡਪੌਇੰਟਾਂ ਬਾਰੇ ਨਾ ਸੋਚੋ, ਯੂਜ਼ਰ-ਦੀਖਣਯੋਗ ਆਬਜੈਕਟਾਂ ਬਾਰੇ ਸੋਚੋ: profile, cart, order list, catalog item, unread count।
ਅਗਲਾ ਕਦਮ ਹੈ ਹਰ ਡੇਟਾ ਕਿਸਮ ਲਈ ਇੱਕ ਸੋਰਸ ਆਫ਼ ਟਰੂਥ ਚੁਣੋ। Flutter ਵਿੱਚ ਇਹ ਆਮ ਤੌਰ 'ਤੇ ਇੱਕ repository ਹੁੰਦਾ ਹੈ ਜੋ ਛੁਪਾਉਂਦਾ ਹੈ ਕਿ ਡੇਟਾ ਕਿੱਥੋਂ ਆ ਰਿਹਾ ਹੈ (ਮੇਮੋਰੀ, ਡਿਸਕ, ਨੈੱਟਵਰਕ)। ਸਕਰੀਨਾਂ ਨੂੰ ਨੈੱਟਵਰਕ ਕਦ ਨੂੰ ਹਿੱਟ ਕਰਨਾ ਹੈ ਇਹ ਫੈਸਲਾ ਨਹੀਂ ਕਰਨਾ ਚਾਹੀਦਾ—ਉਹ repository ਤੋਂ ਡੇਟਾ ਮੰਗਣੇ ਅਤੇ ਵਾਪਸ ਆਏ ਸਟੇਟ 'ਤੇ ਪ੍ਰਤੀਕਿਰਿਆ ਕਰਣੇ ਚਾਹੀਦੇ ਹਨ।
ਇੱਕ ਪ੍ਰਯੋਗਿਕ ਫਲੋ:
ਮੈਟਾਡੇਟਾ ਹੀ ਹੈ ਜੋ ਨਿਯਮ ਲਾਗੂ ਯੋਗ ਬਣਾਉਂਦਾ ਹੈ। ਜੇ ownerUserId ਬਦਲ ਜਾਂਦਾ ਹੈ (ਲੌਗਆਉਟ/ਲੌਗਿਨ) ਤਾਂ ਤੁਸੀਂ ਪੁਰਾਣੇ ਕੈਸ਼ ਰਿਕਾਰਡਾਂ ਨੂੰ ਤੁਰੰਤ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਨਜ਼ਰਅੰਦਾਜ਼ ਕਰ ਸਕਦੇ ਹੋ ਬਜਾਇ ਪਿਛਲੇ ਯੂਜ਼ਰ ਦਾ ਡੇਟਾ ਦਿਖਾਉਣ ਦੇ।
UI ਵਵਹਾਰ ਲਈ ਪਹਿਲਾਂ ਫੈਸਲਾ ਕਰੋ ਕਿ "stale" ਦਾ ਕੀ ਮਤਲਬ ਹੈ। ਇੱਕ ਆਮ ਨਿਯਮ: stale ਡੇਟਾ ਤੁਰੰਤ ਦਿਖਾਓ ਤਾਂ ਕਿ ਸਕਰੀਨ ਖਾਲੀ ਨਾ ਹੋਵੇ, ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਰੀਫ੍ਰੈਸ਼ ਸ਼ੁਰੂ ਕਰੋ, ਅਤੇ ਜਦ ਨਵਾਂ ਡੇਟਾ ਆ ਜਾਵੇ ਤਾਂ ਅਪਡੇਟ ਕਰੋ। ਜੇ ਰੀਫ੍ਰੈਸ਼ ਫੇਲ੍ਹ ਹੋ ਜਾਂਦਾ ਹੈ ਤਾਂ stale ਡੇਟਾ ਦਿਖਾਈ ਰੱਖੇ ਅਤੇ ਇੱਕ ਛੋਟਾ ਸਪਸ਼ਟ ERROR ਦਿਖਾਓ।
ਫਿਰ ਨਿਯਮਾਂ ਨੂੰ ਕੁਝ ਰਹਿਸ਼ਤ ਟੈਸਟਾਂ ਨਾਲ ਲਾਕ ਕਰੋ:
ਇਹੀਂ ਫਰਕ ਹੈ "ਸਾਡਾ ਕੈਸ਼ਿੰਗ ਹੈ" ਅਤੇ "ਸਾਡੀ ਐਪ ਹਰ ਵਾਰੀ ਇੱਕੋ ਤਰ੍ਹਾਂ ਵਰਤਦੀ ਹੈ" ਵਿੱਚ।
ਕੁਝ ਵੀ ਤੇਜ਼ੀ ਨਾਲ ਭਰੋਸਾ तोੜਦਾ ਹੈ ਕਿ ਇੱਕ ਲਿਸਟ ਸਕਰੀਨ ਤੇ ਇੱਕ ਕੀਮਤ ਦਿਖਦੀ ਹੈ, ਤੁਸੀਂ ਡੀਟੇਲ 'ਚ ਜਾ ਕੇ ਉਸ ਨੂੰ ਸੋਧਦੇ ਹੋ, ਅਤੇ ਵਾਪਸ ਆ ਕੇ ਪੁਰਾਣੀ ਕੀਮਤ ਵੇਖਦੇ ਹੋ। ਨੈਵੀਗੇਸ਼ਨ ਦੌਰਾਨ ਇੱਕਸਾਰਤਾ ਇਸ ਗੱਲ ਤੋਂ ਆਉਂਦੀ ਹੈ ਕਿ ਹਰ ਸਕਰੀਨ ਇੱਕੋ ਸੋਰਸ ਤੋਂ ਪੜ੍ਹੇ।
ਮਜ਼ਬੂਤ ਨਿਯਮ ਇਹ ਹੈ: ਇੱਕ ਵਾਰੀ ਫੈਚ ਕਰੋ, ਇੱਕ ਵਾਰੀ ਸਟੋਰ ਕਰੋ, ਬਹੁਤ ਵਾਰੀ ਰੈਂਡਰ ਕਰੋ। ਸਕਰੀਨਾਂ ਨੂੰ ਇੱਕੋ ਏਂਡਪੌਇੰਟ ਨੂੰ ਖੁਦ-ਖੁਦ ਕਾਲ ਕਰਕੇ ਨਿਜੀ ਨਕਲਾਂ ਨਹੀਂ ਰੱਖਣੀਆਂ ਚਾਹੀਦੀਆਂ। ਕੈਸ਼ਡ ਡੇਟਾ ਨੂੰ ਇੱਕ ਸਾਂਝੀ ਸਟੋਰ (ਤੁਹਾਡਾ state management ਲੇਅਰ) ਵਿੱਚ ਰੱਖੋ, ਅਤੇ ਲਿਸਟ ਅਤੇ ਡੀਟੇਲ ਦੋਹਾਂ ਉਸੇ ਡੇਟਾ ਨੂੰ ਵੇਖਣ।
ਮੌਜੂਦਾ ਮੁੱਲ ਅਤੇ ਤਾਜਗੀ ਦਾ ਮਾਲਕ ਇੱਕ ਹੀ ਜਗ੍ਹਾ ਰੱਖੋ। ਸਕਰੀਨ ਰੀਫ੍ਰੈਸ਼ ਦਾ ਬੇਨਤੀ ਕਰ ਸਕਦੀਆਂ ਨੇ, ਪਰ ਉਹਨਾਂ ਨੂੰ ਆਪਣੀਆਂ ਟਾਇਮਰ, ਰੀਟ੍ਰਾਈ, ਅਤੇ ਪਾਰਸਿੰਗ ਨਿਯਮ ਬਣਾਉਣ ਨਹੀਂ ਚਾਹੀਦੀ।
ਅਮਲੀ ਆਦਤਾਂ ਜੋ "ਦੋ ਹਕੀਕਤਾਂ" ਨੂੰ ਰੋਕਦੀਆਂ ਹਨ:
ਚੰਗੇ ਨਿਯਮ ਹੋਣ ਦੇ ਬਾਵਜੂਦ, ਯੂਜ਼ਰ ਕਦੇ-ਕਦੇ stale ਡੇਟਾ ਵੇਖ ਲੈਂਦੇ ਹਨ (ਆਫਲਾਈਨ, ਢੀਲਾ ਨੈੱਟਵਰਕ, ਬੈਕਗ੍ਰਾਊਂਡ). ਇਸਨੂੰ ਛੋਟੇ, ਠੰਡੇ ਸੰਕੇਤਾਂ ਨਾਲ ਸਪਸ਼ਟ ਕਰੋ: "Just updated" ਟਾਈਮਸਟੈਂਪ, ਇਕ ਨਰਮ "Refreshing…" ਇੰਡੀਕੇਟਰ, ਜਾਂ "Offline" ਬੈਜ।
ਸੋਧਾਂ ਲਈ optimistic updates ਅਕਸਰ ਸਭ ਤੋਂ ਵਧੀਆ ਮਹਿਸੂਸ ਹੁੰਦੀਆਂ ਹਨ। ਉਦਾਹਰਨ: ਯੂਜ਼ਰ ਡੀਟੇਲ ਸਕਰੀਨ 'ਤੇ ਉਤਪਾਦ ਦੀ ਕੀਮਤ ਬਦਲਦਾ ਹੈ। shared store ਨੂੰ ਤੁਰੰਤ ਅਪਡੇਟ ਕਰੋ ਤਾਂ ਕਿ ਜਦ ਉਹ ਵਾਪਸ ਲਿਸਟ 'ਤੇ ਆਏ ਤਾਂ ਨਵੀਂ ਕੀਮਤ ਦਿਖਾਈ ਦੇ। ਜੇ ਸੇਵ ਫੇਲ੍ਹ ਹੋ ਜਾਵੇ ਤਾਂ ਪਿਛਲੇ ਮੁੱਲ 'ਤੇ ਰੋਲ ਬੈਕ ਕਰੋ ਅਤੇ ਛੋਟਾ ERROR ਦਿੱਖਾਓ।
ਜ਼ਿਆਦਾਤਰ ਕੈਸ਼ਿੰਗ ਫੇਲਯਰ ਨਿਰਾਸ਼ ਜਿਹੇ ਹੁੰਦੇ ਹਨ: ਕੈਸ਼ ਕੰਮ ਕਰ ਰਿਹਾ ਹੈ, ਪਰ ਕਿਸੇ ਨੂੰ ਇਹ ਸਮਝ ਨਹੀਂ ਆਉਂਦਾ ਕਿ ਕਦੋਂ ਵਰਤਣਾ ਹੈ, ਕਦੋਂ ਉਹ ਖਤਮ ਹੁੰਦਾ, ਅਤੇ ਕੌਣ ਮਾਲਕ ਹੈ।
ਪਹਿਲਾ ਫਸਾਉਣ ਵਾਲਾ ਪੈਰਾਅ ਹੈ metadata ਦੇ ਬਿਨਾਂ ਕੈਸ਼ ਕਰਨਾ। ਜੇ ਤੁਸੀਂ ਸਿਰਫ ਪੇਲੋਡ ਸਟੋਰ ਕਰਦੇ ਹੋ ਤਾਂ ਤੁਸੀਂ ਨਹੀਂ ਦੱਸ ਸਕਦੇ ਕਿ ਇਹ ਪੁਰਾਣਾ ਹੈ, ਕਿਸ ਐਪ ਵਰਜ਼ਨ ਨੇ ਓਸ ਨੂੰ ਬਣਾਇਆ, ਜਾਂ ਕਿਹੜਾ ਯੂਜ਼ਰ ਇਸਦਾ ਮਾਲਕ ਹੈ। ਘੱਟੋ-ਘੱਟ savedAt, ਇੱਕ ਸਧਾਰਨ version number, ਅਤੇ userId (ਜਾਂ tenant key) ਸਟੋਰ ਕਰੋ। ਇਹ ਆਦਤ ਬਹੁਤ ਸਾਰੀਆਂ "ਕਿਉਂ ਇਹ ਸਕਰੀਨ ਗਲਤ ਹੈ?" ਬੱਗਾਂ ਨੂੰ ਰੋਕਦੀ ਹੈ।
ਹੋਰ ਆਮ ਮੁੱਦਾ ਇਹ ਹੈ ਕਿ ਇਕੋ ਡੇਟਾ ਲਈ ਬਹੁਤ ਸਾਰੇ ਕੈਸ਼ ਹਨ ਜਿਨ੍ਹਾਂ ਦਾ ਕੋਈ ਮਾਲਕ ਨਹੀਂ। ਇੱਕ ਲਿਸਟ ਸਕਰੀਨ ਇੱਕ ਮੈਮੋਰੀ ਲਿਸਟ ਰੱਖਦਾ ਹੈ, ਇੱਕ repository ਡਿਸਕ 'ਤੇ ਲਿਖਦਾ ਹੈ, ਅਤੇ ਡੀਟੇਲ ਸਕਰੀਨ ਦੁਬਾਰਾ ਫੈਚ ਕਰਦਾ ਹੈ ਅਤੇ ਕਿਤੇ ਹੋਰ ਸੇਵ ਕਰਦਾ ਹੈ। ਇੱਕ ਸੋਰਸ ਆਫ਼ ਟਰੂਥ ਚੁਣੋ (ਸਧਾਰਨ ਤੌਰ 'ਤੇ repository) ਅਤੇ ਹਰ ਸਕਰੀਨ ਇਸ ਰਾਹੀਂ ਪੜ੍ਹੇ।
ਅਕਾਊਂਟ ਬਦਲਾਅ ਇੱਕ ਆਮ ਫੁਟਗਨ ਹੈ। ਜੇ ਕੋਈ ਲੌਗਆਉਟ ਜਾਂ ਅਕਾਊਂਟ ਸਵਿੱਚ ਕਰਦਾ ਹੈ, ਯੂਜ਼ਰ-ਸਕੋਪਡ ਟੇਬਲਾਂ ਅਤੇ ਕੀਜ਼ ਨੂੰ ਸਾਫ ਕਰੋ। ਨਹੀਂ ਤਾਂ ਤੁਸੀਂ ਥੋੜ੍ਹੇ ਸਮੇਂ ਲਈ ਪਹਿਲੇ ਯੂਜ਼ਰ ਦੀ ਪ੍ਰੋਫਾਈਲ ਫੋਟੋ ਜਾਂ ਆਰਡਰ ਦਿਖਾ ਸਕਦੇ ਹੋ—ਇਹ ਪ੍ਰਾਇਵੇਸੀ ਬ੍ਰੀਚ ਵਰਗਾ ਮਹਿਸੂਸ ਹੁੰਦਾ ਹੈ।
ਪ੍ਰਯੋਗਿਕ ਸੁਧਾਰ ਜੋ ਉੱਪਰ ਦਰਸਾਈ ਸਮੱਸਿਆਵਾਂ ਨੂੰ ਢੱਕਦੇ ਹਨ:
ਉਦਾਹਰਨ: ਤੁਹਾਡੀ ਉਤਪਾਦ ਲਿਸਟ ਤੁਰੰਤ ਕੈਸ਼ ਤੋਂ ਲੋਡ ਹੁੰਦੀ ਹੈ, ਫਿਰ ਚੁੱਪਚਾਪ ਰੀਫ੍ਰੈਸ਼ ਕਰਦੀ ਹੈ। ਜੇ ਰੀਫ੍ਰੈਸ਼ ਫੇਲ੍ਹ ਹੋ ਜਾਵੇ ਤਾਂ cached ਡੇਟਾ ਦਿਖਾਈ ਰੱਖੇ ਪਰ ਸਪਸ਼ਟ ਦਿਓ ਕਿ ਇਹ ਪੁਰਾਣਾ ਹੋ ਸਕਦਾ ਹੈ ਅਤੇ Retry ਦੀ ਪੇਸ਼ਕਸ਼ ਦਿਓ। UI ਨੂੰ ਕਦੇ ਵੀ ਰੀਫ੍ਰੈਸ਼ 'ਤੇ ਬਲਾਕ ਨਾ ਕਰੋ ਜਦ cached ਡੇਟਾ ਠੀਕ ਹੋਵੇ।
ਰਿਲੀਜ਼ ਤੋਂ ਪਹਿਲਾਂ, ਕੈਸ਼ਿੰਗ ਨੂੰ "ਠੀਕ ਲੱਗਦਾ ਹੈ" ਤੋਂ ਨਿਯਮ ਬਣਾਓ ਜੋ ਤੁਸੀਂ ਟੈਸਟ ਕਰ ਸਕੋ। ਯੂਜ਼ਰਾਂ ਨੂੰ ਐਸਾ ਡੇਟਾ ਦੇਖਣਾ ਚਾਹੀਦਾ ਹੈ ਜੋ ਲੌਗਿੰਗ ਬਾਅਦ, ਵਾਪਸੀ ਨੈਵੀਗੇਸ਼ਨ, ਆਫਲਾਈਨ ਹੋਣ, ਜਾਂ ਵੱਖਰੇ ਅਕਾਊਂਟ ਨਾਲ ਸਾਇਨ-ਇਨ ਕਰਨ 'ਤੇ ਵੀ ਸਮਝਦਾਰ ਹੋਵੇ।
ਹਰ ਸਕਰੀਨ ਲਈ ਫੈਸਲਾ ਕਰੋ ਕਿ ਡੇਟਾ ਕਿੰਨੀ ਦੇਰ ਤੱਕ ਤਾਜਾ ਮੰਨਿਆ ਜਾਵੇਗਾ। ਤੇਜ਼-ਰੁਝਣ ਵਾਲੇ ਡੇਟਾ (ਮੇਸੇਜ, ਬੈਲੈਂਸ) ਲਈ ਮਿੰਟ ਹੋ ਸਕਦੇ ਹਨ; ਸਲੋ-ਬਦਲਣ ਵਾਲੇ ਡੇਟਾ (ਸੈਟਿੰਗਜ਼, ਕੈਟਾਗਰੀ) ਲਈ ਘੰਟੇ। ਫਿਰ ਨਿਰਧਾਰਤ ਕਰੋ ਕਿ ਜਦ ਇਹ ਤਾਜਾ ਨਹੀਂ ਰਹਿੰਦਾ ਤਾਂ ਕੀ ਹੁੰਦਾ: ਬੈਕਗ੍ਰਾਊਂਡ ਰੀਫ੍ਰੈਸ਼, ਓਪਨ 'ਤੇ ਰੀਫ੍ਰੈਸ਼, ਜਾਂ ਮੈਨੂਅਲ ਪੁਲ-ਟੂ-ਰੀਫ੍ਰੈਸ਼।
ਹਰ ਡੇਟਾ ਕਿਸਮ ਲਈ ਫੈਸਲਾ ਕਰੋ ਕਿ ਕਿਹੜੇ ਇਵੈਂਟ ਕੈਸ਼ ਨੂੰ ਮਿਟਾਉਣ ਜਾਂ ਬਾਈਪਾਸ ਕਰਨੇ ਹਨ। ਆਮ ਟ੍ਰਿਗਰ ਹਨ: ਲੌਗ ਆਉਟ, ਆਈਟਮ ਸੋਧਣਾ, ਅਕਾਊਂਟ ਸਵਿੱਚ, ਅਤੇ ਐਪ ਅਪਡੇਟ ਜੋ ਡੇਟਾ ਆਕਾਰ ਬਦਲ ਦਿੰਦੇ ਹਨ।
ਯਕੀਨੀ ਬਣਾਓ ਕਿ cached ਐਂਟਰੀਜ਼ ਪੇਲੋਡ ਦੇ ਨਾਲ ਇੱਕ ਛੋਟਾ ਮੈਟਾਡੇਟਾ ਸੈੱਟ ਸਟੋਰ ਕਰਦੀਆਂ ਹਨ:
ਮਾਲਕੀ ਸਾਫ਼ ਹੋ: ਹਰ ਡੇਟਾ ਕਿਸਮ ਲਈ ਇੱਕ repository ਵਰਤੋ (ਉਦਾਹਰਨ: ProductsRepository), ਨਾ ਕਿ ਹਰ ਵਿਜੇਟ ਲਈ। ਵਿਜੇਟ ਡੇਟਾ ਮੰਗਣੇਂ ਚਾਹੀਦੇ ਹਨ, ਨਾਂ ਕਿ ਕੈਸ਼ ਨਿਯਮ ਨਿਰਧਾਰਤ ਕਰਨ।
ਆਫਲਾਈਨ ਵਰਤਾਰਾ ਵੀ ਨਿਰਧਾਰਤ ਅਤੇ ਟੈਸਟ ਕਰੋ। ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਸਕਰੀਨਾਂ ਕੈਸ਼ ਤੋਂ ਕੀ ਦਿਖਾਉਂਦੀਆਂ ਹਨ, ਕਿਹੜੀਆਂ ਕਾਰਵਾਈਆਂ ਅਸਮਰੱਥ ਕੀਤੀਆਂ ਜਾਣ, ਅਤੇ ਤੁਸੀਂ ਕੀ ਟੇਕਸਟ ਦਿਖਾਉਂਦੇ ਹੋ ("Showing saved data" ਦੇ ਨਾਲ ਇੱਕ ਦਰਸ਼ਣਯੋਗ ਰੀਫ੍ਰੈਸ਼ ਨਿਯੰਤਰਣ)। ਹਰ ਕੈਸ਼-ਬੈਕਡ ਸਕਰੀਨ 'ਤੇ ਮੈਨੂਅਲ ਰੀਫ੍ਰੈਸ਼ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਅਤੇ ਅਸਾਨੀ ਨਾਲ ਮਿਲਣਾ ਚਾਹੀਦਾ ਹੈ।
ਇਕ ਸਧਾਰਨ ਦੁਕਾਨ ਐਪ ਸੋਚੋ ਜਿਸ ਵਿੱਚ ਤਿੰਨ ਸਕਰੀਨ ਹਨ: ਉਤਪਾਦ ਕੈਟਾਲਾਗ (ਲਿਸਟ), ਉਤਪਾਦ ਡੀਟੇਲ, ਅਤੇ Favorites ਟੈਬ। ਯੂਜ਼ਰ ਕੈਟਾਲਾਗ ਸਕ੍ਰੋਲ ਕਰਦਾ, ਉਤਪਾਦ ਖੋਲ੍ਹਦਾ, ਅਤੇ ਦਿਲ 'ਤੇ ਟੈਪ ਕਰਕੇ фавੋਰਾਈਟ ਕਰਦਾ। ਲਕੜੀ ਇਹ ਹੈ ਕਿ ਤੇਜ਼ ਮਹਿਸੂਸ ਹੋਵੇ ਬਿਨਾਂ ਗੁੰਝਲਦਾਰ ਮਿਲਾਪ ਦੇ।
ਲੋਕਲ ਤੌਰ 'ਤੇ ਉਨ੍ਹਾਂ ਚੀਜ਼ਾਂ ਨੂੰ ਕੈਸ਼ ਕਰੋ ਜੋ ਤੁਰੰਤ ਰੈਂਡਰ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦੀਆਂ ਹਨ: ਕੈਟਾਲਾਗ ਪੇਜ (IDs, title, price, thumbnail URL, favorite flag), ਉਤਪਾਦ ਡੀਟੇਲ (description, specs, availability, lastUpdated), ਇਮੇਜ ਮੈਟਾਡੇਟਾ (URLs, sizes, cache keys), ਅਤੇ ਯੂਜ਼ਰ ਦੇ favorites (ਉਤਪਾਦ IDs ਦੀ ਸੈੱਟ, ਸੰਭਵਤ: timestamps)।
ਜਦ ਯੂਜ਼ਰ ਕੈਟਾਲਾਗ ਖੋਲ੍ਹਦਾ ਹੈ, cached ਨਤੀਜੇ ਤੁਰੰਤ ਦਿਖਾਓ, ਫਿਰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਰੀਵੈਲੀਡੇਟ ਕਰੋ। ਜੇ ਤਾਜਾ ਡੇਟਾ ਆ ਜਾਂਦਾ ਹੈ ਤਾਂ ਸਿਰਫ਼ ਜੋ ਬਦਲਿਆ ਉਹ ਅਪਡੇਟ ਕਰੋ ਅਤੇ ਸਕ੍ਰੋਲ ਪੋਜ਼ੀਸ਼ਨ ਸਥਿਰ ਰੱਖੋ।
ਫੇਵਰਾਈਟ ਟੌਗਲ ਨੂੰ "ਇੱਕਸਾਰ ਰਹਿਣਾ" ਕਾਰਵਾਈ ਮੰਨੋ। ਲੋਕਲ favorites ਸੈੱਟ ਨੂੰ ਤੁਰੰਤ ਅਪਡੇਟ ਕਰੋ (optimistic), ਫਿਰ ਕਿਸੇ ਵੀ cached product row ਅਤੇ cached product details ਨੂੰ ਅਪਡੇਟ ਕਰੋ। ਜੇ ਨੈੱਟਵਰਕ ਕਾਲ ਫੇਲ੍ਹ ਹੋ ਜਾਵੇ ਤਾਂ ਰੋਲਬੈਕ ਕਰਕੇ ਛੋਟੀ ਸੁਚਨਾ ਦਿਖਾਓ।
ਨੈਵੀਗੇਸ਼ਨ ਦੇ ਸਥਿਰ ਰਹਿਣ ਲਈ ਲਿਸਟ ਬੈਜ ਅਤੇ ਡੀਟੇਲ ਦੇ ਹਾਰਟ ਆਇਕਨ ਨੂੰ ਇੱਕੋ ਸੋਰਸ ਆਫ਼ ਟਰੂਥ (ਤੁਹਾਡਾ ਲੋਕਲ ਕੈਸ਼/ਸਟੋਰ) ਤੋਂ ਚਲਾਓ, ਨਾ ਕਿ ਵੱਖ-ਵੱਖ ਸਕ੍ਰੀਨ ਸਟੇਟ ਤੋਂ। ਲਿਸਟ ਦਾ ਹਾਰਟ ਜਦ ਤੁਸੀਂ ਡੀਟੇਲ ਤੋਂ ਵਾਪਸ ਆਉਂਦੇ ਹੋ ਤੁਰੰਤ ਅਪਡੇਟ ਹੋਵੇ, ਡੀਟੇਲ ਸਕ੍ਰੀਨ ਲਿਸਟ ਤੋਂ ਕੀਤੇ ਬਦਲਾਅ ਨੂੰ ਫੌਰ ਹੀ ਦਿਖਾਏ, ਅਤੇ Favorites ਟੈਬ ਦੀ ਕਾਉਂਟ ਹਰ ਥਾਂ ਮਿਲੇ ਬਿਨਾਂ ਰੀਫੈਚ ਦੇ।
ਸਧਾਰਨ ਰੀਫ੍ਰੈਸ਼ ਨਿਯਮ ਜੋੜੋ: ਕੈਟਾਲਾਗ ਕੈਸ਼ ਤੇਜ਼ੀ ਨਾਲ ਖਤਮ (ਮਿੰਟ), ਉਤਪਾਦ ਡੀਟੇਲ ਥੋੜ੍ਹਾ ਲੰਮਾ, ਅਤੇ favorites ਕਦੇ expire ਨਹੀਂ ਕਰਦੀਆਂ ਪਰ ਲੌਗਿਨ/ਲੌਗਆਉਟ 'ਤੇ ਸਦਾ reconcile ਕਰਦੀਆਂ ਹਨ।
ਜਦ ਤੁਹਾਡੀ ਟੀਮ ਇੱਕ ਪੰਨੇ ਦੇ ਨਿਯਮ ਵੱਲ ਇਸ਼ਾਰਾ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਇਹਨਾਂ ਤੇ ਸਹਿਮਤ ਹੋ ਸਕਦੀ ਹੈ ਤਾਂ ਕੈਸ਼ਿੰਗ ਰਹੱਸਮਈ ਨਹੀਂ ਰਹਿੰਦੀ। ਟੀਚਾ ਬੇਕਮਾਲੀ ਨਹੀਂ ਹੈ—ਮਕਸਦ ਭਵਿੱਖਬਾਣੀਯੋਗ ਵਰਤਾਰਾ ਹੈ ਜੋ ਰੀਲੀਜ਼ਾਂ ਵਿੱਚ ਸਥਿਰ ਰਹੇ।
ਹਰ ਸਕਰੀਨ ਲਈ ਇੱਕ ਛੋਟੀ ਸਾਰਣੀ ਲਿਖੋ ਜੋ ਛੋਟੀ ਹੋਵੇ ਤਾਂ ਕਿ ਬਦਲਾਅ ਦੇ ਵੇਲਿਆਂ ਦੀ ਸਮੀਖਿਆ ਤੇਜ਼ੀ ਨਾਲ ਹੋ ਸਕੇ: ਸਕਰੀਨ ਨਾਮ ਅਤੇ ਮੁੱਖ ਡੇਟਾ, ਕੈਸ਼ ਸਥਾਨ ਅਤੇ ਕੀ, ਤਾਜਗੀ ਨਿਯਮ (TTL, ਇਵੈਂਟ-ਆਧਾਰিত, ਜਾਂ ਮੈਨੂਅਲ), ਅਵੈਧਤਾ ਟ੍ਰਿਗਰ, ਅਤੇ ਰੀਫ੍ਰੈਸ਼ ਦੌਰਾਨ ਯੂਜ਼ਰ ਜੋ ਵੇਖੇ।
ਟਿੁਨਿੰਗ ਦੌਰਾਨ ਹਲਕੀ ਲੌਗਿੰਗ ਜੋੜੋ। cache hits, misses, ਅਤੇ ਕਿਉਂ ਰੀਫ੍ਰੈਸ਼ ਹੋਇਆ (TTL ਖਤਮ, ਯੂਜ਼ਰ ਨੇ ਖਿੱਚਿਆ, ਐਪ ਰੀਜ਼ਿਊਮ, mutation ਪੂਰਾ) ਨੂੰ ਰਿਕਾਰਡ ਕਰੋ। ਜਦ ਕੋਈ ਦਾਖਲ ਕਰੇ "ਇਹ ਲਿਸਟ ਗਲਤ ਮਹਿਸੂਸ ਹੁੰਦੀ ਹੈ" ਤਾਂ ਇਹ ਲੌਗ ਬੱਗ ਨੂੰ ਸੋਲਵ ਕਰਨ ਯੋਗ ਬਣਾਉਂਦੇ ਹਨ।
ਸਾਦੇ TTL ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ, ਫਿਰ ਯੂਜ਼ਰ ਨੋਟਿਸ ਦੇ ਅਧਾਰ ਤੇ ਸੁਧਾਰ ਕਰੋ। ਨਿਊਜ਼ ਫੀਡ 5-10 ਮਿੰਟ ਦੇ stale ਆਸਕਦਾ ਹੈ, ਜਦਕਿ ਆਰਡਰ ਸਥਿਤੀ ਸਕਰੀਨ ਨੂੰ ਰੀਜ਼ਿਊਮ 'ਤੇ ਅਤੇ ਖਰੀਦ-ਕਾਰਵਾਈਆਂ ਤੋਂ ਬਾਅਦ ਰੀਫ੍ਰੈਸ਼ ਚਾਹੀਦਾ ਹੈ।
ਜੇ ਤੁਸੀਂ ਤੇਜ਼ੀ ਨਾਲ Flutter ਐਪ ਬਣਾ ਰਹੇ ਹੋ ਤਾਂ ਪਹਿਲਾਂ ਆਪਣੇ ਡੇਟਾ ਲੇਅਰ ਅਤੇ ਕੈਸ਼ ਨਿਯਮਾਂ ਦੀ ਰੂਪਰੇਖਾ ਬਣਾਉਣ ਵਿੱਚ ਫਾਇਦਾ ਹੋ ਸਕਦਾ ਹੈ। ਉਹਨਾਂ ਲਈ ਜੋ Koder.ai (koder.ai) ਵਰਤ ਰਹੇ ਹਨ, planning mode ਇੱਕ ਵਿਆਵਹਾਰਿਕ ਜਗ੍ਹਾ ਹੈ ਇਹ per-screen ਨਿਯਮ ਲਿਖਣ ਲਈ, ਫਿਰ ਕੋਡ ਬਣਾਉਣ ਲਈ।
ਰੀਫ੍ਰੈਸ਼ ਵਵਹਾਰ ਨੂੰ ਟਿੁਨ ਕਰਦਿਆਂ, ਸਥਿਰ ਸਕਰੀਨਾਂ ਦੀ ਰੱਖਿਆ ਕਰੋ ਜਦ ਤੁਸੀਂ ਪ੍ਰਯੋਗ ਕਰ ਰਹੇ ਹੋ। snapshots ਅਤੇ rollback ਸਮਾਂ ਬਚਾ ਸਕਦੇ ਹਨ ਜਦ ਕੋਈ ਨਵਾਂ ਨਿਯਮ ਗਲਤੀ ਨਾਲ ਫਲਿਕਰ, ਖਾਲੀ ਸਟੇਟ, ਜਾਂ ਗੈਰ-ਇਕਸਾਰ ਕਾਊਂਟ ਲਿਆਏ।
Start with one clear rule per screen: what it may show immediately (cached), when it must refresh, and what the user sees during refresh. If you can’t explain the rule in one sentence, the app will eventually feel inconsistent.
Treat cached data as having a freshness state. If it’s fresh, show it. If it’s stale but usable, show it now and refresh quietly. If it’s must refresh, fetch before showing (or show a loading/offline state). This keeps your UI behavior consistent instead of “sometimes it updates, sometimes it doesn’t.”
Cache things that are read often and can be slightly old without harming the user, like feeds, catalogs, reference data, and basic profile info. Be careful with money- or time-critical data like balances, stock, ETAs, and order status; you can cache it for speed, but force a refresh right before a decision or confirmation step.
Use memory for fast reuse during the current session, like the current profile or recently viewed items. Use disk key-value storage for small, simple items that should survive restarts, like preferences. Use a database when data is large, structured, needs queries, or should work offline, like messages, orders, or an inventory list.
A plain TTL is a good default: consider data fresh for a set time, then refresh. For many screens, a better experience is “show cached now, refresh in the background, then update if changed,” because it avoids blank screens and reduces flicker.
Invalidate on events that clearly change trust in the cache: user edits (create/update/delete), login/logout or account switching, app resume if data is older than your TTL, and explicit user refresh. Keep these triggers small and explicit so you don’t end up refreshing constantly or never refreshing when it matters.
Make both screens read from the same source of truth, not their own private copies. When the user edits something on the details screen, update the shared cached object immediately so the list renders the new value on back navigation, then sync with the server and roll back only if the save fails.
Always store metadata next to the payload, especially a timestamp and a user identifier. On logout or account switch, clear or isolate user-scoped cache entries immediately and cancel in-flight requests tied to the old user so you don’t briefly render the previous user’s data.
Default to keeping stale data visible and show a small, clear error state that offers retry, rather than blanking the screen. If the screen can’t safely show old data, switch to a must-refresh rule and show a loading or offline message instead of pretending the stale value is trustworthy.
Put cache rules in your data layer (for example, repositories) so every screen follows the same behavior. If you’re building quickly in Koder.ai, write the per-screen freshness and invalidation rules in planning mode first, then implement so the UI simply reacts to states instead of inventing its own refresh logic.