উৎপাদনে সেবা কর্মী

পোর্ট্রেট স্ক্রিনশট

সারসংক্ষেপ

Google I/O 2015 ওয়েব অ্যাপকে দ্রুত এবং অফলাইন-প্রথম করতে আমরা কীভাবে পরিষেবা কর্মী লাইব্রেরি ব্যবহার করেছি তা জানুন।

ওভারভিউ

এই বছরের Google I/O 2015 ওয়েব অ্যাপটি Google-এর ডেভেলপার রিলেশনস টিম দ্বারা লেখা হয়েছে, যা আমাদের Instrument- এ বন্ধুদের ডিজাইনের উপর ভিত্তি করে, যারা নিফটি অডিও/ভিজ্যুয়াল পরীক্ষা লিখেছেন৷ আমাদের দলের লক্ষ্য ছিল নিশ্চিত করা যে I/O ওয়েব অ্যাপ (যাকে আমি এর কোডনাম, IOWA দ্বারা উল্লেখ করব) আধুনিক ওয়েব যা করতে পারে তার সবকিছু প্রদর্শন করে। একটি সম্পূর্ণ অফলাইন-প্রথম অভিজ্ঞতা আমাদের থাকা আবশ্যক বৈশিষ্ট্যগুলির তালিকার শীর্ষে ছিল৷

আপনি যদি সম্প্রতি এই সাইটের অন্য কোনো নিবন্ধ পড়ে থাকেন, তাহলে আপনি নিঃসন্দেহে পরিষেবা কর্মীদের সম্মুখীন হয়েছেন, এবং আপনি শুনে অবাক হবেন না যে IOWA-এর অফলাইন সমর্থন তাদের উপর অনেক বেশি নির্ভরশীল। IOWA-এর বাস্তব-বিশ্বের চাহিদার দ্বারা অনুপ্রাণিত হয়ে, আমরা দুটি ভিন্ন অফলাইন ব্যবহারের ক্ষেত্রে দুটি লাইব্রেরি তৈরি করেছি: স্ট্যাটিক রিসোর্সের প্রিক্যাচিং স্বয়ংক্রিয় করতে sw-precache , এবং রানটাইম ক্যাশিং এবং ফলব্যাক কৌশলগুলি পরিচালনা করার জন্য sw-toolbox

লাইব্রেরিগুলি একে অপরের সুন্দরভাবে পরিপূরক করে, এবং আমাদের একটি কার্যকরী কৌশল প্রয়োগ করার অনুমতি দেয় যেখানে IOWA-এর স্ট্যাটিক বিষয়বস্তু "শেল" সর্বদা সরাসরি ক্যাশে থেকে পরিবেশন করা হত এবং গতিশীল বা দূরবর্তী সংস্থানগুলি নেটওয়ার্ক থেকে পরিবেশন করা হয়, ক্যাশে বা স্ট্যাটিক প্রতিক্রিয়াগুলিতে ফলব্যাক সহ প্রয়োজন

sw-precache সঙ্গে precaching

IOWA-এর স্ট্যাটিক রিসোর্স-এর HTML, JavaScript, CSS এবং ছবিগুলি-ওয়েব অ্যাপ্লিকেশনের মূল শেল প্রদান করে। এই সংস্থানগুলি ক্যাশে করার বিষয়ে চিন্তা করার সময় দুটি নির্দিষ্ট প্রয়োজনীয়তা গুরুত্বপূর্ণ ছিল: আমরা নিশ্চিত করতে চেয়েছিলাম যে বেশিরভাগ স্ট্যাটিক সংস্থান ক্যাশে করা হয়েছে এবং সেগুলি আপ টু ডেট রাখা হয়েছে। sw-precache সেই প্রয়োজনীয়তাগুলিকে মাথায় রেখে তৈরি করা হয়েছিল।

বিল্ড-টাইম ইন্টিগ্রেশন

IOWA-এর gulp ভিত্তিক বিল্ড প্রক্রিয়ার সাথে sw-precache , এবং আমরা IOWA ব্যবহার করা সমস্ত স্ট্যাটিক রিসোর্সগুলির একটি সম্পূর্ণ তালিকা তৈরি করা নিশ্চিত করতে গ্লোব প্যাটার্নের একটি সিরিজের উপর নির্ভর করি।

