Web Performance

আপনার সাইটের ছোট নয়, কম অনুরোধ পাঠানো উচিত কেন

ক্ষুদ্র ফাইলও বিনা খরচে আসে না। আধুনিক HTTP অনুরোধের ওভারহেড কমিয়েছে, অপ্রাসঙ্গিক করেনি।

The Wux Webtools Team The Wux Webtools Team 4 মিনিট পড়া এআই-সহায়ক, মানব-পর্যালোচিত
A stylized browser waterfall showing many small requests simplified into fewer intentional requests.
সুচিপত্র
  1. “প্রতিটি ফাইল শুধু ছোট করে দিন” — এই আরামদায়ক মিথ
  2. অনুরোধ শুধু bytes নয়
  3. “কিন্তু HTTP/2 তো এটি ঠিক করেছে,” বেশির ভাগ ক্ষেত্রে নয়
  4. সত্য থাকে waterfall-এ
  5. ছোট ফাইল এখনও গুরুত্বপূর্ণ — শুধু সমানভাবে নয়
  6. অনেক ছোট ফাইলের লুকানো খরচ
  7. 1. Late discovery
  8. 2. Header overhead
  9. 3. Main-thread interruption
  10. 4. Cache complexity
  11. Bundling ফিরে এসেছে, তবে বিচক্ষণতার সঙ্গে
  12. Third-party requests নিয়ে অতিরিক্ত সন্দেহ প্রাপ্য
  13. অনুরোধ কমানোর একটি ব্যবহারিক checklist
  14. Remove
  15. Combine thoughtfully
  16. Defer
  17. Cache properly
  18. Re-measure
  19. ভালো অবস্থা দেখতে কেমন

“প্রতিটি ফাইল শুধু ছোট করে দিন” — এই আরামদায়ক মিথ

বছরের পর বছর ওয়েব পারফরম্যান্সের পরামর্শ সহজ শোনাত: সবকিছু কমপ্রেস করুন, সবকিছু minify করুন, প্রতিটি asset ছোট করুন।

এই পরামর্শ এখনও মোটের ওপর সঠিক। 400 KB script-এর চেয়ে 40 KB script সাধারণত ভালো। raw export-এর চেয়ে optimized image ভালো। Brotli, AVIF, CSS minification, tree shaking, এবং font subsetting—সবই গুরুত্বপূর্ণ।

কিন্তু অনেক production site-এ বড় সমস্যা আর একটি অতিরিক্ত বড় ফাইল নয়। সমস্যা হলো পেজটি ব্যবহারযোগ্য মনে হওয়ার আগে browser-কে কতগুলো জিনিস চাইতে হচ্ছে।

একটি পেজ ফাইল সাইজে শৃঙ্খলিত দেখাতে পারে, তবু 120টি অনুরোধ পাঠানোর কারণে ধীর হতে পারে: CSS fragments, JavaScript chunks, third-party tags, font files, tracking pixels, icon sprites, JSON endpoints, preloads, analytics beacons, এবং cache revalidations। প্রতিটিই হয়তো “ছোট।” একসঙ্গে এগুলো একটি দীর্ঘ, ভঙ্গুর waterfall তৈরি করে।

ব্যবহারিক নিয়মটি হলো: পৃথক assets যখন যুক্তিসঙ্গতভাবে compressed, তখন প্রতিটি ফাইল থেকে কয়েক kilobytes কমানোর চেয়ে অনুরোধের সংখ্যা কমানো প্রায়ই user experience বেশি উন্নত করে।

অনুরোধ শুধু bytes নয়

একটি network request কেবল data transfer নয়। এটি কাজের একটি ধারাবাহিকতা।

Browser-কে resource খুঁজে বের করতে হয়, কখন fetch করবে তা সিদ্ধান্ত নিতে হয়, অন্যান্য resources-এর সঙ্গে schedule করতে হয়, headers পাঠাতে হয়, server-এর জন্য অপেক্ষা করতে হয়, headers গ্রহণ করতে হয়, response parse করতে হয়, প্রায়ই decompress করতে হয়, এবং তারপর সেটি দিয়ে দরকারি কিছু করতে হয়।

সেই “দরকারি কিছু” ব্যয়বহুল হতে পারে। একটি JavaScript file parse, compile, এবং execute করতে হয়। একটি CSS file rendering block করতে পারে। একটি font file পাঠযোগ্য text দেরি করাতে পারে বা layout shifts ঘটাতে পারে। একটি image Largest Contentful Paint element-কে প্রভাবিত করতে পারে। একটি third-party script তার নিজস্ব dependency chain নিয়ে আসতে পারে।

