زیادہ تر ویب ایپس اب بھی امیج اپ لوڈز کو ایک بلیک باکس کی طرح ہینڈل کرتی ہیں۔ ایک صارف فائل ڈراپ کرتا ہے، براؤزر اسے بھیج دیتا ہے، اور سرور یا تو پے لوڈ کو قبول کر لیتا ہے یا 413 ایرر دے دیتا ہے جس کے لیے کوئی تیار نہیں ہوتا۔ براؤزر سائیڈ کمپریشن اس صورتحال کو بدل دیتی ہے۔ یہ آپ کو وائر (wire) تک پہنچنے سے پہلے پے لوڈز کو چھوٹا کرنے کا موقع دیتی ہے، جس کا مطلب ہے تیز تر اپ لوڈز، کم بینڈوتھ بلز، اور سرور ٹائم آؤٹ کا کم ہونا۔ لیکن اس کام میں غلطی کرنا آسان ہے۔ اگر آپ کمپریشن کو صرف "کوالٹی" کے نام سے ایک جادوئی سلائیڈر سمجھیں گے، تو آپ خراب تصاویر، کھچی ہوئی تھمب نیلز، اور الجھن زدہ صارف تجربہ فراہم کریں گے۔ بہتر طریقہ یہ ہے کہ پورے بہاؤ (flow) کو ایک پائپ لائن کے طور پر دیکھا جائے۔
سلائیڈرز کے بجائے پائپ لائنز کے بارے میں سوچیں
کام کو الگ الگ مراحل میں تقسیم کریں۔ ان پٹ ایلیمنٹ سے فائل پڑھیں۔ تصویر کو اپنے مطلوبہ ڈائمینشنز تک اسکیل کریں۔ ایک نیا Blob انکوڈ کریں۔ پھر نتیجہ واپس صارف کو رینڈر کریں۔ ہر مرحلہ ایک کام کرتا ہے اور اپنا آؤٹ پٹ اگلے مرحلے کو بھیجتا ہے۔ یہ علیحدگی صرف کوڈ کو صاف ستھرا نہیں بناتی، بلکہ یہ یونٹ ٹیسٹنگ کو بھی آسان بنا دیتی ہے۔ آپ فائل ان پٹ کو چھوئے بغیر اسکیلنگ مرحلے میں ایک معلوم بفر (buffer) دے سکتے ہیں۔ آپ سرور کے راؤنڈ ٹرپ کا انتظار کیے بغیر یہ تصدیق کر سکتے ہیں کہ آپ کا انکوڈر 200 KB سے کم کا JPEG تیار کر رہا ہے۔ جب کچھ خراب ہوتا ہے، تو آپ کو بالکل معلوم ہوتا ہے کہ کون سا مرحلہ ناکام ہوا۔
ان ذمہ داریوں کو الگ رکھنا اپ لوڈ کے دوران غیر متوقع مسائل سے بھی بچاتا ہے۔ اگر آپ اسکیلنگ اور انکوڈنگ کو ایک ہی الجھے ہوئے فنکشن میں بند کر دیتے ہیں، تو درمیان میں ہونے والی ڈی کوڈنگ کی غلطی آپ کے اپ لوڈ کیو (queue) کو غیر مستقل حالت میں چھوڑ سکتی ہے۔ ایک پائپ لائن آپ کو ہر حد (boundary) پر تصدیق کرنے پر مجبور کرتی ہے۔ اگر فائل کو ڈی کوڈ نہیں کیا جا سکتا، تو آپ کینوس بنانے سے پہلے ہی اسے پکڑ لیتے ہیں۔ اگر انکوڈ شدہ Blob بہت بڑا ہے، تو آپ سرور کو اسے اسٹور کرنے کے لیے کہنے سے پہلے ہی اسے پکڑ لیتے ہیں۔
کوڈ لکھنے سے پہلے ایک معاہدہ (Contract) طے کریں
اس سے پہلے کہ کوئی کینوس ڈرا کال (canvas draw call) لکھے، قواعد لکھ لیں اور انہیں ٹیم کے ساتھ شیئر کریں۔ منظور شدہ MIME types کا انتخاب کریں۔ کیا آپ JPEG، PNG، WebP، یا AVIF کی اجازت دیں گے؟ ہر ایک کے الفا چینلز (alpha channels)، براؤزر سپورٹ، اور CPU کاسٹ کے حوالے سے مختلف اثرات ہوتے ہیں۔ زیادہ سے زیادہ ان پٹ سائز مقرر کریں۔ کسی فلیگ شپ فون سے لی گئی 30 MB کی خام (raw) تصویر اگر آپ مکمل طور پر میموری میں ڈی کوڈ کرنے کی کوشش کریں گے، تو یہ پرانے لیپ ٹاپ کو فریز یا کریش کر دے گی۔ زیادہ سے زیادہ آؤٹ پٹ ڈائمینشنز (dimensions) متعین کریں۔ اگر آپ کا UI کبھی بھی 2048 پکسلز سے زیادہ چوڑی تصاویر نہیں دکھاتا، تو 6000 پکسل چوڑی تصویر کو پائپ لائن سے گزرنے دینے کا کوئی فائدہ نہیں۔
سب سے اہم بات یہ ہے کہ ڈی کوڈنگ کی ناکامیوں کے لیے منصوبہ بندی کریں۔ ایک خراب فائل، ایک غیر معمولی کلر پروفائل، یا ادھورا اپ لوڈ Image constructor پر ایرر دے سکتا ہے۔ آپ کی پائپ لائن میں ایک واضح catch block اور انسان کے پڑھنے کے قابل ایرر میسج ہونا چاہیے۔ براؤزر کو خاموشی سے کام چھوڑنے نہ دیں اور صارف کو صرف سپنر (spinner) گھومتا دیکھ کر خالی نہ چھوڑیں۔
تصویر کا احترام کریں
ڈسٹورشن (Distortion) غیر پیشہ ورانہ لگتا ہے۔ اسپیکٹ ریشو (aspect ratio) کو برقرار رکھیں اور طویل ترین سائیڈ کو محدود کریں۔ اگر آپ کا مطلوبہ باکس 1024x1024 پکسلز ہے، تو 4000x3000 کی تصویر 1024x768 پر ہونی چاہیے، نہ کہ 1024x1024 پر۔ طویل کنارے سے اسکیل فیکٹر کا حساب لگائیں اور چھوٹے کنارے کو اس کے مطابق ہونے دیں۔ یہ تصاویر کو عجیب شکلوں میں کھنچنے سے روکتا ہے۔
اصل ایکسپورٹ کے لیے، کینوس کا toBlob میتھڈ استعمال کریں۔ یہ آپ کو آؤٹ پٹ فارمیٹ اور کوالٹی سیٹنگ پر براہ راست کنٹرول دیتا ہے، اور یہ ایسنکرونسلی (asynchronously) چلتا ہے تاکہ آپ کا مین تھریڈ بلاک نہ ہو۔ ایک آف اسکرین کینوس بنائیں، اس پر ری سائز شدہ تصویر بنائیں، پھر اپنی پسندیدہ ٹائپ اور کوالٹی ویلیو کے ساتھ canvas.toBlob کو کال کریں۔ وہ نیا Blob ہی ہے جو آپ اپنے اپ لوڈ لاجک یا اسٹوریج API کو دیتے ہیں۔
ثبوت دکھائیں
کمپریشن ایک نظر نہ آنے والا کام ہے۔ اگر آپ اعداد و شمار سامنے نہیں لائیں گے، تو صارفین اس عمل پر بھروسہ نہیں کریں گے۔ ایک ایسا انٹرفیس بنائیں جو انہیں اصل تصویر کا نتیجے کے ساتھ موازنہ کرنے کی اجازت دے۔ اصل فائل کا سائز، نئی فائل کا سائز، نئی ڈائمینشنز، اور حتمی فارمیٹ ٹائپ دکھائیں۔ ایک 4.2 MB کی فون فوٹو کو 380 KB WebP میں بدلتے دیکھنا اس خوف کو ختم کر دیتا ہے کہ آپ خفیہ طور پر ان کی تصویر خراب کر رہے ہیں۔
یہ شفافیت ٹربل شوٹنگ میں بھی مدد دیتی ہے۔ جب کوئی صارف شکایت کرتا ہے کہ اپ لوڈ ناکام ہو گیا، تو پہلی چیز جو آپ چیک کریں گے وہ یہ ہوگی کہ آیا آؤٹ پٹ ڈائمینشنز آپ کے سرور کی حد سے تجاوز کر گئیں، یا کیا فارمیٹ PNG سے JPEG میں تبدیل ہو گیا اور الفا چینل ختم ہو گیا۔ یہ ڈیٹا UI میں رکھیں تاکہ صارف سپورٹ ٹکٹ کھولنے سے پہلے خود مسئلے کی تشخیص کر سکے۔
پری سیٹس (Presets) دوبارہ کمپریشن سے بہتر ہیں
ایک ہی تصویر کو کبھی بھی دو بار کمپریس نہ کریں۔ ایک لوسی انکوڈر (lossy encoder) کے ذریعے ہر بار گزرنے سے تفصیلات کم ہوتی جاتی ہیں اور بلاکی آرٹی فیکٹس (artifacts) پیدا ہوتے ہیں۔ اگر آپ صارف کو بار بار "optimize" کرنے کی اجازت دیتے ہیں، تو تیسری جنریشن ایک فوٹو کاپی کی فوٹو کاپی جیسی لگے گی۔ اس کے بجائے، ہر آؤٹ پٹ کو اصل فائل سے تیار کریں اور پری سیٹس پیش کریں:
- چھوٹی فائل: تھمب نیلز یا تیز پری ویوز کے لیے کوالٹی کو کم رکھیں اور ڈائمینشنز کو سختی سے محدود کریں۔
- متوازن: مناسب ڈائمینشنز کے ساتھ درمیانی درجے کی کوالٹی کا ہدف رکھیں، جو سوشل فیڈز اور گیلریوں کے لیے موزوں ہو۔
- زیادہ تفصیل: فوٹوگرافی، آرٹ ورک، یا پرنٹ پری ویوز کے لیے کوالٹی کو بلند رکھیں اور بڑی ڈائمینشنز برقرار رکھیں۔
اصل Blob کو میموری میں محفوظ کریں تاکہ صارف معیار میں بار بار کمی (loss) کے بغیر پری سیٹس کے درمیان سوئچ کر سکے۔ ہمیشہ اصل ماخذ (source) سے جنریٹ کریں، آخری آؤٹ پٹ سے کبھی نہیں۔
ویسے ہی ٹیسٹ کریں جیسے آپ کے صارفین اپ لوڈ کرتے ہیں
آپ کی ڈویلپمنٹ مشین جس میں فائبر کنکشن اور 32 GB RAM ہے، حقیقت نہیں ہے۔ ان اصل فائلوں کے ساتھ ٹیسٹ کریں جو حقیقی صارفین استعمال کرتے ہیں۔ iOS اور Android کے فون فوٹوز مختلف میٹا ڈیٹا اورینٹیشنز استعمال کرتے ہیں اور ہو سکتا ہے کہ وہ HEIC ذرائع سے ہوں۔ لوگوز اور آئیکنز جیسے شفاف اثاثے (transparent assets) JPEG کنورژن کے دوران مختلف طریقے سے کام کرتے ہیں کیونکہ JPEG سادہ طور پر alpha channels کو سپورٹ نہیں کرتا۔ بہت بڑی فائلیں 2 GB RAM والے آلات پر میموری کی حدود کو ظاہر کر دیں گی۔ سست موبائل CPUs بالکل واضح کر دیں گے کہ toBlob کال میں اصل میں کتنا وقت لگتا ہے۔
CPU اور نیٹ ورک کو تھروٹل (throttle) کرنے کے لیے Chrome DevTools کا استعمال کریں۔ پانچ سال پرانے Android فون پر آزمائیں۔ اگر آپ کا پائپ لائن انکوڈنگ کے دوران UI کو تین سیکنڈ کے لیے لاک کر دیتا ہے، تو آپ کو بھاری کام کو Web Worker میں منتقل کرنے کی ضرورت ہے تاکہ انٹرفیس ریسپانسو رہے۔
پہلے بنیادی چیزیں فراہم کریں
ہر فارمیٹ کو سپورٹ کرنا پرکشش لگتا ہے اور