staticFileGlobs: [
    rootDir + '/bower_components/**/*.{html,js,css}',
    rootDir + '/elements/**',
    rootDir + '/fonts/**',
    rootDir + '/images/**',
    rootDir + '/scripts/**',
    rootDir + '/styles/**/*.css',
    rootDir + '/data-worker-scripts.js'
]

বিকল্প পন্থা, যেমন একটি অ্যারেতে ফাইলের নামের তালিকাকে হার্ড কোডিং করা, এবং প্রতিবার সেই ফাইলগুলির যেকোনও পরিবর্তনের সময় একটি ক্যাশে সংস্করণ নম্বর বাম্প করার কথা মনে রাখা অনেক বেশি ত্রুটির প্রবণ ছিল, বিশেষ করে আমাদের একাধিক টিম সদস্য কোড চেক করার কারণে। ম্যানুয়ালি রক্ষণাবেক্ষণ করা অ্যারেতে একটি নতুন ফাইল রেখে কেউ অফলাইন সমর্থন ভাঙতে চায় না! বিল্ড-টাইম ইন্টিগ্রেশন মানে আমরা বিদ্যমান ফাইলগুলিতে পরিবর্তন করতে পারি এবং সেই উদ্বেগ ছাড়াই নতুন ফাইল যোগ করতে পারি।

ক্যাশড রিসোর্স আপডেট করা হচ্ছে

sw-precache একটি বেস সার্ভিস ওয়ার্কার স্ক্রিপ্ট তৈরি করে যাতে প্রতিটি রিসোর্সের জন্য একটি অনন্য MD5 হ্যাশ থাকে যা প্রিক্যাচ করা হয়। প্রতিবার একটি বিদ্যমান সংস্থান পরিবর্তিত হয়, বা একটি নতুন সংস্থান যোগ করা হয়, পরিষেবা কর্মী স্ক্রিপ্টটি পুনরায় তৈরি করা হয়। এটি স্বয়ংক্রিয়ভাবে পরিষেবা কর্মী আপডেট ফ্লোকে ট্রিগার করে, যাতে নতুন সংস্থানগুলি ক্যাশে করা হয় এবং পুরানো সংস্থানগুলি পরিষ্কার করা হয়৷ অভিন্ন MD5 হ্যাশ আছে এমন যেকোন বিদ্যমান সংস্থান যেমন আছে তেমনই রেখে দেওয়া হয়। এর অর্থ হল যে ব্যবহারকারীরা সাইটটি পরিদর্শন করার আগে শুধুমাত্র পরিবর্তিত সংস্থানগুলির ন্যূনতম সেট ডাউনলোড করে, যার ফলে সমগ্র ক্যাশের মেয়াদ শেষ হয়ে যাওয়ার চেয়ে অনেক বেশি কার্যকর অভিজ্ঞতা হয়৷

প্রতিটি ফাইল যা গ্লোব প্যাটার্নগুলির একটির সাথে মেলে তা ডাউনলোড করা হয় এবং প্রথমবার ব্যবহারকারী যখন IOWA পরিদর্শন করে তখন ক্যাশ করা হয়। আমরা নিশ্চিত করার জন্য একটি প্রচেষ্টা করেছি যে পৃষ্ঠাটি রেন্ডার করার জন্য শুধুমাত্র গুরুত্বপূর্ণ সংস্থানগুলিই প্রিক্যাচ করা হয়েছে৷ মাধ্যমিক বিষয়বস্তু, যেমন অডিও/ভিজ্যুয়াল পরীক্ষায় ব্যবহৃত মিডিয়া, অথবা সেশনের স্পিকারের প্রোফাইল চিত্রগুলি, ইচ্ছাকৃতভাবে প্রিক্যাচ করা হয়নি, এবং আমরা পরিবর্তে সেই সংস্থানগুলির জন্য অফলাইন অনুরোধগুলি পরিচালনা করতে sw-toolbox লাইব্রেরি ব্যবহার করেছি৷

sw-toolbox , আমাদের সমস্ত গতিশীল প্রয়োজনের জন্য