এই কারণেই ফাইল ছোট হলেও request count গুরুত্বপূর্ণ থাকে। 3 KB script একটি 30 KB image-এর চেয়েও খারাপ হতে পারে, যদি সেটি rendering block করে, দেরিতে আসে, এবং ভুল মুহূর্তে main thread-এ execute হয়।

আপনি যদি Lighthouse report পড়ে ডজন ডজন আলাদা warning-এ বিপর্যস্ত বোধ করেন, individual scores-এর বদলে request waterfall দিয়ে শুরু করুন। আতঙ্কিত না হয়ে Lighthouse report কীভাবে পড়তে হয় সে বিষয়ে আমাদের একটি ব্যবহারিক walkthrough আছে, তবে সংক্ষিপ্ত সংস্করণ হলো: কী first render block করে এবং কী main content দেরি করায় তা খুঁজুন।

“কিন্তু HTTP/2 তো এটি ঠিক করেছে,” বেশির ভাগ ক্ষেত্রে নয়

HTTP/2 এবং HTTP/3 অনুরোধের অর্থনীতি বদলে দিয়েছে। এগুলো multiplexing, header compression, এবং উন্নত connection behavior এনেছে। সহজ কথায়, browsers কম connections-এর ওপর একাধিক requests পাঠাতে অনেক ভালো হয়েছে।

এটি বাস্তব উন্নতি ছিল। এটি কিছু পুরোনো অভ্যাসও শেষ করেছে, যেমন extreme CSS sprites এবং শুধু connection limits এড়াতে বানানো giant concatenated bundles।

কিন্তু HTTP/2 requests-কে free করে দেয়নি।

অনেক resources একই connection share করলে multiplexing সাহায্য করে, কিন্তু browser-কে এখনও সেগুলোর priority নির্ধারণ করতে হয়। Servers-কে এখনও respond করতে হয়। Client-কে এখনও প্রতিটি response process করতে হয়। Congestion, packet loss, TLS negotiation, DNS lookup, cache misses, এবং main-thread pressure এখনও আছে।

HTTP/3 কিছু transport behavior উন্নত করে, বিশেষ করে connection migration এবং transport layer-এ head-of-line blocking-এর ক্ষেত্রে। কিন্তু এটি resources discover, schedule, download, parse, এবং execute করার খরচ সরিয়ে দেয় না।

তাই আধুনিক লক্ষ্য “সবকিছু একটি বিশাল ফাইলে bundle করা” নয়। লক্ষ্য হলো “কম critical requests পাঠানো, এবং বাকি requests-কে উদ্দেশ্যপূর্ণ করা।”

সত্য থাকে waterfall-এ

Performance problems খুব কমই একটি single metric-এ নিজেকে ঘোষণা করে। এগুলো shape হিসেবে দেখা দেয়।

একটি browser network panel খুলুন এবং প্রথম কয়েক seconds দেখুন। জিজ্ঞেস করুন:

  • Main content দেখা দেওয়ার আগে কতগুলো requests শুরু হয়?
  • কোন requests rendering block করে?
  • গুরুত্বপূর্ণ resources কি দেরিতে discovered হয়?
  • Third-party scripts কি first-party CSS, fonts, বা images-এর সঙ্গে প্রতিযোগিতা করছে?
  • অনেক files কি cache থেকে সরাসরি serve হওয়ার বদলে 304 responses ফিরিয়ে দিচ্ছে?
  • Icons, fonts, বা UI fragments কি পেজের প্রয়োজনের চেয়ে বেশি files-এ split করা?

একটি fast page-এর early waterfall সাধারণত নিরস হয়। অল্প কিছু critical resources তাড়াতাড়ি আসে। Non-critical resources অপেক্ষা করে। Third-party scripts delayed, limited, বা removed থাকে। Browser-কে পেজ paint করার আগে বিশটি priority সামলাতে বাধ্য করা হয় না।

একটি slow page-এ প্রায়ই অস্থির waterfall থাকে: অনেক small files, অনেক origins, এবং অনেক late discoveries।

ছোট ফাইল এখনও গুরুত্বপূর্ণ — শুধু সমানভাবে নয়