উল্লিখিত হিসাবে, একটি সাইটের অফলাইনে কাজ করার জন্য প্রয়োজন এমন প্রতিটি সংস্থান প্রিক্যাচ করা সম্ভব নয়৷ কিছু রিসোর্স অনেক বড় বা কদাচিৎ এটিকে সার্থক করার জন্য ব্যবহার করা হয় এবং অন্যান্য রিসোর্সগুলি গতিশীল, যেমন দূরবর্তী API বা পরিষেবা থেকে পাওয়া প্রতিক্রিয়া। কিন্তু শুধুমাত্র একটি অনুরোধ প্রিক্যাচেড না হওয়ার মানে এই নয় যে এটি একটি NetworkError এ পরিণত হবে। sw-toolbox আমাদের অনুরোধ হ্যান্ডলার বাস্তবায়নের নমনীয়তা দিয়েছে যা কিছু সংস্থানের জন্য রানটাইম ক্যাশিং এবং অন্যদের জন্য কাস্টম ফলব্যাক পরিচালনা করে। আমরা পুশ বিজ্ঞপ্তির প্রতিক্রিয়া হিসাবে আমাদের পূর্বে ক্যাশে করা সংস্থানগুলি আপডেট করতেও এটি ব্যবহার করেছি৷

এখানে কাস্টম অনুরোধ হ্যান্ডলারের কয়েকটি উদাহরণ রয়েছে যা আমরা sw-toolbox এর উপরে তৈরি করেছি। sw-precache এর importScripts parameter মাধ্যমে বেস সার্ভিস ওয়ার্কার স্ক্রিপ্টের সাথে এগুলিকে একীভূত করা সহজ ছিল, যা পরিষেবা কর্মীর সুযোগে স্বতন্ত্র জাভাস্ক্রিপ্ট ফাইলগুলিকে টেনে আনে।

অডিও/ভিজ্যুয়াল পরীক্ষা

অডিও/ভিজ্যুয়াল পরীক্ষার জন্য, আমরা sw-toolbox এর networkFirst cache কৌশল ব্যবহার করেছি। পরীক্ষার জন্য URL প্যাটার্নের সাথে মিলে যাওয়া সমস্ত HTTP অনুরোধ প্রথমে নেটওয়ার্কের বিরুদ্ধে করা হবে, এবং যদি একটি সফল প্রতিক্রিয়া ফেরত দেওয়া হয়, সেই প্রতিক্রিয়াটি ক্যাশে স্টোরেজ API ব্যবহার করে লুকিয়ে রাখা হবে। নেটওয়ার্ক অনুপলব্ধ হলে পরবর্তী অনুরোধ করা হলে, পূর্বে ক্যাশ করা প্রতিক্রিয়া ব্যবহার করা হবে।

যেহেতু প্রতিবার একটি সফল নেটওয়ার্ক প্রতিক্রিয়া ফিরে আসার সময় ক্যাশে স্বয়ংক্রিয়ভাবে আপডেট হয়েছিল, তাই আমাদের নির্দিষ্টভাবে সংস্করণ সংস্থান বা মেয়াদ শেষ হওয়ার দরকার ছিল না।

toolbox.router.get('/experiment/(.+)', toolbox.networkFirst);

স্পিকার প্রোফাইল ইমেজ

স্পিকার প্রোফাইল ইমেজগুলির জন্য, আমাদের লক্ষ্য ছিল একটি প্রদত্ত স্পিকারের চিত্রের পূর্বে ক্যাশে করা সংস্করণ প্রদর্শন করা যদি এটি উপলব্ধ থাকে, যদি এটি না থাকে তবে ছবিটি পুনরুদ্ধার করতে নেটওয়ার্কে ফিরে আসা। যদি সেই নেটওয়ার্ক অনুরোধ ব্যর্থ হয়, চূড়ান্ত ফলব্যাক হিসাবে, আমরা একটি জেনেরিক প্লেসহোল্ডার ইমেজ ব্যবহার করেছি যা প্রিক্যাচ করা ছিল (এবং তাই সর্বদা উপলব্ধ থাকবে)। এটি একটি সাধারণ কৌশল যা চিত্রগুলির সাথে ডিল করার সময় ব্যবহার করা যেতে পারে যা একটি সাধারণ স্থানধারক দিয়ে প্রতিস্থাপন করা যেতে পারে এবং এটি sw-toolbox এর cacheFirst এবং cacheOnly হ্যান্ডলারগুলিকে চেইন করে প্রয়োগ করা সহজ ছিল৷

var DEFAULT_PROFILE_IMAGE = 'images/touch/homescreen96.png';

function profileImageRequest(request) {
    return toolbox.cacheFirst(request).catch(function() {
    return toolbox.cacheOnly(new Request(DEFAULT_PROFILE_IMAGE));
    });
}

toolbox.precache([DEFAULT_PROFILE_IMAGE]);
toolbox.router.get('/(.+)/images/speakers/(.*)',
                    profileImageRequest,
                    {origin: /.*\.googleapis\.com/});