এটি compression বা optimization-এর বিরুদ্ধে যুক্তি নয়। এটি coordination উপেক্ষা করে bytes optimize করার বিরুদ্ধে যুক্তি।

ছোট ফাইল সবচেয়ে বেশি গুরুত্বপূর্ণ যখন resource বড়, render-blocking, বা main content path-এর অংশ। উদাহরণস্বরূপ:

  • Hero image সঠিকভাবে sized এবং encoded হওয়া উচিত।
  • Render-blocking CSS lean হওয়া উচিত।
  • First interaction-এর জন্য দরকারি JavaScript minimal হওয়া উচিত।
  • Fonts subset, compressed, এবং বাস্তবে ব্যবহৃত weights-এ সীমিত হওয়া উচিত।

Fonts একটি সাধারণ উদাহরণ। Teams প্রায়ই একটি font file 24 KB নাকি 31 KB, তা নিয়ে অতিরিক্ত মনোযোগ দেয়, অথচ ছয়টি weights, দুটি styles, এবং একাধিক families ship করে। ভালো সমাধান এক ফাইল থেকে 7 KB কমানো নয়। সমাধান হলো কম font files পাঠানো। Typography যদি আপনার performance work-এর অংশ হয়, web fonts এখনও অধিকাংশ সাইটে সবচেয়ে সহজ wins-এর একটি

Images-ও একই pattern অনুসরণ করে। AVIF বা WebP উল্লেখযোগ্য bytes বাঁচাতে পারে, কিন্তু fold-এর ওপরে দশটি decorative images পাঠানো এখনও খারাপ পরিকল্পনা। ভালো formats বেছে নিন, হ্যাঁ, তবে প্রতিটি image আদৌ request করা দরকার কি না সেটিও প্রশ্ন করুন। Format decisions-এর জন্য, কখন AVIF WebP-কে হারায় এবং কখন হারায় না নিয়ে আমাদের guide এই request-count কাজের সহায়ক companion।

অনেক ছোট ফাইলের লুকানো খরচ

অনেক small requests এমন সমস্যা তৈরি করে যা আপনি যদি শুধু total transferred bytes দেখেন, তাহলে ধরা পড়ে না।

1. Late discovery

Browsers যা discover করেনি, তা request করতে পারে না। একটি CSS file একটি font reference করতে পারে। একটি script আরেকটি script import করতে পারে। একটি component hydration-এর পর JSON request করতে পারে। প্রতিটি dependency chain-এ আরেকটি ধাপ যোগ করে।

Chain যত গভীর, গুরুত্বপূর্ণ কাজ তত দেরিতে শুরু হয়।

2. Header overhead

প্রতিটি request এবং response-এ headers থাকে। Header compression সাহায্য করে, বিশেষ করে HTTP/2 এবং HTTP/3-তে, কিন্তু overhead দূর করে না। Cookies এটি আরও খারাপ করতে পারে। আপনার site যদি প্রতিটি request-এর সঙ্গে বড় cookies পাঠায়, tiny assets বাস্তবে আর তত tiny থাকে না।

এ কারণেই static assets প্রায়ই cookie-free paths বা domains-এ থাকা উচিত, এবং cache headers মনোযোগ পাওয়ার যোগ্য। Production-এ headers অদ্ভুত আচরণ করলে, অনুমান করার চেয়ে redirects এবং HTTP headers debug করা সাধারণত দ্রুত।

3. Main-thread interruption

অনেক JavaScript chunks বারবার parse এবং execution work তৈরি করতে পারে। প্রতিটি chunk ছোট হলেও browser হয়তো code evaluate করতে বারবার থামে। এটি Interaction to Next Paint ক্ষতিগ্রস্ত করতে পারে এবং page-কে jittery মনে করাতে পারে।

User-এর কাছে প্রতিটি ফাইল ছোট ছিল কি না তা গুরুত্বপূর্ণ নয়। তাদের কাছে গুরুত্বপূর্ণ হলো menu tap করতে 600 milliseconds লাগল।

4. Cache complexity

সতর্কভাবে করা হলে assets split করা caching উন্নত করতে পারে। একটি stable vendor bundle এবং একটি changing app bundle ভালো split হতে পারে।

কিন্তু excessive chunking উল্টো ফল দিতে পারে। বেশি files মানে বেশি cache lookups, বেশি revalidation opportunities, বেশি version coordination, এবং এমন resources ভুলবশত invalidate করার বেশি উপায় যেগুলো বদলানোর দরকার ছিল না।