একটি সেশন পৃষ্ঠা থেকে প্রোফাইল ছবি
একটি অধিবেশন পৃষ্ঠা থেকে প্রোফাইল ছবি.

ব্যবহারকারীদের সময়সূচী আপডেট

IOWA-এর অন্যতম প্রধান বৈশিষ্ট্য হল সাইন-ইন করা ব্যবহারকারীদের সেশনের একটি সময়সূচী তৈরি এবং বজায় রাখার অনুমতি দেওয়া যা তারা যোগ দেওয়ার পরিকল্পনা করেছিল। আপনি যেমনটি আশা করেছিলেন, সেশন আপডেটগুলি HTTP POST অনুরোধের মাধ্যমে একটি ব্যাকএন্ড সার্ভারে করা হয়েছিল, এবং ব্যবহারকারী অফলাইনে থাকাকালীন সেই রাজ্য-সংশোধনের অনুরোধগুলি পরিচালনা করার জন্য আমরা কিছু সময় ব্যয় করেছি৷ আমরা IndexedDB-তে সারিবদ্ধ ব্যর্থ অনুরোধগুলির একটি সংমিশ্রণ নিয়ে এসেছি, মূল ওয়েব পৃষ্ঠায় যুক্তি সহ যা সারিবদ্ধ অনুরোধগুলির জন্য IndexedDB চেক করেছে এবং এটি যেটি পাওয়া গেছে তা পুনরায় চেষ্টা করেছে।

var DB_NAME = 'shed-offline-session-updates';

function queueFailedSessionUpdateRequest(request) {
    simpleDB.open(DB_NAME).then(function(db) {
    db.set(request.url, request.method);
    });
}

function handleSessionUpdateRequest(request) {
    return global.fetch(request).then(function(response) {
    if (response.status >= 500) {
        return Response.error();
    }
    return response;
    }).catch(function() {
    queueFailedSessionUpdateRequest(request);
    });
}

toolbox.router.put('/(.+)api/v1/user/schedule/(.+)',
                    handleSessionUpdateRequest);
toolbox.router.delete('/(.+)api/v1/user/schedule/(.+)',
                        handleSessionUpdateRequest);

কারণ পুনঃপ্রচারগুলি মূল পৃষ্ঠার প্রসঙ্গ থেকে করা হয়েছিল, আমরা নিশ্চিত হতে পারি যে তারা ব্যবহারকারীর শংসাপত্রের একটি নতুন সেট অন্তর্ভুক্ত করেছে। একবার পুনঃপ্রচেষ্টা সফল হলে, আমরা ব্যবহারকারীকে জানাতে একটি বার্তা প্রদর্শন করেছি যে তাদের পূর্বে সারিবদ্ধ আপডেটগুলি প্রয়োগ করা হয়েছে৷

simpleDB.open(QUEUED_SESSION_UPDATES_DB_NAME).then(function(db) {
    var replayPromises = [];
    return db.forEach(function(url, method) {
    var promise = IOWA.Request.xhrPromise(method, url, true).then(function() {
        return db.delete(url).then(function() {
        return true;
        });
    });
    replayPromises.push(promise);
    }).then(function() {
    if (replayPromises.length) {
        return Promise.all(replayPromises).then(function() {
        IOWA.Elements.Toast.showMessage(
            'My Schedule was updated with offline changes.');
        });
    }
    });
}).catch(function() {
    IOWA.Elements.Toast.showMessage(
    'Offline changes could not be applied to My Schedule.');
});

অফলাইন Google Analytics

অনুরূপ শিরায়, আমরা একটি হ্যান্ডলার প্রয়োগ করেছি যে কোনো ব্যর্থ গুগল অ্যানালিটিক্স অনুরোধ সারিবদ্ধ করার জন্য এবং পরবর্তীতে সেগুলি পুনরায় চালানোর চেষ্টা করার জন্য, যখন নেটওয়ার্কটি আশা করা যায় উপলব্ধ ছিল। এই পদ্ধতির সাথে, অফলাইন থাকার অর্থ এই নয় যে Google অ্যানালিটিক্স অফার করা অন্তর্দৃষ্টিগুলিকে ত্যাগ করা৷ আমরা প্রতিটি সারিবদ্ধ অনুরোধে qt প্যারামিটার যোগ করেছি, অনুরোধটি প্রথম চেষ্টা করার পর থেকে যে পরিমাণ সময় অতিবাহিত হয়েছে তার জন্য সেট করা হয়েছে, যাতে একটি সঠিক ইভেন্ট অ্যাট্রিবিউশন সময় এটি Google Analytics ব্যাকএন্ডে তৈরি করে। Google Analytics আনুষ্ঠানিকভাবে মাত্র 4 ঘন্টা পর্যন্ত qt এর মান সমর্থন করে, তাই আমরা যত তাড়াতাড়ি সম্ভব সেই অনুরোধগুলি পুনরায় প্লে করার সর্বোত্তম প্রচেষ্টা করেছি, প্রতিবার পরিষেবা কর্মী শুরু করার সময়।