Bundling ফিরে এসেছে, তবে বিচক্ষণতার সঙ্গে

Web performance-এর প্রথম era bundling ভালোবাসত, কারণ browsers-এর strict connection limits ছিল। তারপর HTTP/2 এল এবং অনেক teams aggressive code splitting-এর দিকে প্রবলভাবে ঝুঁকল। কিছু অংশ কার্যকর ছিল। কিছু অংশ কুসংস্কারে পরিণত হলো।

বিবেচনাপূর্ণ মধ্যপন্থা হলো route-aware bundling।

একটি সাধারণ marketing site বা content site-এর জন্য:

  • Initial rendering-এর জন্য দরকারি CSS কেবল inline বা load করুন।
  • Global JavaScript ছোট রাখুন।
  • Tiny modules-কে separate network requests-এ split করা এড়িয়ে চলুন।
  • সঙ্গে সঙ্গে দরকার নেই এমন interactive features delay করুন।
  • যেসব third-party scripts তাদের খরচের ন্যায্যতা দেয় না, সেগুলো remove করুন।

একটি application-এর জন্য:

  • প্রতিটি component নয়, route বা major feature অনুযায়ী split করুন।
  • Shared dependencies stable এবং cacheable রাখুন।
  • শুধু সেই resources preload করুন যেগুলো নিশ্চিতভাবে শিগগির দরকার হবে।
  • Public pages-এ admin, dashboard, editor, বা experiment code load করা এড়িয়ে চলুন।
  • শুধু bundle size নয়, interaction cost মাপুন।

Bundling স্বয়ংক্রিয়ভাবে ভালো নয়। Code splitting স্বয়ংক্রিয়ভাবে ভালো নয়। দরকারি প্রশ্নটি হলো: এই split কি browser-কে পরবর্তী meaningful user experience দ্রুত পৌঁছে দিতে সাহায্য করে?

Third-party requests নিয়ে অতিরিক্ত সন্দেহ প্রাপ্য

First-party requests অন্তত আপনার control-এ থাকে। Third-party requests প্রায়ই ধীর, কম predictable, এবং দেখতে যতটা লাগে তার চেয়ে বেশি ব্যয়বহুল।

একটি single tag manager analytics, ads, heatmaps, chat widgets, A/B testing, consent tools, এবং personalization scripts trigger করতে পারে। প্রতিটি vendor আরও requests আনতে পারে। কিছু early run করবে। কিছু main thread block করবে। কিছু আপনার release process ছাড়াই বদলে যাবে।

সেরা third-party optimization হলো deletion। দ্বিতীয় সেরা হলো delay।

একটি third-party script যোগ করার আগে জিজ্ঞেস করুন:

  • User পেজ দেখার আগে কি এটি load হওয়া দরকার?
  • প্রতিটি page-এ কি এটি load হওয়া দরকার?
  • Consent, interaction, বা idle time-এর পর কি এটি load করা যায়?
  • Internally এর owner কে?
  • কোন metric প্রমাণ করে যে performance cost সত্ত্বেও এটি মূল্যবান?

এখানেই performance governance-এ পরিণত হয়। কাউকে no বলার অনুমতি থাকতে হবে।

অনুরোধ কমানোর একটি ব্যবহারিক checklist

সবচেয়ে গুরুত্বপূর্ণ pages দিয়ে শুরু করুন: homepage, pricing page, product page, checkout, signup, বা top landing pages। তারপর waterfall ধরে এগোন।

Remove

  • Unused JavaScript এবং CSS delete করুন।
  • পুরোনো experiments, abandoned pixels, এবং duplicate analytics remove করুন।
  • Unused font weights এবং icon libraries drop করুন।
  • উপযুক্ত হলে decorative images-এর বদলে CSS ব্যবহার করুন।

Combine thoughtfully

  • যেসব tiny JavaScript modules সবসময় একসঙ্গে load হয়, সেগুলো bundle করুন।
  • একই render path block করা small CSS files merge করুন।
  • Repeated icons-এর জন্য SVG sprites বা inline SVG ব্যবহার করুন, যখন তা maintainability ক্ষতি না করে requests কমায়।

Defer

  • Below-the-fold images lazy-load করুন।
  • Non-critical scripts first paint বা user interaction-এর পর পর্যন্ত delay করুন।
  • Comments, embeds, maps, chat, এবং video players কেবল প্রয়োজন হলে load করুন।