var DB_NAME = 'offline-analytics';
var EXPIRATION_TIME_DELTA = 86400000;
var ORIGIN = /https?:\/\/((www|ssl)\.)?google-analytics\.com/;

function replayQueuedAnalyticsRequests() {
    simpleDB.open(DB_NAME).then(function(db) {
    db.forEach(function(url, originalTimestamp) {
        var timeDelta = Date.now() - originalTimestamp;
        var replayUrl = url + '&qt=' + timeDelta;
        fetch(replayUrl).then(function(response) {
        if (response.status >= 500) {
            return Response.error();
        }
        db.delete(url);
        }).catch(function(error) {
        if (timeDelta > EXPIRATION_TIME_DELTA) {
            db.delete(url);
        }
        });
    });
    });
}

function queueFailedAnalyticsRequest(request) {
    simpleDB.open(DB_NAME).then(function(db) {
    db.set(request.url, Date.now());
    });
}

function handleAnalyticsCollectionRequest(request) {
    return global.fetch(request).then(function(response) {
    if (response.status >= 500) {
        return Response.error();
    }
    return response;
    }).catch(function() {
    queueFailedAnalyticsRequest(request);
    });
}

toolbox.router.get('/collect',
                    handleAnalyticsCollectionRequest,
                    {origin: ORIGIN});
toolbox.router.get('/analytics.js',
                    toolbox.networkFirst,
                    {origin: ORIGIN});

replayQueuedAnalyticsRequests();

পুশ নোটিফিকেশন ল্যান্ডিং পেজ

পরিষেবা কর্মীরা শুধু IOWA-এর অফলাইন কার্যকারিতাই পরিচালনা করেননি—তারা পুশ বিজ্ঞপ্তিগুলিকেও চালিত করে যা আমরা ব্যবহারকারীদের তাদের বুকমার্ক করা সেশনের আপডেট সম্পর্কে অবহিত করতে ব্যবহার করি। সেই বিজ্ঞপ্তিগুলির সাথে যুক্ত ল্যান্ডিং পৃষ্ঠা আপডেট করা সেশনের বিবরণ প্রদর্শন করে৷ সেই ল্যান্ডিং পৃষ্ঠাগুলি ইতিমধ্যেই সামগ্রিক সাইটের অংশ হিসাবে ক্যাশে করা হয়েছে, তাই তারা ইতিমধ্যেই অফলাইনে কাজ করেছে, কিন্তু আমাদের নিশ্চিত করতে হবে যে সেই পৃষ্ঠায় সেশনের বিবরণ আপ টু ডেট ছিল, এমনকি অফলাইনে দেখা হলেও। এটি করার জন্য, আমরা পূর্বে ক্যাশে করা সেশনের মেটাডেটা পরিবর্তন করেছি যে আপডেটগুলি পুশ নোটিফিকেশনকে ট্রিগার করেছিল এবং আমরা ফলাফলটি ক্যাশে সংরক্ষণ করেছি। এই আপ-টু-ডেট তথ্যটি পরের বার সেশনের বিবরণ পৃষ্ঠা খোলার সময় ব্যবহার করা হবে, সেটা অনলাইনে হোক বা অফলাইনে হোক।

caches.open(toolbox.options.cacheName).then(function(cache) {
    cache.match('api/v1/schedule').then(function(response) {
    if (response) {
        parseResponseJSON(response).then(function(schedule) {
        sessions.forEach(function(session) {
            schedule.sessions[session.id] = session;
        });
        cache.put('api/v1/schedule',
                    new Response(JSON.stringify(schedule)));
        });
    } else {
        toolbox.cache('api/v1/schedule');
    }
    });
});

Gotchas এবং বিবেচনা

অবশ্যই, কেউ IOWA এর স্কেলের একটি প্রকল্পে কয়েকটি গোটচা ছাড়াই কাজ করে না। আমরা যেগুলির মধ্যে ছুটে গিয়েছিলাম এবং কীভাবে আমরা সেগুলিকে ঘিরে কাজ করেছি তা এখানে রয়েছে৷

বাসি বিষয়বস্তু

যখনই আপনি একটি ক্যাশিং কৌশল পরিকল্পনা করছেন, পরিষেবা কর্মীদের মাধ্যমে বা স্ট্যান্ডার্ড ব্রাউজার ক্যাশের মাধ্যমে প্রয়োগ করা হোক না কেন, যত তাড়াতাড়ি সম্ভব সম্পদ সরবরাহ করার বনাম নতুনতম সংস্থান সরবরাহ করার মধ্যে একটি ট্রেডঅফ রয়েছে। sw-precache এর মাধ্যমে, আমরা আমাদের অ্যাপ্লিকেশনের শেলের জন্য একটি আক্রমণাত্মক ক্যাশে-প্রথম কৌশল প্রয়োগ করেছি, যার অর্থ আমাদের পরিষেবা কর্মী পৃষ্ঠায় HTML, JavaScript এবং CSS ফেরত দেওয়ার আগে আপডেটের জন্য নেটওয়ার্ক পরীক্ষা করবে না।

সৌভাগ্যবশত, পৃষ্ঠাটি ইতিমধ্যে লোড হওয়ার পরে নতুন সামগ্রী কখন উপলব্ধ ছিল তা সনাক্ত করতে আমরা পরিষেবা কর্মী লাইফসাইকেল ইভেন্টগুলির সুবিধা নিতে সক্ষম হয়েছি। যখন একটি আপডেট করা পরিষেবা কর্মী সনাক্ত করা হয়, আমরা ব্যবহারকারীকে একটি টোস্ট বার্তা প্রদর্শন করি যাতে তারা জানায় যে তাদের নতুন সামগ্রী দেখতে তাদের পৃষ্ঠাটি পুনরায় লোড করা উচিত।

if (navigator.serviceWorker && navigator.serviceWorker.controller) {
    navigator.serviceWorker.controller.onstatechange = function(e) {
    if (e.target.state === 'redundant') {
        var tapHandler = function() {
        window.location.reload();
        };
        IOWA.Elements.Toast.showMessage(
        'Tap here or refresh the page for the latest content.',
        tapHandler);
    }
    };
}
সর্বশেষ কন্টেন্ট টোস্ট
"সর্বশেষ কন্টেন্ট" টোস্ট।

নিশ্চিত করুন স্ট্যাটিক বিষয়বস্তু স্ট্যাটিক!

sw-precache স্থানীয় ফাইলের বিষয়বস্তুগুলির একটি MD5 হ্যাশ ব্যবহার করে এবং শুধুমাত্র সেই সংস্থানগুলি নিয়ে আসে যার হ্যাশ পরিবর্তিত হয়েছে। এর মানে হল যে সংস্থানগুলি প্রায় সঙ্গে সঙ্গেই পৃষ্ঠায় পাওয়া যায়, কিন্তু এর মানে এটাও যে একবার কিছু ক্যাশে করা হলে, আপডেট করা পরিষেবা কর্মী স্ক্রিপ্টে একটি নতুন হ্যাশ বরাদ্দ না করা পর্যন্ত এটি ক্যাশেই থাকবে।

কনফারেন্সের প্রতিটি দিনের জন্য আমাদের ব্যাকএন্ডকে গতিশীলভাবে লাইভস্ট্রিম YouTube ভিডিও আইডি আপডেট করার প্রয়োজনের কারণে আমরা I/O চলাকালীন এই আচরণের সাথে একটি সমস্যায় পড়েছিলাম । কারণ অন্তর্নিহিত টেমপ্লেট ফাইলটি স্থির ছিল এবং পরিবর্তিত হয়নি, আমাদের পরিষেবা কর্মী আপডেট ফ্লো ট্রিগার করা হয়নি, এবং YouTube ভিডিওগুলি আপডেট করার সাথে সার্ভার থেকে একটি গতিশীল প্রতিক্রিয়া বলতে যা বোঝানো হয়েছিল তা অনেক ব্যবহারকারীর জন্য ক্যাশে করা প্রতিক্রিয়া হিসাবে শেষ হয়েছে .