Cache properly

  • Versioned static assets-এর জন্য long-lived caching ব্যবহার করুন।
  • খুব কম বদলায় এমন files-এর unnecessary revalidation এড়িয়ে চলুন।
  • HTML fresh রাখুন, কিন্তু hashed assets cached থাকতে দিন।

Re-measure

প্রতিটি change-এর পর আবার waterfall দেখুন। লক্ষ্য perfect score নয়। লক্ষ্য হলো কম critical requests, আগে useful rendering, এবং কম main-thread disruption।

ভালো অবস্থা দেখতে কেমন

একটি healthy page-এর অবশ্যই সম্ভাব্য সবচেয়ে কম requests থাকতে হবে, এমন নয়। এর একটি ছোট, deliberate critical path থাকে।

Browser HTML, essential CSS, যদি থাকে main content image, হয়তো navigation বা above-the-fold interaction-এর জন্য দরকারি ছোট script, এবং text readable করতে দরকারি minimum font set পায়। বাকিগুলো নিজের turn-এর জন্য অপেক্ষা করে।

এটাই একটি শুধু optimized page এবং fast মনে হওয়া page-এর পার্থক্য।

Files shrink করা এখনও মূল্যবান। কিন্তু site যদি ইতিমধ্যেই যুক্তিসঙ্গতভাবে compressed হয়, পরবর্তী performance win সাধারণত bundle থেকে আরও 2 KB বাঁচানো নয়। এটি হলো একটি কম blocking request, একটি কম font file, একটি কম third-party script, একটি কম dependency chain।

কম requests browser-এর কাজ সহজ করে। আমরা যতটা স্বীকার করতে চাই, তার চেয়ে বেশি ক্ষেত্রে simple-ই fast।

প্রায়শই জিজ্ঞাসিত প্রশ্ন

একটি বড় bundle কি অনেক ছোট files-এর চেয়ে ভালো?
স্বয়ংক্রিয়ভাবে নয়। একটি huge bundle সবকিছু দেরি করাতে পারে, বিশেষ করে first load-এ। অনেক tiny files scheduling এবং execution overhead তৈরি করতে পারে। ভালো pattern হলো যেসব resources সবসময় একসঙ্গে দরকার হয় সেগুলো bundle করা, এবং route বা major feature অনুযায়ী split করা।
HTTP/2 কি বোঝায় request count আর গুরুত্বপূর্ণ নয়?
না। HTTP/2 multiplexing এবং header compression-এর মাধ্যমে কিছু connection overhead কমায়, কিন্তু প্রতিটি request-এর এখনও discovery, prioritization, server, cache, parsing, এবং execution costs থাকে।
সব critical CSS কি inline করা উচিত?
সত্যিকারের critical CSS-এর ছোট একটি অংশ inline করলে first render-এ সাহায্য করতে পারে, কিন্তু বেশি inline করলে HTML ভারী হয় এবং cache করা কঠিন হয়। এটিকে minimal রাখুন এবং effect মাপুন।
Requests কমানোর সবচেয়ে সহজ জায়গা কোনটি?
Fonts এবং third-party scripts প্রায়ই দ্রুততম wins। অনেক sites unused font weights, duplicate analytics, old pixels, chat widgets, বা embeds ship করে, যেগুলো সঙ্গে সঙ্গে load হওয়ার দরকার নেই।
একটি page-এ কতগুলো requests থাকা উচিত?
সর্বজনীন কোনো target নেই। একটি small content page-এ খুব কম critical requests থাকা উচিত। একটি complex app-এ বেশি লাগতে পারে। First render-এর আগে এবং main interaction path-এর আগে requests কমানোর ওপর focus করুন।

স्रोत ও আরও পড়া

  1. MDN Web Docs: HTTP caching
  2. web.dev: Optimize Largest Contentful Paint
  3. RFC 9113: HTTP/2
  4. HTTP Archive Web Almanac: Page Weight
লেখক সম্পর্কে
The Wux Webtools Team

শেষ আপডেট:

আরও পড়ুন

Web Performance

আপনার Time to First Byte কেন ধীর এবং এ বিষয়ে কী করবেন

ধীর TTFB সাধারণত ধীর routing, অনুপস্থিত cache, অতিরিক্ত চাপগ্রস্ত servers, অথবা ব্যয়বহুল backend work বোঝায়। কীভাবে এটি নির্ণয় ও ঠিক করবেন, তা এখানে।

5 মিনিট পড়া