আপনার ওয়েব অ্যাপ্লিকেশনটি সুগঠিত হয়েছে তা নিশ্চিত করে আপনি এই ধরণের সমস্যা এড়াতে পারেন যাতে শেলটি সর্বদা স্থির থাকে এবং নিরাপদে প্রিক্যাচ করা যায়, যখন শেলটি পরিবর্তন করে এমন যেকোনো গতিশীল সংস্থান স্বাধীনভাবে লোড হয়।

ক্যাশে-বাস্ট আপনার precaching অনুরোধ

যখন sw-precache রিসোর্সগুলি precache করার জন্য অনুরোধ করে, তখন এটি সেই প্রতিক্রিয়াগুলিকে অনির্দিষ্টকালের জন্য ব্যবহার করে যতক্ষণ না এটি মনে করে যে ফাইলের জন্য MD5 হ্যাশ পরিবর্তন হয়নি। এর মানে হল যে প্রিক্যাচিং অনুরোধের প্রতিক্রিয়া একটি নতুন এবং ব্রাউজারের HTTP ক্যাশে থেকে ফিরে আসে না তা নিশ্চিত করা বিশেষভাবে গুরুত্বপূর্ণ৷ (হ্যাঁ, একটি পরিষেবা কর্মী fetch() করা অনুরোধগুলি ব্রাউজারের HTTP ক্যাশে থেকে ডেটার সাথে প্রতিক্রিয়া জানাতে পারে৷)

আমরা যে প্রতিক্রিয়াগুলি precache করি তা সরাসরি নেটওয়ার্ক থেকে এবং ব্রাউজারের HTTP ক্যাশে নয় তা নিশ্চিত করার জন্য, sw-precache স্বয়ংক্রিয়ভাবে প্রতিটি ইউআরএলে একটি ক্যাশে-বাস্টিং ক্যোয়ারী প্যারামিটার যোগ করে যা এটি অনুরোধ করে। আপনি যদি sw-precache ব্যবহার না করেন এবং আপনি একটি ক্যাশে-প্রথম প্রতিক্রিয়া কৌশল ব্যবহার করছেন, তবে নিশ্চিত করুন যে আপনি নিজের কোডে অনুরূপ কিছু করছেন !

ক্যাশে-বাস্টিংয়ের একটি পরিষ্কার সমাধান হল reload করার জন্য প্রিক্যাচিংয়ের জন্য ব্যবহৃত প্রতিটি Request ক্যাশে মোড সেট করা, যা নিশ্চিত করবে যে প্রতিক্রিয়া নেটওয়ার্ক থেকে আসবে। যাইহোক, এই লেখা পর্যন্ত, ক্যাশে মোড বিকল্পটি Chrome-এ সমর্থিত নয়

লগ ইন এবং আউট জন্য সমর্থন

IOWA ব্যবহারকারীদের তাদের Google অ্যাকাউন্ট ব্যবহার করে লগ ইন করার এবং তাদের কাস্টমাইজড ইভেন্টের সময়সূচী আপডেট করার অনুমতি দিয়েছে, কিন্তু এর মানে হল যে ব্যবহারকারীরা পরে লগ আউট করতে পারে। ব্যক্তিগতকৃত প্রতিক্রিয়া ডেটা ক্যাশ করা স্পষ্টতই একটি জটিল বিষয় এবং সর্বদা একটি একক সঠিক পদ্ধতি নেই।

যেহেতু আপনার ব্যক্তিগত সময়সূচী দেখা, এমনকি অফলাইনে থাকাকালীনও, IOWA অভিজ্ঞতার মূল বিষয় ছিল, তাই আমরা সিদ্ধান্ত নিয়েছি যে ক্যাশে করা ডেটা ব্যবহার করা উপযুক্ত। যখন একজন ব্যবহারকারী সাইন আউট করেন, আমরা পূর্বে ক্যাশে করা সেশন ডেটা সাফ করার বিষয়টি নিশ্চিত করেছিলাম।

    self.addEventListener('message', function(event) {
      if (event.data === 'clear-cached-user-data') {
        caches.open(toolbox.options.cacheName).then(function(cache) {
          cache.keys().then(function(requests) {
            return requests.filter(function(request) {
              return request.url.indexOf('api/v1/user/') !== -1;
            });
          }).then(function(userDataRequests) {
            userDataRequests.forEach(function(userDataRequest) {
              cache.delete(userDataRequest);
            });
          });
        });
      }
    });

অতিরিক্ত ক্যোয়ারী পরামিতি জন্য দেখুন!

যখন কোনও পরিষেবা কর্মী একটি ক্যাশে করা প্রতিক্রিয়া পরীক্ষা করে, তখন এটি কী হিসাবে একটি অনুরোধ URL ব্যবহার করে। ডিফল্টরূপে, অনুরোধের URLটি অবশ্যই URL-এর অনুসন্ধান অংশে যেকোন ক্যোয়ারী প্যারামিটার সহ ক্যাশে করা প্রতিক্রিয়া সঞ্চয় করতে ব্যবহৃত URL-এর সাথে হুবহু মিলতে হবে৷

আমাদের ট্র্যাফিক কোথা থেকে আসছে তা ট্র্যাক করার জন্য যখন আমরা URL প্যারামিটার ব্যবহার করা শুরু করি তখন এটি বিকাশের সময় আমাদের জন্য একটি সমস্যা সৃষ্টি করে। উদাহরণ স্বরূপ, আমরা utm_source=notification প্যারামিটার যুক্ত করেছিলাম URL-এ যা খোলা হয়েছিল আমাদের একটি বিজ্ঞপ্তিতে ক্লিক করার সময়, এবং utm_source=web_app_manifest ব্যবহার করেছি আমাদের ওয়েব অ্যাপ ম্যানিফেস্টের জন্য start_url এ। পূর্বে ক্যাশ করা প্রতিক্রিয়াগুলির সাথে মিলে যাওয়া URLগুলি যখন সেই প্যারামিটারগুলি যুক্ত করা হয়েছিল তখন মিস হিসাবে উঠে আসছে৷

এটি আংশিকভাবে ignoreSearch বিকল্প দ্বারা সম্বোধন করা হয়েছে যা Cache.match() কল করার সময় ব্যবহার করা যেতে পারে। দুর্ভাগ্যবশত, Chrome এখনও ignoreSearch সমর্থন করে না , এবং এমনকি যদি এটি করেও, এটি একটি সব-বা-কিছুই নয়। আমাদের যা দরকার ছিল তা হল কিছু ইউআরএল ক্যোয়ারী প্যারামিটার উপেক্ষা করার একটি উপায় যা অর্থপূর্ণ ছিল।

আমরা একটি ক্যাশে ম্যাচের জন্য চেক করার আগে কিছু ক্যোয়ারী প্যারামিটার বের করার জন্য sw-precache প্রসারিত করেছি এবং ignoreUrlParametersMatching বিকল্পের মাধ্যমে কোন প্যারামিটারগুলি উপেক্ষা করা হয়েছে তা ডেভেলপারদের কাস্টমাইজ করার অনুমতি দেয়। এখানে অন্তর্নিহিত বাস্তবায়ন আছে:

function stripIgnoredUrlParameters(originalUrl, ignoredRegexes) {
    var url = new URL(originalUrl);

    url.search = url.search.slice(1)
    .split('&')
    .map(function(kv) {
        return kv.split('=');
    })
    .filter(function(kv) {
        return ignoredRegexes.every(function(ignoredRegex) {
        return !ignoredRegex.test(kv[0]);
        });
    })
    .map(function(kv) {
        return kv.join('=');
    })
    .join('&');

    return url.toString();
}

হোয়াট দিস মিন্স ফর ইউ

Google I/O ওয়েব অ্যাপে পরিষেবা কর্মী সংহতকরণ সম্ভবত সবচেয়ে জটিল, বাস্তব-বিশ্বের ব্যবহার যা এই সময়ে স্থাপন করা হয়েছে। আমরা sw-precache এবং sw-toolbox তৈরি করা টুলগুলি ব্যবহার করে ওয়েব ডেভেলপার সম্প্রদায়ের সাথে সাথে আপনার নিজস্ব ওয়েব অ্যাপ্লিকেশনগুলিকে শক্তি দেওয়ার জন্য আমরা যে কৌশলগুলি বর্ণনা করছি তার জন্য অপেক্ষা করছি৷ পরিষেবা কর্মীরা একটি প্রগতিশীল বর্ধন যা আপনি আজ ব্যবহার শুরু করতে পারেন, এবং যখন একটি সঠিকভাবে কাঠামোগত ওয়েব অ্যাপের অংশ হিসাবে ব্যবহার করা হয়, তখন গতি এবং অফলাইন সুবিধাগুলি আপনার ব্যবহারকারীদের জন্য উল্লেখযোগ্য।